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