1 /* src/prism2/driver/prism2mgmt.c 2 * 3 * Management request handler functions. 4 * 5 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. 6 * -------------------------------------------------------------------- 7 * 8 * linux-wlan 9 * 10 * The contents of this file are subject to the Mozilla Public 11 * License Version 1.1 (the "License"); you may not use this file 12 * except in compliance with the License. You may obtain a copy of 13 * the License at http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS 16 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 17 * implied. See the License for the specific language governing 18 * rights and limitations under the License. 19 * 20 * Alternatively, the contents of this file may be used under the 21 * terms of the GNU Public License version 2 (the "GPL"), in which 22 * case the provisions of the GPL are applicable instead of the 23 * above. If you wish to allow the use of your version of this file 24 * only under the terms of the GPL and not to allow others to use 25 * your version of this file under the MPL, indicate your decision 26 * by deleting the provisions above and replace them with the notice 27 * and other provisions required by the GPL. If you do not delete 28 * the provisions above, a recipient may use your version of this 29 * file under either the MPL or the GPL. 30 * 31 * -------------------------------------------------------------------- 32 * 33 * Inquiries regarding the linux-wlan Open Source project can be 34 * made directly to: 35 * 36 * AbsoluteValue Systems Inc. 37 * info@linux-wlan.com 38 * http://www.linux-wlan.com 39 * 40 * -------------------------------------------------------------------- 41 * 42 * Portions of the development of this software were funded by 43 * Intersil Corporation as part of PRISM(R) chipset product development. 44 * 45 * -------------------------------------------------------------------- 46 * 47 * The functions in this file handle management requests sent from 48 * user mode. 49 * 50 * Most of these functions have two separate blocks of code that are 51 * conditional on whether this is a station or an AP. This is used 52 * to separate out the STA and AP responses to these management primitives. 53 * It's a choice (good, bad, indifferent?) to have the code in the same 54 * place so it's clear that the same primitive is implemented in both 55 * cases but has different behavior. 56 * 57 * -------------------------------------------------------------------- 58 */ 59 60 #include <linux/if_arp.h> 61 #include <linux/module.h> 62 #include <linux/kernel.h> 63 #include <linux/wait.h> 64 #include <linux/sched.h> 65 #include <linux/types.h> 66 #include <linux/wireless.h> 67 #include <linux/netdevice.h> 68 #include <linux/delay.h> 69 #include <linux/io.h> 70 #include <asm/byteorder.h> 71 #include <linux/random.h> 72 #include <linux/usb.h> 73 #include <linux/bitops.h> 74 75 #include "p80211types.h" 76 #include "p80211hdr.h" 77 #include "p80211mgmt.h" 78 #include "p80211conv.h" 79 #include "p80211msg.h" 80 #include "p80211netdev.h" 81 #include "p80211metadef.h" 82 #include "p80211metastruct.h" 83 #include "hfa384x.h" 84 #include "prism2mgmt.h" 85 86 /* Converts 802.11 format rate specifications to prism2 */ 87 #define p80211rate_to_p2bit(n) ((((n)&~BIT(7)) == 2) ? BIT(0) : \ 88 (((n)&~BIT(7)) == 4) ? BIT(1) : \ 89 (((n)&~BIT(7)) == 11) ? BIT(2) : \ 90 (((n)&~BIT(7)) == 22) ? BIT(3) : 0) 91 92 /*---------------------------------------------------------------- 93 * prism2mgmt_scan 94 * 95 * Initiate a scan for BSSs. 96 * 97 * This function corresponds to MLME-scan.request and part of 98 * MLME-scan.confirm. As far as I can tell in the standard, there 99 * are no restrictions on when a scan.request may be issued. We have 100 * to handle in whatever state the driver/MAC happen to be. 101 * 102 * Arguments: 103 * wlandev wlan device structure 104 * msgp ptr to msg buffer 105 * 106 * Returns: 107 * 0 success and done 108 * <0 success, but we're waiting for something to finish. 109 * >0 an error occurred while handling the message. 110 * Side effects: 111 * 112 * Call context: 113 * process thread (usually) 114 * interrupt 115 ----------------------------------------------------------------*/ 116 int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) 117 { 118 int result = 0; 119 hfa384x_t *hw = wlandev->priv; 120 struct p80211msg_dot11req_scan *msg = msgp; 121 u16 roamingmode, word; 122 int i, timeout; 123 int istmpenable = 0; 124 125 hfa384x_HostScanRequest_data_t scanreq; 126 127 /* gatekeeper check */ 128 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, 129 hw->ident_sta_fw.minor, 130 hw->ident_sta_fw.variant) < 131 HFA384x_FIRMWARE_VERSION(1, 3, 2)) { 132 netdev_err(wlandev->netdev, 133 "HostScan not supported with current firmware (<1.3.2).\n"); 134 result = 1; 135 msg->resultcode.data = P80211ENUM_resultcode_not_supported; 136 goto exit; 137 } 138 139 memset(&scanreq, 0, sizeof(scanreq)); 140 141 /* save current roaming mode */ 142 result = hfa384x_drvr_getconfig16(hw, 143 HFA384x_RID_CNFROAMINGMODE, 144 &roamingmode); 145 if (result) { 146 netdev_err(wlandev->netdev, 147 "getconfig(ROAMMODE) failed. result=%d\n", result); 148 msg->resultcode.data = 149 P80211ENUM_resultcode_implementation_failure; 150 goto exit; 151 } 152 153 /* drop into mode 3 for the scan */ 154 result = hfa384x_drvr_setconfig16(hw, 155 HFA384x_RID_CNFROAMINGMODE, 156 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); 157 if (result) { 158 netdev_err(wlandev->netdev, 159 "setconfig(ROAMINGMODE) failed. result=%d\n", 160 result); 161 msg->resultcode.data = 162 P80211ENUM_resultcode_implementation_failure; 163 goto exit; 164 } 165 166 /* active or passive? */ 167 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, 168 hw->ident_sta_fw.minor, 169 hw->ident_sta_fw.variant) > 170 HFA384x_FIRMWARE_VERSION(1, 5, 0)) { 171 if (msg->scantype.data != P80211ENUM_scantype_active) 172 word = cpu_to_le16(msg->maxchanneltime.data); 173 else 174 word = 0; 175 176 result = 177 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, 178 word); 179 if (result) { 180 netdev_warn(wlandev->netdev, 181 "Passive scan not supported with current firmware. (<1.5.1)\n"); 182 } 183 } 184 185 /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ 186 word = HFA384x_RATEBIT_2; 187 scanreq.txRate = cpu_to_le16(word); 188 189 /* set up the channel list */ 190 word = 0; 191 for (i = 0; i < msg->channellist.data.len; i++) { 192 u8 channel = msg->channellist.data.data[i]; 193 194 if (channel > 14) 195 continue; 196 /* channel 1 is BIT 0 ... channel 14 is BIT 13 */ 197 word |= (1 << (channel - 1)); 198 } 199 scanreq.channelList = cpu_to_le16(word); 200 201 /* set up the ssid, if present. */ 202 scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len); 203 memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); 204 205 /* Enable the MAC port if it's not already enabled */ 206 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); 207 if (result) { 208 netdev_err(wlandev->netdev, 209 "getconfig(PORTSTATUS) failed. result=%d\n", result); 210 msg->resultcode.data = 211 P80211ENUM_resultcode_implementation_failure; 212 goto exit; 213 } 214 if (word == HFA384x_PORTSTATUS_DISABLED) { 215 u16 wordbuf[17]; 216 217 result = hfa384x_drvr_setconfig16(hw, 218 HFA384x_RID_CNFROAMINGMODE, 219 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); 220 if (result) { 221 netdev_err(wlandev->netdev, 222 "setconfig(ROAMINGMODE) failed. result=%d\n", 223 result); 224 msg->resultcode.data = 225 P80211ENUM_resultcode_implementation_failure; 226 goto exit; 227 } 228 /* Construct a bogus SSID and assign it to OwnSSID and 229 * DesiredSSID 230 */ 231 wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN); 232 get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); 233 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, 234 wordbuf, 235 HFA384x_RID_CNFOWNSSID_LEN); 236 if (result) { 237 netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n"); 238 msg->resultcode.data = 239 P80211ENUM_resultcode_implementation_failure; 240 goto exit; 241 } 242 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, 243 wordbuf, 244 HFA384x_RID_CNFDESIREDSSID_LEN); 245 if (result) { 246 netdev_err(wlandev->netdev, 247 "Failed to set DesiredSSID.\n"); 248 msg->resultcode.data = 249 P80211ENUM_resultcode_implementation_failure; 250 goto exit; 251 } 252 /* bsstype */ 253 result = hfa384x_drvr_setconfig16(hw, 254 HFA384x_RID_CNFPORTTYPE, 255 HFA384x_PORTTYPE_IBSS); 256 if (result) { 257 netdev_err(wlandev->netdev, 258 "Failed to set CNFPORTTYPE.\n"); 259 msg->resultcode.data = 260 P80211ENUM_resultcode_implementation_failure; 261 goto exit; 262 } 263 /* ibss options */ 264 result = hfa384x_drvr_setconfig16(hw, 265 HFA384x_RID_CREATEIBSS, 266 HFA384x_CREATEIBSS_JOINCREATEIBSS); 267 if (result) { 268 netdev_err(wlandev->netdev, 269 "Failed to set CREATEIBSS.\n"); 270 msg->resultcode.data = 271 P80211ENUM_resultcode_implementation_failure; 272 goto exit; 273 } 274 result = hfa384x_drvr_enable(hw, 0); 275 if (result) { 276 netdev_err(wlandev->netdev, 277 "drvr_enable(0) failed. result=%d\n", 278 result); 279 msg->resultcode.data = 280 P80211ENUM_resultcode_implementation_failure; 281 goto exit; 282 } 283 istmpenable = 1; 284 } 285 286 /* Figure out our timeout first Kus, then HZ */ 287 timeout = msg->channellist.data.len * msg->maxchanneltime.data; 288 timeout = (timeout * HZ) / 1000; 289 290 /* Issue the scan request */ 291 hw->scanflag = 0; 292 293 result = hfa384x_drvr_setconfig(hw, 294 HFA384x_RID_HOSTSCAN, &scanreq, 295 sizeof(hfa384x_HostScanRequest_data_t)); 296 if (result) { 297 netdev_err(wlandev->netdev, 298 "setconfig(SCANREQUEST) failed. result=%d\n", 299 result); 300 msg->resultcode.data = 301 P80211ENUM_resultcode_implementation_failure; 302 goto exit; 303 } 304 305 /* sleep until info frame arrives */ 306 wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); 307 308 msg->numbss.status = P80211ENUM_msgitem_status_data_ok; 309 if (hw->scanflag == -1) 310 hw->scanflag = 0; 311 312 msg->numbss.data = hw->scanflag; 313 314 hw->scanflag = 0; 315 316 /* Disable port if we temporarily enabled it. */ 317 if (istmpenable) { 318 result = hfa384x_drvr_disable(hw, 0); 319 if (result) { 320 netdev_err(wlandev->netdev, 321 "drvr_disable(0) failed. result=%d\n", 322 result); 323 msg->resultcode.data = 324 P80211ENUM_resultcode_implementation_failure; 325 goto exit; 326 } 327 } 328 329 /* restore original roaming mode */ 330 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 331 roamingmode); 332 if (result) { 333 netdev_err(wlandev->netdev, 334 "setconfig(ROAMMODE) failed. result=%d\n", result); 335 msg->resultcode.data = 336 P80211ENUM_resultcode_implementation_failure; 337 goto exit; 338 } 339 340 result = 0; 341 msg->resultcode.data = P80211ENUM_resultcode_success; 342 343 exit: 344 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 345 346 return result; 347 } 348 349 /*---------------------------------------------------------------- 350 * prism2mgmt_scan_results 351 * 352 * Retrieve the BSS description for one of the BSSs identified in 353 * a scan. 354 * 355 * Arguments: 356 * wlandev wlan device structure 357 * msgp ptr to msg buffer 358 * 359 * Returns: 360 * 0 success and done 361 * <0 success, but we're waiting for something to finish. 362 * >0 an error occurred while handling the message. 363 * Side effects: 364 * 365 * Call context: 366 * process thread (usually) 367 * interrupt 368 ----------------------------------------------------------------*/ 369 int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) 370 { 371 int result = 0; 372 struct p80211msg_dot11req_scan_results *req; 373 hfa384x_t *hw = wlandev->priv; 374 hfa384x_HScanResultSub_t *item = NULL; 375 376 int count; 377 378 req = msgp; 379 380 req->resultcode.status = P80211ENUM_msgitem_status_data_ok; 381 382 if (!hw->scanresults) { 383 netdev_err(wlandev->netdev, 384 "dot11req_scan_results can only be used after a successful dot11req_scan.\n"); 385 result = 2; 386 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; 387 goto exit; 388 } 389 390 count = (hw->scanresults->framelen - 3) / 32; 391 if (count > HFA384x_SCANRESULT_MAX) 392 count = HFA384x_SCANRESULT_MAX; 393 394 if (req->bssindex.data >= count) { 395 pr_debug("requested index (%d) out of range (%d)\n", 396 req->bssindex.data, count); 397 result = 2; 398 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; 399 goto exit; 400 } 401 402 item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]); 403 /* signal and noise */ 404 req->signal.status = P80211ENUM_msgitem_status_data_ok; 405 req->noise.status = P80211ENUM_msgitem_status_data_ok; 406 req->signal.data = le16_to_cpu(item->sl); 407 req->noise.data = le16_to_cpu(item->anl); 408 409 /* BSSID */ 410 req->bssid.status = P80211ENUM_msgitem_status_data_ok; 411 req->bssid.data.len = WLAN_BSSID_LEN; 412 memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN); 413 414 /* SSID */ 415 req->ssid.status = P80211ENUM_msgitem_status_data_ok; 416 req->ssid.data.len = le16_to_cpu(item->ssid.len); 417 req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN); 418 memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len); 419 420 /* supported rates */ 421 for (count = 0; count < 10; count++) 422 if (item->supprates[count] == 0) 423 break; 424 425 #define REQBASICRATE(N) \ 426 do { \ 427 if ((count >= N) && DOT11_RATE5_ISBASIC_GET( \ 428 item->supprates[(N)-1])) { \ 429 req->basicrate ## N .data = item->supprates[(N)-1]; \ 430 req->basicrate ## N .status = \ 431 P80211ENUM_msgitem_status_data_ok; \ 432 } \ 433 } while (0) 434 435 REQBASICRATE(1); 436 REQBASICRATE(2); 437 REQBASICRATE(3); 438 REQBASICRATE(4); 439 REQBASICRATE(5); 440 REQBASICRATE(6); 441 REQBASICRATE(7); 442 REQBASICRATE(8); 443 444 #define REQSUPPRATE(N) \ 445 do { \ 446 if (count >= N) { \ 447 req->supprate ## N .data = item->supprates[(N)-1]; \ 448 req->supprate ## N .status = \ 449 P80211ENUM_msgitem_status_data_ok; \ 450 } \ 451 } while (0) 452 453 REQSUPPRATE(1); 454 REQSUPPRATE(2); 455 REQSUPPRATE(3); 456 REQSUPPRATE(4); 457 REQSUPPRATE(5); 458 REQSUPPRATE(6); 459 REQSUPPRATE(7); 460 REQSUPPRATE(8); 461 462 /* beacon period */ 463 req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok; 464 req->beaconperiod.data = le16_to_cpu(item->bcnint); 465 466 /* timestamps */ 467 req->timestamp.status = P80211ENUM_msgitem_status_data_ok; 468 req->timestamp.data = jiffies; 469 req->localtime.status = P80211ENUM_msgitem_status_data_ok; 470 req->localtime.data = jiffies; 471 472 /* atim window */ 473 req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok; 474 req->ibssatimwindow.data = le16_to_cpu(item->atim); 475 476 /* Channel */ 477 req->dschannel.status = P80211ENUM_msgitem_status_data_ok; 478 req->dschannel.data = le16_to_cpu(item->chid); 479 480 /* capinfo bits */ 481 count = le16_to_cpu(item->capinfo); 482 req->capinfo.status = P80211ENUM_msgitem_status_data_ok; 483 req->capinfo.data = count; 484 485 /* privacy flag */ 486 req->privacy.status = P80211ENUM_msgitem_status_data_ok; 487 req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count); 488 489 /* cfpollable */ 490 req->cfpollable.status = P80211ENUM_msgitem_status_data_ok; 491 req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count); 492 493 /* cfpollreq */ 494 req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok; 495 req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count); 496 497 /* bsstype */ 498 req->bsstype.status = P80211ENUM_msgitem_status_data_ok; 499 req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ? 500 P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent; 501 502 result = 0; 503 req->resultcode.data = P80211ENUM_resultcode_success; 504 505 exit: 506 return result; 507 } 508 509 /*---------------------------------------------------------------- 510 * prism2mgmt_start 511 * 512 * Start a BSS. Any station can do this for IBSS, only AP for ESS. 513 * 514 * Arguments: 515 * wlandev wlan device structure 516 * msgp ptr to msg buffer 517 * 518 * Returns: 519 * 0 success and done 520 * <0 success, but we're waiting for something to finish. 521 * >0 an error occurred while handling the message. 522 * Side effects: 523 * 524 * Call context: 525 * process thread (usually) 526 * interrupt 527 ----------------------------------------------------------------*/ 528 int prism2mgmt_start(wlandevice_t *wlandev, void *msgp) 529 { 530 int result = 0; 531 hfa384x_t *hw = wlandev->priv; 532 struct p80211msg_dot11req_start *msg = msgp; 533 534 p80211pstrd_t *pstr; 535 u8 bytebuf[80]; 536 struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf; 537 u16 word; 538 539 wlandev->macmode = WLAN_MACMODE_NONE; 540 541 /* Set the SSID */ 542 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); 543 544 /*** ADHOC IBSS ***/ 545 /* see if current f/w is less than 8c3 */ 546 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, 547 hw->ident_sta_fw.minor, 548 hw->ident_sta_fw.variant) < 549 HFA384x_FIRMWARE_VERSION(0, 8, 3)) { 550 /* Ad-Hoc not quite supported on Prism2 */ 551 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 552 msg->resultcode.data = P80211ENUM_resultcode_not_supported; 553 goto done; 554 } 555 556 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 557 558 /*** STATION ***/ 559 /* Set the REQUIRED config items */ 560 /* SSID */ 561 pstr = (p80211pstrd_t *) &(msg->ssid.data); 562 prism2mgmt_pstr2bytestr(p2bytestr, pstr); 563 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, 564 bytebuf, HFA384x_RID_CNFOWNSSID_LEN); 565 if (result) { 566 netdev_err(wlandev->netdev, "Failed to set CnfOwnSSID\n"); 567 goto failed; 568 } 569 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, 570 bytebuf, 571 HFA384x_RID_CNFDESIREDSSID_LEN); 572 if (result) { 573 netdev_err(wlandev->netdev, "Failed to set CnfDesiredSSID\n"); 574 goto failed; 575 } 576 577 /* bsstype - we use the default in the ap firmware */ 578 /* IBSS port */ 579 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0); 580 581 /* beacon period */ 582 word = msg->beaconperiod.data; 583 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNint, word); 584 if (result) { 585 netdev_err(wlandev->netdev, 586 "Failed to set beacon period=%d.\n", word); 587 goto failed; 588 } 589 590 /* dschannel */ 591 word = msg->dschannel.data; 592 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); 593 if (result) { 594 netdev_err(wlandev->netdev, 595 "Failed to set channel=%d.\n", word); 596 goto failed; 597 } 598 /* Basic rates */ 599 word = p80211rate_to_p2bit(msg->basicrate1.data); 600 if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok) 601 word |= p80211rate_to_p2bit(msg->basicrate2.data); 602 603 if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok) 604 word |= p80211rate_to_p2bit(msg->basicrate3.data); 605 606 if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok) 607 word |= p80211rate_to_p2bit(msg->basicrate4.data); 608 609 if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok) 610 word |= p80211rate_to_p2bit(msg->basicrate5.data); 611 612 if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok) 613 word |= p80211rate_to_p2bit(msg->basicrate6.data); 614 615 if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok) 616 word |= p80211rate_to_p2bit(msg->basicrate7.data); 617 618 if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok) 619 word |= p80211rate_to_p2bit(msg->basicrate8.data); 620 621 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); 622 if (result) { 623 netdev_err(wlandev->netdev, 624 "Failed to set basicrates=%d.\n", word); 625 goto failed; 626 } 627 628 /* Operational rates (supprates and txratecontrol) */ 629 word = p80211rate_to_p2bit(msg->operationalrate1.data); 630 if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok) 631 word |= p80211rate_to_p2bit(msg->operationalrate2.data); 632 633 if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok) 634 word |= p80211rate_to_p2bit(msg->operationalrate3.data); 635 636 if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok) 637 word |= p80211rate_to_p2bit(msg->operationalrate4.data); 638 639 if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok) 640 word |= p80211rate_to_p2bit(msg->operationalrate5.data); 641 642 if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok) 643 word |= p80211rate_to_p2bit(msg->operationalrate6.data); 644 645 if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok) 646 word |= p80211rate_to_p2bit(msg->operationalrate7.data); 647 648 if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok) 649 word |= p80211rate_to_p2bit(msg->operationalrate8.data); 650 651 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); 652 if (result) { 653 netdev_err(wlandev->netdev, 654 "Failed to set supprates=%d.\n", word); 655 goto failed; 656 } 657 658 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word); 659 if (result) { 660 netdev_err(wlandev->netdev, "Failed to set txrates=%d.\n", 661 word); 662 goto failed; 663 } 664 665 /* Set the macmode so the frame setup code knows what to do */ 666 if (msg->bsstype.data == P80211ENUM_bsstype_independent) { 667 wlandev->macmode = WLAN_MACMODE_IBSS_STA; 668 /* lets extend the data length a bit */ 669 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); 670 } 671 672 /* Enable the Port */ 673 result = hfa384x_drvr_enable(hw, 0); 674 if (result) { 675 netdev_err(wlandev->netdev, 676 "Enable macport failed, result=%d.\n", result); 677 goto failed; 678 } 679 680 msg->resultcode.data = P80211ENUM_resultcode_success; 681 682 goto done; 683 failed: 684 pr_debug("Failed to set a config option, result=%d\n", result); 685 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; 686 687 done: 688 result = 0; 689 690 return result; 691 } 692 693 /*---------------------------------------------------------------- 694 * prism2mgmt_readpda 695 * 696 * Collect the PDA data and put it in the message. 697 * 698 * Arguments: 699 * wlandev wlan device structure 700 * msgp ptr to msg buffer 701 * 702 * Returns: 703 * 0 success and done 704 * <0 success, but we're waiting for something to finish. 705 * >0 an error occurred while handling the message. 706 * Side effects: 707 * 708 * Call context: 709 * process thread (usually) 710 ----------------------------------------------------------------*/ 711 int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp) 712 { 713 hfa384x_t *hw = wlandev->priv; 714 struct p80211msg_p2req_readpda *msg = msgp; 715 int result; 716 717 /* We only support collecting the PDA when in the FWLOAD 718 * state. 719 */ 720 if (wlandev->msdstate != WLAN_MSD_FWLOAD) { 721 netdev_err(wlandev->netdev, 722 "PDA may only be read in the fwload state.\n"); 723 msg->resultcode.data = 724 P80211ENUM_resultcode_implementation_failure; 725 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 726 } else { 727 /* Call drvr_readpda(), it handles the auxport enable 728 * and validating the returned PDA. 729 */ 730 result = hfa384x_drvr_readpda(hw, 731 msg->pda.data, 732 HFA384x_PDA_LEN_MAX); 733 if (result) { 734 netdev_err(wlandev->netdev, 735 "hfa384x_drvr_readpda() failed, result=%d\n", 736 result); 737 738 msg->resultcode.data = 739 P80211ENUM_resultcode_implementation_failure; 740 msg->resultcode.status = 741 P80211ENUM_msgitem_status_data_ok; 742 return 0; 743 } 744 msg->pda.status = P80211ENUM_msgitem_status_data_ok; 745 msg->resultcode.data = P80211ENUM_resultcode_success; 746 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 747 } 748 749 return 0; 750 } 751 752 /*---------------------------------------------------------------- 753 * prism2mgmt_ramdl_state 754 * 755 * Establishes the beginning/end of a card RAM download session. 756 * 757 * It is expected that the ramdl_write() function will be called 758 * one or more times between the 'enable' and 'disable' calls to 759 * this function. 760 * 761 * Note: This function should not be called when a mac comm port 762 * is active. 763 * 764 * Arguments: 765 * wlandev wlan device structure 766 * msgp ptr to msg buffer 767 * 768 * Returns: 769 * 0 success and done 770 * <0 success, but we're waiting for something to finish. 771 * >0 an error occurred while handling the message. 772 * Side effects: 773 * 774 * Call context: 775 * process thread (usually) 776 ----------------------------------------------------------------*/ 777 int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp) 778 { 779 hfa384x_t *hw = wlandev->priv; 780 struct p80211msg_p2req_ramdl_state *msg = msgp; 781 782 if (wlandev->msdstate != WLAN_MSD_FWLOAD) { 783 netdev_err(wlandev->netdev, 784 "ramdl_state(): may only be called in the fwload state.\n"); 785 msg->resultcode.data = 786 P80211ENUM_resultcode_implementation_failure; 787 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 788 return 0; 789 } 790 791 /* 792 ** Note: Interrupts are locked out if this is an AP and are NOT 793 ** locked out if this is a station. 794 */ 795 796 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 797 if (msg->enable.data == P80211ENUM_truth_true) { 798 if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) { 799 msg->resultcode.data = 800 P80211ENUM_resultcode_implementation_failure; 801 } else { 802 msg->resultcode.data = P80211ENUM_resultcode_success; 803 } 804 } else { 805 hfa384x_drvr_ramdl_disable(hw); 806 msg->resultcode.data = P80211ENUM_resultcode_success; 807 } 808 809 return 0; 810 } 811 812 /*---------------------------------------------------------------- 813 * prism2mgmt_ramdl_write 814 * 815 * Writes a buffer to the card RAM using the download state. This 816 * is for writing code to card RAM. To just read or write raw data 817 * use the aux functions. 818 * 819 * Arguments: 820 * wlandev wlan device structure 821 * msgp ptr to msg buffer 822 * 823 * Returns: 824 * 0 success and done 825 * <0 success, but we're waiting for something to finish. 826 * >0 an error occurred while handling the message. 827 * Side effects: 828 * 829 * Call context: 830 * process thread (usually) 831 ----------------------------------------------------------------*/ 832 int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp) 833 { 834 hfa384x_t *hw = wlandev->priv; 835 struct p80211msg_p2req_ramdl_write *msg = msgp; 836 u32 addr; 837 u32 len; 838 u8 *buf; 839 840 if (wlandev->msdstate != WLAN_MSD_FWLOAD) { 841 netdev_err(wlandev->netdev, 842 "ramdl_write(): may only be called in the fwload state.\n"); 843 msg->resultcode.data = 844 P80211ENUM_resultcode_implementation_failure; 845 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 846 return 0; 847 } 848 849 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 850 /* first validate the length */ 851 if (msg->len.data > sizeof(msg->data.data)) { 852 msg->resultcode.status = 853 P80211ENUM_resultcode_invalid_parameters; 854 return 0; 855 } 856 /* call the hfa384x function to do the write */ 857 addr = msg->addr.data; 858 len = msg->len.data; 859 buf = msg->data.data; 860 if (hfa384x_drvr_ramdl_write(hw, addr, buf, len)) 861 msg->resultcode.data = P80211ENUM_resultcode_refused; 862 863 msg->resultcode.data = P80211ENUM_resultcode_success; 864 865 return 0; 866 } 867 868 /*---------------------------------------------------------------- 869 * prism2mgmt_flashdl_state 870 * 871 * Establishes the beginning/end of a card Flash download session. 872 * 873 * It is expected that the flashdl_write() function will be called 874 * one or more times between the 'enable' and 'disable' calls to 875 * this function. 876 * 877 * Note: This function should not be called when a mac comm port 878 * is active. 879 * 880 * Arguments: 881 * wlandev wlan device structure 882 * msgp ptr to msg buffer 883 * 884 * Returns: 885 * 0 success and done 886 * <0 success, but we're waiting for something to finish. 887 * >0 an error occurred while handling the message. 888 * Side effects: 889 * 890 * Call context: 891 * process thread (usually) 892 ----------------------------------------------------------------*/ 893 int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp) 894 { 895 int result = 0; 896 hfa384x_t *hw = wlandev->priv; 897 struct p80211msg_p2req_flashdl_state *msg = msgp; 898 899 if (wlandev->msdstate != WLAN_MSD_FWLOAD) { 900 netdev_err(wlandev->netdev, 901 "flashdl_state(): may only be called in the fwload state.\n"); 902 msg->resultcode.data = 903 P80211ENUM_resultcode_implementation_failure; 904 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 905 return 0; 906 } 907 908 /* 909 ** Note: Interrupts are locked out if this is an AP and are NOT 910 ** locked out if this is a station. 911 */ 912 913 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 914 if (msg->enable.data == P80211ENUM_truth_true) { 915 if (hfa384x_drvr_flashdl_enable(hw)) { 916 msg->resultcode.data = 917 P80211ENUM_resultcode_implementation_failure; 918 } else { 919 msg->resultcode.data = P80211ENUM_resultcode_success; 920 } 921 } else { 922 hfa384x_drvr_flashdl_disable(hw); 923 msg->resultcode.data = P80211ENUM_resultcode_success; 924 /* NOTE: At this point, the MAC is in the post-reset 925 * state and the driver is in the fwload state. 926 * We need to get the MAC back into the fwload 927 * state. To do this, we set the nsdstate to HWPRESENT 928 * and then call the ifstate function to redo everything 929 * that got us into the fwload state. 930 */ 931 wlandev->msdstate = WLAN_MSD_HWPRESENT; 932 result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload); 933 if (result != P80211ENUM_resultcode_success) { 934 netdev_err(wlandev->netdev, 935 "prism2sta_ifstate(fwload) failed, P80211ENUM_resultcode=%d\n", 936 result); 937 msg->resultcode.data = 938 P80211ENUM_resultcode_implementation_failure; 939 result = -1; 940 } 941 } 942 943 return 0; 944 } 945 946 /*---------------------------------------------------------------- 947 * prism2mgmt_flashdl_write 948 * 949 * 950 * 951 * Arguments: 952 * wlandev wlan device structure 953 * msgp ptr to msg buffer 954 * 955 * Returns: 956 * 0 success and done 957 * <0 success, but we're waiting for something to finish. 958 * >0 an error occurred while handling the message. 959 * Side effects: 960 * 961 * Call context: 962 * process thread (usually) 963 ----------------------------------------------------------------*/ 964 int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp) 965 { 966 hfa384x_t *hw = wlandev->priv; 967 struct p80211msg_p2req_flashdl_write *msg = msgp; 968 u32 addr; 969 u32 len; 970 u8 *buf; 971 972 if (wlandev->msdstate != WLAN_MSD_FWLOAD) { 973 netdev_err(wlandev->netdev, 974 "flashdl_write(): may only be called in the fwload state.\n"); 975 msg->resultcode.data = 976 P80211ENUM_resultcode_implementation_failure; 977 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 978 return 0; 979 } 980 981 /* 982 ** Note: Interrupts are locked out if this is an AP and are NOT 983 ** locked out if this is a station. 984 */ 985 986 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 987 /* first validate the length */ 988 if (msg->len.data > sizeof(msg->data.data)) { 989 msg->resultcode.status = 990 P80211ENUM_resultcode_invalid_parameters; 991 return 0; 992 } 993 /* call the hfa384x function to do the write */ 994 addr = msg->addr.data; 995 len = msg->len.data; 996 buf = msg->data.data; 997 if (hfa384x_drvr_flashdl_write(hw, addr, buf, len)) 998 msg->resultcode.data = P80211ENUM_resultcode_refused; 999 1000 msg->resultcode.data = P80211ENUM_resultcode_success; 1001 1002 return 0; 1003 } 1004 1005 /*---------------------------------------------------------------- 1006 * prism2mgmt_autojoin 1007 * 1008 * Associate with an ESS. 1009 * 1010 * Arguments: 1011 * wlandev wlan device structure 1012 * msgp ptr to msg buffer 1013 * 1014 * Returns: 1015 * 0 success and done 1016 * <0 success, but we're waiting for something to finish. 1017 * >0 an error occurred while handling the message. 1018 * Side effects: 1019 * 1020 * Call context: 1021 * process thread (usually) 1022 * interrupt 1023 ----------------------------------------------------------------*/ 1024 int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp) 1025 { 1026 hfa384x_t *hw = wlandev->priv; 1027 int result = 0; 1028 u16 reg; 1029 u16 port_type; 1030 struct p80211msg_lnxreq_autojoin *msg = msgp; 1031 p80211pstrd_t *pstr; 1032 u8 bytebuf[256]; 1033 struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf; 1034 1035 wlandev->macmode = WLAN_MACMODE_NONE; 1036 1037 /* Set the SSID */ 1038 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); 1039 1040 /* Disable the Port */ 1041 hfa384x_drvr_disable(hw, 0); 1042 1043 /*** STATION ***/ 1044 /* Set the TxRates */ 1045 hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f); 1046 1047 /* Set the auth type */ 1048 if (msg->authtype.data == P80211ENUM_authalg_sharedkey) 1049 reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; 1050 else 1051 reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; 1052 1053 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); 1054 1055 /* Set the ssid */ 1056 memset(bytebuf, 0, 256); 1057 pstr = (p80211pstrd_t *) &(msg->ssid.data); 1058 prism2mgmt_pstr2bytestr(p2bytestr, pstr); 1059 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, 1060 bytebuf, 1061 HFA384x_RID_CNFDESIREDSSID_LEN); 1062 port_type = HFA384x_PORTTYPE_BSS; 1063 /* Set the PortType */ 1064 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type); 1065 1066 /* Enable the Port */ 1067 hfa384x_drvr_enable(hw, 0); 1068 1069 /* Set the resultcode */ 1070 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 1071 msg->resultcode.data = P80211ENUM_resultcode_success; 1072 1073 return result; 1074 } 1075 1076 /*---------------------------------------------------------------- 1077 * prism2mgmt_wlansniff 1078 * 1079 * Start or stop sniffing. 1080 * 1081 * Arguments: 1082 * wlandev wlan device structure 1083 * msgp ptr to msg buffer 1084 * 1085 * Returns: 1086 * 0 success and done 1087 * <0 success, but we're waiting for something to finish. 1088 * >0 an error occurred while handling the message. 1089 * Side effects: 1090 * 1091 * Call context: 1092 * process thread (usually) 1093 * interrupt 1094 ----------------------------------------------------------------*/ 1095 int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) 1096 { 1097 int result = 0; 1098 struct p80211msg_lnxreq_wlansniff *msg = msgp; 1099 1100 hfa384x_t *hw = wlandev->priv; 1101 u16 word; 1102 1103 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; 1104 switch (msg->enable.data) { 1105 case P80211ENUM_truth_false: 1106 /* Confirm that we're in monitor mode */ 1107 if (wlandev->netdev->type == ARPHRD_ETHER) { 1108 msg->resultcode.data = 1109 P80211ENUM_resultcode_invalid_parameters; 1110 return 0; 1111 } 1112 /* Disable monitor mode */ 1113 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE); 1114 if (result) { 1115 pr_debug("failed to disable monitor mode, result=%d\n", 1116 result); 1117 goto failed; 1118 } 1119 /* Disable port 0 */ 1120 result = hfa384x_drvr_disable(hw, 0); 1121 if (result) { 1122 pr_debug 1123 ("failed to disable port 0 after sniffing, result=%d\n", 1124 result); 1125 goto failed; 1126 } 1127 /* Clear the driver state */ 1128 wlandev->netdev->type = ARPHRD_ETHER; 1129 1130 /* Restore the wepflags */ 1131 result = hfa384x_drvr_setconfig16(hw, 1132 HFA384x_RID_CNFWEPFLAGS, 1133 hw->presniff_wepflags); 1134 if (result) { 1135 pr_debug 1136 ("failed to restore wepflags=0x%04x, result=%d\n", 1137 hw->presniff_wepflags, result); 1138 goto failed; 1139 } 1140 1141 /* Set the port to its prior type and enable (if necessary) */ 1142 if (hw->presniff_port_type != 0) { 1143 word = hw->presniff_port_type; 1144 result = hfa384x_drvr_setconfig16(hw, 1145 HFA384x_RID_CNFPORTTYPE, 1146 word); 1147 if (result) { 1148 pr_debug 1149 ("failed to restore porttype, result=%d\n", 1150 result); 1151 goto failed; 1152 } 1153 1154 /* Enable the port */ 1155 result = hfa384x_drvr_enable(hw, 0); 1156 if (result) { 1157 pr_debug("failed to enable port to presniff setting, result=%d\n", 1158 result); 1159 goto failed; 1160 } 1161 } else { 1162 result = hfa384x_drvr_disable(hw, 0); 1163 1164 } 1165 1166 netdev_info(wlandev->netdev, "monitor mode disabled\n"); 1167 msg->resultcode.data = P80211ENUM_resultcode_success; 1168 return 0; 1169 case P80211ENUM_truth_true: 1170 /* Disable the port (if enabled), only check Port 0 */ 1171 if (hw->port_enabled[0]) { 1172 if (wlandev->netdev->type == ARPHRD_ETHER) { 1173 /* Save macport 0 state */ 1174 result = hfa384x_drvr_getconfig16(hw, 1175 HFA384x_RID_CNFPORTTYPE, 1176 &(hw->presniff_port_type)); 1177 if (result) { 1178 pr_debug 1179 ("failed to read porttype, result=%d\n", 1180 result); 1181 goto failed; 1182 } 1183 /* Save the wepflags state */ 1184 result = hfa384x_drvr_getconfig16(hw, 1185 HFA384x_RID_CNFWEPFLAGS, 1186 &(hw->presniff_wepflags)); 1187 if (result) { 1188 pr_debug 1189 ("failed to read wepflags, result=%d\n", 1190 result); 1191 goto failed; 1192 } 1193 hfa384x_drvr_stop(hw); 1194 result = hfa384x_drvr_start(hw); 1195 if (result) { 1196 pr_debug("failed to restart the card for sniffing, result=%d\n", 1197 result); 1198 goto failed; 1199 } 1200 } else { 1201 /* Disable the port */ 1202 result = hfa384x_drvr_disable(hw, 0); 1203 if (result) { 1204 pr_debug("failed to enable port for sniffing, result=%d\n", 1205 result); 1206 goto failed; 1207 } 1208 } 1209 } else { 1210 hw->presniff_port_type = 0; 1211 } 1212 1213 /* Set the channel we wish to sniff */ 1214 word = msg->channel.data; 1215 result = hfa384x_drvr_setconfig16(hw, 1216 HFA384x_RID_CNFOWNCHANNEL, 1217 word); 1218 hw->sniff_channel = word; 1219 1220 if (result) { 1221 pr_debug("failed to set channel %d, result=%d\n", 1222 word, result); 1223 goto failed; 1224 } 1225 1226 /* Now if we're already sniffing, we can skip the rest */ 1227 if (wlandev->netdev->type != ARPHRD_ETHER) { 1228 /* Set the port type to pIbss */ 1229 word = HFA384x_PORTTYPE_PSUEDOIBSS; 1230 result = hfa384x_drvr_setconfig16(hw, 1231 HFA384x_RID_CNFPORTTYPE, 1232 word); 1233 if (result) { 1234 pr_debug 1235 ("failed to set porttype %d, result=%d\n", 1236 word, result); 1237 goto failed; 1238 } 1239 if ((msg->keepwepflags.status == 1240 P80211ENUM_msgitem_status_data_ok) 1241 && (msg->keepwepflags.data != 1242 P80211ENUM_truth_true)) { 1243 /* Set the wepflags for no decryption */ 1244 word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | 1245 HFA384x_WEPFLAGS_DISABLE_RXCRYPT; 1246 result = 1247 hfa384x_drvr_setconfig16(hw, 1248 HFA384x_RID_CNFWEPFLAGS, 1249 word); 1250 } 1251 1252 if (result) { 1253 pr_debug 1254 ("failed to set wepflags=0x%04x, result=%d\n", 1255 word, result); 1256 goto failed; 1257 } 1258 } 1259 1260 /* Do we want to strip the FCS in monitor mode? */ 1261 if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) 1262 && (msg->stripfcs.data == P80211ENUM_truth_true)) { 1263 hw->sniff_fcs = 0; 1264 } else { 1265 hw->sniff_fcs = 1; 1266 } 1267 1268 /* Do we want to truncate the packets? */ 1269 if (msg->packet_trunc.status == 1270 P80211ENUM_msgitem_status_data_ok) { 1271 hw->sniff_truncate = msg->packet_trunc.data; 1272 } else { 1273 hw->sniff_truncate = 0; 1274 } 1275 1276 /* Enable the port */ 1277 result = hfa384x_drvr_enable(hw, 0); 1278 if (result) { 1279 pr_debug 1280 ("failed to enable port for sniffing, result=%d\n", 1281 result); 1282 goto failed; 1283 } 1284 /* Enable monitor mode */ 1285 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE); 1286 if (result) { 1287 pr_debug("failed to enable monitor mode, result=%d\n", 1288 result); 1289 goto failed; 1290 } 1291 1292 if (wlandev->netdev->type == ARPHRD_ETHER) 1293 netdev_info(wlandev->netdev, "monitor mode enabled\n"); 1294 1295 /* Set the driver state */ 1296 /* Do we want the prism2 header? */ 1297 if ((msg->prismheader.status == 1298 P80211ENUM_msgitem_status_data_ok) 1299 && (msg->prismheader.data == P80211ENUM_truth_true)) { 1300 hw->sniffhdr = 0; 1301 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; 1302 } else 1303 if ((msg->wlanheader.status == 1304 P80211ENUM_msgitem_status_data_ok) 1305 && (msg->wlanheader.data == P80211ENUM_truth_true)) { 1306 hw->sniffhdr = 1; 1307 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; 1308 } else { 1309 wlandev->netdev->type = ARPHRD_IEEE80211; 1310 } 1311 1312 msg->resultcode.data = P80211ENUM_resultcode_success; 1313 return 0; 1314 default: 1315 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; 1316 return 0; 1317 } 1318 1319 failed: 1320 msg->resultcode.data = P80211ENUM_resultcode_refused; 1321 return 0; 1322 } 1323