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