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