1 // SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) 2 /* src/prism2/driver/prism2sta.c 3 * 4 * Implements the station functionality for prism2 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 * This file implements the module and linux pcmcia routines for the 49 * prism2 driver. 50 * 51 * -------------------------------------------------------------------- 52 */ 53 54 #include <linux/module.h> 55 #include <linux/kernel.h> 56 #include <linux/sched.h> 57 #include <linux/types.h> 58 #include <linux/slab.h> 59 #include <linux/wireless.h> 60 #include <linux/netdevice.h> 61 #include <linux/workqueue.h> 62 #include <linux/byteorder/generic.h> 63 #include <linux/etherdevice.h> 64 65 #include <linux/io.h> 66 #include <linux/delay.h> 67 #include <asm/byteorder.h> 68 #include <linux/if_arp.h> 69 #include <linux/if_ether.h> 70 #include <linux/bitops.h> 71 72 #include "p80211types.h" 73 #include "p80211hdr.h" 74 #include "p80211mgmt.h" 75 #include "p80211conv.h" 76 #include "p80211msg.h" 77 #include "p80211netdev.h" 78 #include "p80211req.h" 79 #include "p80211metadef.h" 80 #include "p80211metastruct.h" 81 #include "hfa384x.h" 82 #include "prism2mgmt.h" 83 84 static char *dev_info = "prism2_usb"; 85 static struct wlandevice *create_wlan(void); 86 87 int prism2_reset_holdtime = 30; /* Reset hold time in ms */ 88 int prism2_reset_settletime = 100; /* Reset settle time in ms */ 89 90 static int prism2_doreset; /* Do a reset at init? */ 91 92 module_param(prism2_doreset, int, 0644); 93 MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization"); 94 95 module_param(prism2_reset_holdtime, int, 0644); 96 MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms"); 97 module_param(prism2_reset_settletime, int, 0644); 98 MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms"); 99 100 MODULE_LICENSE("Dual MPL/GPL"); 101 102 static int prism2sta_open(struct wlandevice *wlandev); 103 static int prism2sta_close(struct wlandevice *wlandev); 104 static void prism2sta_reset(struct wlandevice *wlandev); 105 static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb, 106 union p80211_hdr *p80211_hdr, 107 struct p80211_metawep *p80211_wep); 108 static int prism2sta_mlmerequest(struct wlandevice *wlandev, 109 struct p80211msg *msg); 110 static int prism2sta_getcardinfo(struct wlandevice *wlandev); 111 static int prism2sta_globalsetup(struct wlandevice *wlandev); 112 static int prism2sta_setmulticast(struct wlandevice *wlandev, 113 struct net_device *dev); 114 115 static void prism2sta_inf_handover(struct wlandevice *wlandev, 116 struct hfa384x_inf_frame *inf); 117 static void prism2sta_inf_tallies(struct wlandevice *wlandev, 118 struct hfa384x_inf_frame *inf); 119 static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, 120 struct hfa384x_inf_frame *inf); 121 static void prism2sta_inf_scanresults(struct wlandevice *wlandev, 122 struct hfa384x_inf_frame *inf); 123 static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, 124 struct hfa384x_inf_frame *inf); 125 static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, 126 struct hfa384x_inf_frame *inf); 127 static void prism2sta_inf_assocstatus(struct wlandevice *wlandev, 128 struct hfa384x_inf_frame *inf); 129 static void prism2sta_inf_authreq(struct wlandevice *wlandev, 130 struct hfa384x_inf_frame *inf); 131 static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, 132 struct hfa384x_inf_frame *inf); 133 static void prism2sta_inf_psusercnt(struct wlandevice *wlandev, 134 struct hfa384x_inf_frame *inf); 135 136 /* 137 * prism2sta_open 138 * 139 * WLAN device open method. Called from p80211netdev when kernel 140 * device open (start) method is called in response to the 141 * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP 142 * from clear to set. 143 * 144 * Arguments: 145 * wlandev wlan device structure 146 * 147 * Returns: 148 * 0 success 149 * >0 f/w reported error 150 * <0 driver reported error 151 * 152 * Side effects: 153 * 154 * Call context: 155 * process thread 156 */ 157 static int prism2sta_open(struct wlandevice *wlandev) 158 { 159 /* We don't currently have to do anything else. 160 * The setup of the MAC should be subsequently completed via 161 * the mlme commands. 162 * Higher layers know we're ready from dev->start==1 and 163 * dev->tbusy==0. Our rx path knows to pass up received/ 164 * frames because of dev->flags&IFF_UP is true. 165 */ 166 167 return 0; 168 } 169 170 /* 171 * prism2sta_close 172 * 173 * WLAN device close method. Called from p80211netdev when kernel 174 * device close method is called in response to the 175 * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP 176 * from set to clear. 177 * 178 * Arguments: 179 * wlandev wlan device structure 180 * 181 * Returns: 182 * 0 success 183 * >0 f/w reported error 184 * <0 driver reported error 185 * 186 * Side effects: 187 * 188 * Call context: 189 * process thread 190 */ 191 static int prism2sta_close(struct wlandevice *wlandev) 192 { 193 /* We don't currently have to do anything else. 194 * Higher layers know we're not ready from dev->start==0 and 195 * dev->tbusy==1. Our rx path knows to not pass up received 196 * frames because of dev->flags&IFF_UP is false. 197 */ 198 199 return 0; 200 } 201 202 /* 203 * prism2sta_reset 204 * 205 * Currently not implemented. 206 * 207 * Arguments: 208 * wlandev wlan device structure 209 * none 210 * 211 * Returns: 212 * nothing 213 * 214 * Side effects: 215 * 216 * Call context: 217 * process thread 218 */ 219 static void prism2sta_reset(struct wlandevice *wlandev) 220 { 221 } 222 223 /* 224 * prism2sta_txframe 225 * 226 * Takes a frame from p80211 and queues it for transmission. 227 * 228 * Arguments: 229 * wlandev wlan device structure 230 * pb packet buffer struct. Contains an 802.11 231 * data frame. 232 * p80211_hdr points to the 802.11 header for the packet. 233 * Returns: 234 * 0 Success and more buffs available 235 * 1 Success but no more buffs 236 * 2 Allocation failure 237 * 4 Buffer full or queue busy 238 * 239 * Side effects: 240 * 241 * Call context: 242 * process thread 243 */ 244 static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb, 245 union p80211_hdr *p80211_hdr, 246 struct p80211_metawep *p80211_wep) 247 { 248 struct hfa384x *hw = wlandev->priv; 249 250 /* If necessary, set the 802.11 WEP bit */ 251 if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == 252 HOSTWEP_PRIVACYINVOKED) { 253 p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); 254 } 255 256 return hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep); 257 } 258 259 /* 260 * prism2sta_mlmerequest 261 * 262 * wlan command message handler. All we do here is pass the message 263 * over to the prism2sta_mgmt_handler. 264 * 265 * Arguments: 266 * wlandev wlan device structure 267 * msg wlan command message 268 * Returns: 269 * 0 success 270 * <0 successful acceptance of message, but we're 271 * waiting for an async process to finish before 272 * we're done with the msg. When the asynch 273 * process is done, we'll call the p80211 274 * function p80211req_confirm() . 275 * >0 An error occurred while we were handling 276 * the message. 277 * 278 * Side effects: 279 * 280 * Call context: 281 * process thread 282 */ 283 static int prism2sta_mlmerequest(struct wlandevice *wlandev, 284 struct p80211msg *msg) 285 { 286 struct hfa384x *hw = wlandev->priv; 287 288 int result = 0; 289 290 switch (msg->msgcode) { 291 case DIDMSG_DOT11REQ_MIBGET: 292 pr_debug("Received mibget request\n"); 293 result = prism2mgmt_mibset_mibget(wlandev, msg); 294 break; 295 case DIDMSG_DOT11REQ_MIBSET: 296 pr_debug("Received mibset request\n"); 297 result = prism2mgmt_mibset_mibget(wlandev, msg); 298 break; 299 case DIDMSG_DOT11REQ_SCAN: 300 pr_debug("Received scan request\n"); 301 result = prism2mgmt_scan(wlandev, msg); 302 break; 303 case DIDMSG_DOT11REQ_SCAN_RESULTS: 304 pr_debug("Received scan_results request\n"); 305 result = prism2mgmt_scan_results(wlandev, msg); 306 break; 307 case DIDMSG_DOT11REQ_START: 308 pr_debug("Received mlme start request\n"); 309 result = prism2mgmt_start(wlandev, msg); 310 break; 311 /* 312 * Prism2 specific messages 313 */ 314 case DIDMSG_P2REQ_READPDA: 315 pr_debug("Received mlme readpda request\n"); 316 result = prism2mgmt_readpda(wlandev, msg); 317 break; 318 case DIDMSG_P2REQ_RAMDL_STATE: 319 pr_debug("Received mlme ramdl_state request\n"); 320 result = prism2mgmt_ramdl_state(wlandev, msg); 321 break; 322 case DIDMSG_P2REQ_RAMDL_WRITE: 323 pr_debug("Received mlme ramdl_write request\n"); 324 result = prism2mgmt_ramdl_write(wlandev, msg); 325 break; 326 case DIDMSG_P2REQ_FLASHDL_STATE: 327 pr_debug("Received mlme flashdl_state request\n"); 328 result = prism2mgmt_flashdl_state(wlandev, msg); 329 break; 330 case DIDMSG_P2REQ_FLASHDL_WRITE: 331 pr_debug("Received mlme flashdl_write request\n"); 332 result = prism2mgmt_flashdl_write(wlandev, msg); 333 break; 334 /* 335 * Linux specific messages 336 */ 337 case DIDMSG_LNXREQ_HOSTWEP: 338 break; /* ignore me. */ 339 case DIDMSG_LNXREQ_IFSTATE: { 340 struct p80211msg_lnxreq_ifstate *ifstatemsg; 341 342 pr_debug("Received mlme ifstate request\n"); 343 ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg; 344 result = prism2sta_ifstate(wlandev, 345 ifstatemsg->ifstate.data); 346 ifstatemsg->resultcode.status = 347 P80211ENUM_msgitem_status_data_ok; 348 ifstatemsg->resultcode.data = result; 349 result = 0; 350 break; 351 } 352 case DIDMSG_LNXREQ_WLANSNIFF: 353 pr_debug("Received mlme wlansniff request\n"); 354 result = prism2mgmt_wlansniff(wlandev, msg); 355 break; 356 case DIDMSG_LNXREQ_AUTOJOIN: 357 pr_debug("Received mlme autojoin request\n"); 358 result = prism2mgmt_autojoin(wlandev, msg); 359 break; 360 case DIDMSG_LNXREQ_COMMSQUALITY: { 361 struct p80211msg_lnxreq_commsquality *qualmsg; 362 363 pr_debug("Received commsquality request\n"); 364 365 qualmsg = (struct p80211msg_lnxreq_commsquality *)msg; 366 367 qualmsg->link.status = P80211ENUM_msgitem_status_data_ok; 368 qualmsg->level.status = P80211ENUM_msgitem_status_data_ok; 369 qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok; 370 371 qualmsg->link.data = le16_to_cpu(hw->qual.cq_curr_bss); 372 qualmsg->level.data = le16_to_cpu(hw->qual.asl_curr_bss); 373 qualmsg->noise.data = le16_to_cpu(hw->qual.anl_curr_fc); 374 qualmsg->txrate.data = hw->txrate; 375 376 break; 377 } 378 default: 379 netdev_warn(wlandev->netdev, 380 "Unknown mgmt request message 0x%08x", 381 msg->msgcode); 382 break; 383 } 384 385 return result; 386 } 387 388 /* 389 * prism2sta_ifstate 390 * 391 * Interface state. This is the primary WLAN interface enable/disable 392 * handler. Following the driver/load/deviceprobe sequence, this 393 * function must be called with a state of "enable" before any other 394 * commands will be accepted. 395 * 396 * Arguments: 397 * wlandev wlan device structure 398 * msgp ptr to msg buffer 399 * 400 * Returns: 401 * A p80211 message resultcode value. 402 * 403 * Side effects: 404 * 405 * Call context: 406 * process thread (usually) 407 * interrupt 408 */ 409 u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate) 410 { 411 struct hfa384x *hw = wlandev->priv; 412 u32 result; 413 414 result = P80211ENUM_resultcode_implementation_failure; 415 416 pr_debug("Current MSD state(%d), requesting(%d)\n", 417 wlandev->msdstate, ifstate); 418 switch (ifstate) { 419 case P80211ENUM_ifstate_fwload: 420 switch (wlandev->msdstate) { 421 case WLAN_MSD_HWPRESENT: 422 wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING; 423 /* 424 * Initialize the device+driver sufficiently 425 * for firmware loading. 426 */ 427 result = hfa384x_drvr_start(hw); 428 if (result) { 429 netdev_err(wlandev->netdev, 430 "hfa384x_drvr_start() failed,result=%d\n", 431 (int)result); 432 result = 433 P80211ENUM_resultcode_implementation_failure; 434 wlandev->msdstate = WLAN_MSD_HWPRESENT; 435 break; 436 } 437 wlandev->msdstate = WLAN_MSD_FWLOAD; 438 result = P80211ENUM_resultcode_success; 439 break; 440 case WLAN_MSD_FWLOAD: 441 hfa384x_cmd_initialize(hw); 442 result = P80211ENUM_resultcode_success; 443 break; 444 case WLAN_MSD_RUNNING: 445 netdev_warn(wlandev->netdev, 446 "Cannot enter fwload state from enable state, you must disable first.\n"); 447 result = P80211ENUM_resultcode_invalid_parameters; 448 break; 449 case WLAN_MSD_HWFAIL: 450 default: 451 /* probe() had a problem or the msdstate contains 452 * an unrecognized value, there's nothing we can do. 453 */ 454 result = P80211ENUM_resultcode_implementation_failure; 455 break; 456 } 457 break; 458 case P80211ENUM_ifstate_enable: 459 switch (wlandev->msdstate) { 460 case WLAN_MSD_HWPRESENT: 461 case WLAN_MSD_FWLOAD: 462 wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; 463 /* Initialize the device+driver for full 464 * operation. Note that this might me an FWLOAD 465 * to RUNNING transition so we must not do a chip 466 * or board level reset. Note that on failure, 467 * the MSD state is set to HWPRESENT because we 468 * can't make any assumptions about the state 469 * of the hardware or a previous firmware load. 470 */ 471 result = hfa384x_drvr_start(hw); 472 if (result) { 473 netdev_err(wlandev->netdev, 474 "hfa384x_drvr_start() failed,result=%d\n", 475 (int)result); 476 result = 477 P80211ENUM_resultcode_implementation_failure; 478 wlandev->msdstate = WLAN_MSD_HWPRESENT; 479 break; 480 } 481 482 result = prism2sta_getcardinfo(wlandev); 483 if (result) { 484 netdev_err(wlandev->netdev, 485 "prism2sta_getcardinfo() failed,result=%d\n", 486 (int)result); 487 result = 488 P80211ENUM_resultcode_implementation_failure; 489 hfa384x_drvr_stop(hw); 490 wlandev->msdstate = WLAN_MSD_HWPRESENT; 491 break; 492 } 493 result = prism2sta_globalsetup(wlandev); 494 if (result) { 495 netdev_err(wlandev->netdev, 496 "prism2sta_globalsetup() failed,result=%d\n", 497 (int)result); 498 result = 499 P80211ENUM_resultcode_implementation_failure; 500 hfa384x_drvr_stop(hw); 501 wlandev->msdstate = WLAN_MSD_HWPRESENT; 502 break; 503 } 504 wlandev->msdstate = WLAN_MSD_RUNNING; 505 hw->join_ap = 0; 506 hw->join_retries = 60; 507 result = P80211ENUM_resultcode_success; 508 break; 509 case WLAN_MSD_RUNNING: 510 /* Do nothing, we're already in this state. */ 511 result = P80211ENUM_resultcode_success; 512 break; 513 case WLAN_MSD_HWFAIL: 514 default: 515 /* probe() had a problem or the msdstate contains 516 * an unrecognized value, there's nothing we can do. 517 */ 518 result = P80211ENUM_resultcode_implementation_failure; 519 break; 520 } 521 break; 522 case P80211ENUM_ifstate_disable: 523 switch (wlandev->msdstate) { 524 case WLAN_MSD_HWPRESENT: 525 /* Do nothing, we're already in this state. */ 526 result = P80211ENUM_resultcode_success; 527 break; 528 case WLAN_MSD_FWLOAD: 529 case WLAN_MSD_RUNNING: 530 wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; 531 /* 532 * TODO: Shut down the MAC completely. Here a chip 533 * or board level reset is probably called for. 534 * After a "disable" _all_ results are lost, even 535 * those from a fwload. 536 */ 537 if (!wlandev->hwremoved) 538 netif_carrier_off(wlandev->netdev); 539 540 hfa384x_drvr_stop(hw); 541 542 wlandev->macmode = WLAN_MACMODE_NONE; 543 wlandev->msdstate = WLAN_MSD_HWPRESENT; 544 result = P80211ENUM_resultcode_success; 545 break; 546 case WLAN_MSD_HWFAIL: 547 default: 548 /* probe() had a problem or the msdstate contains 549 * an unrecognized value, there's nothing we can do. 550 */ 551 result = P80211ENUM_resultcode_implementation_failure; 552 break; 553 } 554 break; 555 default: 556 result = P80211ENUM_resultcode_invalid_parameters; 557 break; 558 } 559 560 return result; 561 } 562 563 /* 564 * prism2sta_getcardinfo 565 * 566 * Collect the NICID, firmware version and any other identifiers 567 * we'd like to have in host-side data structures. 568 * 569 * Arguments: 570 * wlandev wlan device structure 571 * 572 * Returns: 573 * 0 success 574 * >0 f/w reported error 575 * <0 driver reported error 576 * 577 * Side effects: 578 * 579 * Call context: 580 * Either. 581 */ 582 static int prism2sta_getcardinfo(struct wlandevice *wlandev) 583 { 584 int result = 0; 585 struct hfa384x *hw = wlandev->priv; 586 u16 temp; 587 u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; 588 589 /* Collect version and compatibility info */ 590 /* Some are critical, some are not */ 591 /* NIC identity */ 592 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY, 593 &hw->ident_nic, 594 sizeof(struct hfa384x_compident)); 595 if (result) { 596 netdev_err(wlandev->netdev, "Failed to retrieve NICIDENTITY\n"); 597 goto failed; 598 } 599 600 /* get all the nic id fields in host byte order */ 601 le16_to_cpus(&hw->ident_nic.id); 602 le16_to_cpus(&hw->ident_nic.variant); 603 le16_to_cpus(&hw->ident_nic.major); 604 le16_to_cpus(&hw->ident_nic.minor); 605 606 netdev_info(wlandev->netdev, "ident: nic h/w: id=0x%02x %d.%d.%d\n", 607 hw->ident_nic.id, hw->ident_nic.major, 608 hw->ident_nic.minor, hw->ident_nic.variant); 609 610 /* Primary f/w identity */ 611 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY, 612 &hw->ident_pri_fw, 613 sizeof(struct hfa384x_compident)); 614 if (result) { 615 netdev_err(wlandev->netdev, "Failed to retrieve PRIIDENTITY\n"); 616 goto failed; 617 } 618 619 /* get all the private fw id fields in host byte order */ 620 le16_to_cpus(&hw->ident_pri_fw.id); 621 le16_to_cpus(&hw->ident_pri_fw.variant); 622 le16_to_cpus(&hw->ident_pri_fw.major); 623 le16_to_cpus(&hw->ident_pri_fw.minor); 624 625 netdev_info(wlandev->netdev, "ident: pri f/w: id=0x%02x %d.%d.%d\n", 626 hw->ident_pri_fw.id, hw->ident_pri_fw.major, 627 hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); 628 629 /* Station (Secondary?) f/w identity */ 630 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY, 631 &hw->ident_sta_fw, 632 sizeof(struct hfa384x_compident)); 633 if (result) { 634 netdev_err(wlandev->netdev, "Failed to retrieve STAIDENTITY\n"); 635 goto failed; 636 } 637 638 if (hw->ident_nic.id < 0x8000) { 639 netdev_err(wlandev->netdev, 640 "FATAL: Card is not an Intersil Prism2/2.5/3\n"); 641 result = -1; 642 goto failed; 643 } 644 645 /* get all the station fw id fields in host byte order */ 646 le16_to_cpus(&hw->ident_sta_fw.id); 647 le16_to_cpus(&hw->ident_sta_fw.variant); 648 le16_to_cpus(&hw->ident_sta_fw.major); 649 le16_to_cpus(&hw->ident_sta_fw.minor); 650 651 /* strip out the 'special' variant bits */ 652 hw->mm_mods = hw->ident_sta_fw.variant & GENMASK(15, 14); 653 hw->ident_sta_fw.variant &= ~((u16)GENMASK(15, 14)); 654 655 if (hw->ident_sta_fw.id == 0x1f) { 656 netdev_info(wlandev->netdev, 657 "ident: sta f/w: id=0x%02x %d.%d.%d\n", 658 hw->ident_sta_fw.id, hw->ident_sta_fw.major, 659 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); 660 } else { 661 netdev_info(wlandev->netdev, 662 "ident: ap f/w: id=0x%02x %d.%d.%d\n", 663 hw->ident_sta_fw.id, hw->ident_sta_fw.major, 664 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); 665 netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmware loaded!\n"); 666 goto failed; 667 } 668 669 /* Compatibility range, Modem supplier */ 670 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE, 671 &hw->cap_sup_mfi, 672 sizeof(struct hfa384x_caplevel)); 673 if (result) { 674 netdev_err(wlandev->netdev, "Failed to retrieve MFISUPRANGE\n"); 675 goto failed; 676 } 677 678 /* get all the Compatibility range, modem interface supplier 679 * fields in byte order 680 */ 681 le16_to_cpus(&hw->cap_sup_mfi.role); 682 le16_to_cpus(&hw->cap_sup_mfi.id); 683 le16_to_cpus(&hw->cap_sup_mfi.variant); 684 le16_to_cpus(&hw->cap_sup_mfi.bottom); 685 le16_to_cpus(&hw->cap_sup_mfi.top); 686 687 netdev_info(wlandev->netdev, 688 "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 689 hw->cap_sup_mfi.role, hw->cap_sup_mfi.id, 690 hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom, 691 hw->cap_sup_mfi.top); 692 693 /* Compatibility range, Controller supplier */ 694 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE, 695 &hw->cap_sup_cfi, 696 sizeof(struct hfa384x_caplevel)); 697 if (result) { 698 netdev_err(wlandev->netdev, "Failed to retrieve CFISUPRANGE\n"); 699 goto failed; 700 } 701 702 /* get all the Compatibility range, controller interface supplier 703 * fields in byte order 704 */ 705 le16_to_cpus(&hw->cap_sup_cfi.role); 706 le16_to_cpus(&hw->cap_sup_cfi.id); 707 le16_to_cpus(&hw->cap_sup_cfi.variant); 708 le16_to_cpus(&hw->cap_sup_cfi.bottom); 709 le16_to_cpus(&hw->cap_sup_cfi.top); 710 711 netdev_info(wlandev->netdev, 712 "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 713 hw->cap_sup_cfi.role, hw->cap_sup_cfi.id, 714 hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom, 715 hw->cap_sup_cfi.top); 716 717 /* Compatibility range, Primary f/w supplier */ 718 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE, 719 &hw->cap_sup_pri, 720 sizeof(struct hfa384x_caplevel)); 721 if (result) { 722 netdev_err(wlandev->netdev, "Failed to retrieve PRISUPRANGE\n"); 723 goto failed; 724 } 725 726 /* get all the Compatibility range, primary firmware supplier 727 * fields in byte order 728 */ 729 le16_to_cpus(&hw->cap_sup_pri.role); 730 le16_to_cpus(&hw->cap_sup_pri.id); 731 le16_to_cpus(&hw->cap_sup_pri.variant); 732 le16_to_cpus(&hw->cap_sup_pri.bottom); 733 le16_to_cpus(&hw->cap_sup_pri.top); 734 735 netdev_info(wlandev->netdev, 736 "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 737 hw->cap_sup_pri.role, hw->cap_sup_pri.id, 738 hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom, 739 hw->cap_sup_pri.top); 740 741 /* Compatibility range, Station f/w supplier */ 742 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE, 743 &hw->cap_sup_sta, 744 sizeof(struct hfa384x_caplevel)); 745 if (result) { 746 netdev_err(wlandev->netdev, "Failed to retrieve STASUPRANGE\n"); 747 goto failed; 748 } 749 750 /* get all the Compatibility range, station firmware supplier 751 * fields in byte order 752 */ 753 le16_to_cpus(&hw->cap_sup_sta.role); 754 le16_to_cpus(&hw->cap_sup_sta.id); 755 le16_to_cpus(&hw->cap_sup_sta.variant); 756 le16_to_cpus(&hw->cap_sup_sta.bottom); 757 le16_to_cpus(&hw->cap_sup_sta.top); 758 759 if (hw->cap_sup_sta.id == 0x04) { 760 netdev_info(wlandev->netdev, 761 "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 762 hw->cap_sup_sta.role, hw->cap_sup_sta.id, 763 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, 764 hw->cap_sup_sta.top); 765 } else { 766 netdev_info(wlandev->netdev, 767 "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 768 hw->cap_sup_sta.role, hw->cap_sup_sta.id, 769 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, 770 hw->cap_sup_sta.top); 771 } 772 773 /* Compatibility range, primary f/w actor, CFI supplier */ 774 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES, 775 &hw->cap_act_pri_cfi, 776 sizeof(struct hfa384x_caplevel)); 777 if (result) { 778 netdev_err(wlandev->netdev, "Failed to retrieve PRI_CFIACTRANGES\n"); 779 goto failed; 780 } 781 782 /* get all the Compatibility range, primary f/w actor, CFI supplier 783 * fields in byte order 784 */ 785 le16_to_cpus(&hw->cap_act_pri_cfi.role); 786 le16_to_cpus(&hw->cap_act_pri_cfi.id); 787 le16_to_cpus(&hw->cap_act_pri_cfi.variant); 788 le16_to_cpus(&hw->cap_act_pri_cfi.bottom); 789 le16_to_cpus(&hw->cap_act_pri_cfi.top); 790 791 netdev_info(wlandev->netdev, 792 "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 793 hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id, 794 hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom, 795 hw->cap_act_pri_cfi.top); 796 797 /* Compatibility range, sta f/w actor, CFI supplier */ 798 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES, 799 &hw->cap_act_sta_cfi, 800 sizeof(struct hfa384x_caplevel)); 801 if (result) { 802 netdev_err(wlandev->netdev, "Failed to retrieve STA_CFIACTRANGES\n"); 803 goto failed; 804 } 805 806 /* get all the Compatibility range, station f/w actor, CFI supplier 807 * fields in byte order 808 */ 809 le16_to_cpus(&hw->cap_act_sta_cfi.role); 810 le16_to_cpus(&hw->cap_act_sta_cfi.id); 811 le16_to_cpus(&hw->cap_act_sta_cfi.variant); 812 le16_to_cpus(&hw->cap_act_sta_cfi.bottom); 813 le16_to_cpus(&hw->cap_act_sta_cfi.top); 814 815 netdev_info(wlandev->netdev, 816 "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 817 hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id, 818 hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom, 819 hw->cap_act_sta_cfi.top); 820 821 /* Compatibility range, sta f/w actor, MFI supplier */ 822 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES, 823 &hw->cap_act_sta_mfi, 824 sizeof(struct hfa384x_caplevel)); 825 if (result) { 826 netdev_err(wlandev->netdev, "Failed to retrieve STA_MFIACTRANGES\n"); 827 goto failed; 828 } 829 830 /* get all the Compatibility range, station f/w actor, MFI supplier 831 * fields in byte order 832 */ 833 le16_to_cpus(&hw->cap_act_sta_mfi.role); 834 le16_to_cpus(&hw->cap_act_sta_mfi.id); 835 le16_to_cpus(&hw->cap_act_sta_mfi.variant); 836 le16_to_cpus(&hw->cap_act_sta_mfi.bottom); 837 le16_to_cpus(&hw->cap_act_sta_mfi.top); 838 839 netdev_info(wlandev->netdev, 840 "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 841 hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id, 842 hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom, 843 hw->cap_act_sta_mfi.top); 844 845 /* Serial Number */ 846 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, 847 snum, HFA384x_RID_NICSERIALNUMBER_LEN); 848 if (!result) { 849 netdev_info(wlandev->netdev, "Prism2 card SN: %*pE\n", 850 HFA384x_RID_NICSERIALNUMBER_LEN, snum); 851 } else { 852 netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); 853 goto failed; 854 } 855 856 /* Collect the MAC address */ 857 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR, 858 wlandev->netdev->dev_addr, ETH_ALEN); 859 if (result != 0) { 860 netdev_err(wlandev->netdev, "Failed to retrieve mac address\n"); 861 goto failed; 862 } 863 864 /* short preamble is always implemented */ 865 wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE; 866 867 /* find out if hardware wep is implemented */ 868 hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp); 869 if (temp) 870 wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP; 871 872 /* get the dBm Scaling constant */ 873 hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp); 874 hw->dbmadjust = temp; 875 876 /* Only enable scan by default on newer firmware */ 877 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, 878 hw->ident_sta_fw.minor, 879 hw->ident_sta_fw.variant) < 880 HFA384x_FIRMWARE_VERSION(1, 5, 5)) { 881 wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN; 882 } 883 884 /* TODO: Set any internally managed config items */ 885 886 goto done; 887 failed: 888 netdev_err(wlandev->netdev, "Failed, result=%d\n", result); 889 done: 890 return result; 891 } 892 893 /* 894 * prism2sta_globalsetup 895 * 896 * Set any global RIDs that we want to set at device activation. 897 * 898 * Arguments: 899 * wlandev wlan device structure 900 * 901 * Returns: 902 * 0 success 903 * >0 f/w reported error 904 * <0 driver reported error 905 * 906 * Side effects: 907 * 908 * Call context: 909 * process thread 910 */ 911 static int prism2sta_globalsetup(struct wlandevice *wlandev) 912 { 913 struct hfa384x *hw = wlandev->priv; 914 915 /* Set the maximum frame size */ 916 return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 917 WLAN_DATA_MAXLEN); 918 } 919 920 static int prism2sta_setmulticast(struct wlandevice *wlandev, 921 struct net_device *dev) 922 { 923 int result = 0; 924 struct hfa384x *hw = wlandev->priv; 925 926 u16 promisc; 927 928 /* If we're not ready, what's the point? */ 929 if (hw->state != HFA384x_STATE_RUNNING) 930 goto exit; 931 932 if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) 933 promisc = P80211ENUM_truth_true; 934 else 935 promisc = P80211ENUM_truth_false; 936 937 result = 938 hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, 939 promisc); 940 exit: 941 return result; 942 } 943 944 /* 945 * prism2sta_inf_handover 946 * 947 * Handles the receipt of a Handover info frame. Should only be present 948 * in APs only. 949 * 950 * Arguments: 951 * wlandev wlan device structure 952 * inf ptr to info frame (contents in hfa384x order) 953 * 954 * Returns: 955 * nothing 956 * 957 * Side effects: 958 * 959 * Call context: 960 * interrupt 961 */ 962 static void prism2sta_inf_handover(struct wlandevice *wlandev, 963 struct hfa384x_inf_frame *inf) 964 { 965 pr_debug("received infoframe:HANDOVER (unhandled)\n"); 966 } 967 968 /* 969 * prism2sta_inf_tallies 970 * 971 * Handles the receipt of a CommTallies info frame. 972 * 973 * Arguments: 974 * wlandev wlan device structure 975 * inf ptr to info frame (contents in hfa384x order) 976 * 977 * Returns: 978 * nothing 979 * 980 * Side effects: 981 * 982 * Call context: 983 * interrupt 984 */ 985 static void prism2sta_inf_tallies(struct wlandevice *wlandev, 986 struct hfa384x_inf_frame *inf) 987 { 988 struct hfa384x *hw = wlandev->priv; 989 __le16 *src16; 990 u32 *dst; 991 __le32 *src32; 992 int i; 993 int cnt; 994 995 /* 996 * Determine if these are 16-bit or 32-bit tallies, based on the 997 * record length of the info record. 998 */ 999 1000 cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32); 1001 if (inf->framelen > 22) { 1002 dst = (u32 *)&hw->tallies; 1003 src32 = (__le32 *)&inf->info.commtallies32; 1004 for (i = 0; i < cnt; i++, dst++, src32++) 1005 *dst += le32_to_cpu(*src32); 1006 } else { 1007 dst = (u32 *)&hw->tallies; 1008 src16 = (__le16 *)&inf->info.commtallies16; 1009 for (i = 0; i < cnt; i++, dst++, src16++) 1010 *dst += le16_to_cpu(*src16); 1011 } 1012 } 1013 1014 /* 1015 * prism2sta_inf_scanresults 1016 * 1017 * Handles the receipt of a Scan Results info frame. 1018 * 1019 * Arguments: 1020 * wlandev wlan device structure 1021 * inf ptr to info frame (contents in hfa384x order) 1022 * 1023 * Returns: 1024 * nothing 1025 * 1026 * Side effects: 1027 * 1028 * Call context: 1029 * interrupt 1030 */ 1031 static void prism2sta_inf_scanresults(struct wlandevice *wlandev, 1032 struct hfa384x_inf_frame *inf) 1033 { 1034 struct hfa384x *hw = wlandev->priv; 1035 int nbss; 1036 struct hfa384x_scan_result *sr = &inf->info.scanresult; 1037 int i; 1038 struct hfa384x_join_request_data joinreq; 1039 int result; 1040 1041 /* Get the number of results, first in bytes, then in results */ 1042 nbss = (inf->framelen * sizeof(u16)) - 1043 sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason); 1044 nbss /= sizeof(struct hfa384x_scan_result_sub); 1045 1046 /* Print em */ 1047 pr_debug("rx scanresults, reason=%d, nbss=%d:\n", 1048 inf->info.scanresult.scanreason, nbss); 1049 for (i = 0; i < nbss; i++) { 1050 pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n", 1051 sr->result[i].chid, 1052 sr->result[i].anl, 1053 sr->result[i].sl, sr->result[i].bcnint); 1054 pr_debug(" capinfo=0x%04x proberesp_rate=%d\n", 1055 sr->result[i].capinfo, sr->result[i].proberesp_rate); 1056 } 1057 /* issue a join request */ 1058 joinreq.channel = sr->result[0].chid; 1059 memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN); 1060 result = hfa384x_drvr_setconfig(hw, 1061 HFA384x_RID_JOINREQUEST, 1062 &joinreq, HFA384x_RID_JOINREQUEST_LEN); 1063 if (result) { 1064 netdev_err(wlandev->netdev, "setconfig(joinreq) failed, result=%d\n", 1065 result); 1066 } 1067 } 1068 1069 /* 1070 * prism2sta_inf_hostscanresults 1071 * 1072 * Handles the receipt of a Scan Results info frame. 1073 * 1074 * Arguments: 1075 * wlandev wlan device structure 1076 * inf ptr to info frame (contents in hfa384x order) 1077 * 1078 * Returns: 1079 * nothing 1080 * 1081 * Side effects: 1082 * 1083 * Call context: 1084 * interrupt 1085 */ 1086 static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, 1087 struct hfa384x_inf_frame *inf) 1088 { 1089 struct hfa384x *hw = wlandev->priv; 1090 int nbss; 1091 1092 nbss = (inf->framelen - 3) / 32; 1093 pr_debug("Received %d hostscan results\n", nbss); 1094 1095 if (nbss > 32) 1096 nbss = 32; 1097 1098 kfree(hw->scanresults); 1099 1100 hw->scanresults = kmemdup(inf, sizeof(*inf), GFP_ATOMIC); 1101 1102 if (nbss == 0) 1103 nbss = -1; 1104 1105 /* Notify/wake the sleeping caller. */ 1106 hw->scanflag = nbss; 1107 wake_up_interruptible(&hw->cmdq); 1108 }; 1109 1110 /* 1111 * prism2sta_inf_chinforesults 1112 * 1113 * Handles the receipt of a Channel Info Results info frame. 1114 * 1115 * Arguments: 1116 * wlandev wlan device structure 1117 * inf ptr to info frame (contents in hfa384x order) 1118 * 1119 * Returns: 1120 * nothing 1121 * 1122 * Side effects: 1123 * 1124 * Call context: 1125 * interrupt 1126 */ 1127 static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, 1128 struct hfa384x_inf_frame *inf) 1129 { 1130 struct hfa384x *hw = wlandev->priv; 1131 unsigned int i, n; 1132 1133 hw->channel_info.results.scanchannels = 1134 inf->info.chinforesult.scanchannels; 1135 1136 for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { 1137 struct hfa384x_ch_info_result_sub *result; 1138 struct hfa384x_ch_info_result_sub *chinforesult; 1139 int chan; 1140 1141 if (!(hw->channel_info.results.scanchannels & (1 << i))) 1142 continue; 1143 1144 result = &inf->info.chinforesult.result[n]; 1145 chan = result->chid - 1; 1146 1147 if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) 1148 continue; 1149 1150 chinforesult = &hw->channel_info.results.result[chan]; 1151 chinforesult->chid = chan; 1152 chinforesult->anl = result->anl; 1153 chinforesult->pnl = result->pnl; 1154 chinforesult->active = result->active; 1155 1156 pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", 1157 chan + 1, 1158 (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) 1159 ? "signal" : "noise", 1160 chinforesult->anl, chinforesult->pnl, 1161 (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) 1162 ? 1 : 0); 1163 n++; 1164 } 1165 atomic_set(&hw->channel_info.done, 2); 1166 1167 hw->channel_info.count = n; 1168 } 1169 1170 void prism2sta_processing_defer(struct work_struct *data) 1171 { 1172 struct hfa384x *hw = container_of(data, struct hfa384x, link_bh); 1173 struct wlandevice *wlandev = hw->wlandev; 1174 struct hfa384x_bytestr32 ssid; 1175 int result; 1176 1177 /* First let's process the auth frames */ 1178 { 1179 struct sk_buff *skb; 1180 struct hfa384x_inf_frame *inf; 1181 1182 while ((skb = skb_dequeue(&hw->authq))) { 1183 inf = (struct hfa384x_inf_frame *)skb->data; 1184 prism2sta_inf_authreq_defer(wlandev, inf); 1185 } 1186 } 1187 1188 /* Now let's handle the linkstatus stuff */ 1189 if (hw->link_status == hw->link_status_new) 1190 return; 1191 1192 hw->link_status = hw->link_status_new; 1193 1194 switch (hw->link_status) { 1195 case HFA384x_LINK_NOTCONNECTED: 1196 /* I'm currently assuming that this is the initial link 1197 * state. It should only be possible immediately 1198 * following an Enable command. 1199 * Response: 1200 * Block Transmits, Ignore receives of data frames 1201 */ 1202 netif_carrier_off(wlandev->netdev); 1203 1204 netdev_info(wlandev->netdev, "linkstatus=NOTCONNECTED (unhandled)\n"); 1205 break; 1206 1207 case HFA384x_LINK_CONNECTED: 1208 /* This one indicates a successful scan/join/auth/assoc. 1209 * When we have the full MLME complement, this event will 1210 * signify successful completion of both mlme_authenticate 1211 * and mlme_associate. State management will get a little 1212 * ugly here. 1213 * Response: 1214 * Indicate authentication and/or association 1215 * Enable Transmits, Receives and pass up data frames 1216 */ 1217 1218 netif_carrier_on(wlandev->netdev); 1219 1220 /* If we are joining a specific AP, set our 1221 * state and reset retries 1222 */ 1223 if (hw->join_ap == 1) 1224 hw->join_ap = 2; 1225 hw->join_retries = 60; 1226 1227 /* Don't call this in monitor mode */ 1228 if (wlandev->netdev->type == ARPHRD_ETHER) { 1229 u16 portstatus; 1230 1231 netdev_info(wlandev->netdev, "linkstatus=CONNECTED\n"); 1232 1233 /* For non-usb devices, we can use the sync versions */ 1234 /* Collect the BSSID, and set state to allow tx */ 1235 1236 result = hfa384x_drvr_getconfig(hw, 1237 HFA384x_RID_CURRENTBSSID, 1238 wlandev->bssid, 1239 WLAN_BSSID_LEN); 1240 if (result) { 1241 pr_debug 1242 ("getconfig(0x%02x) failed, result = %d\n", 1243 HFA384x_RID_CURRENTBSSID, result); 1244 return; 1245 } 1246 1247 result = hfa384x_drvr_getconfig(hw, 1248 HFA384x_RID_CURRENTSSID, 1249 &ssid, sizeof(ssid)); 1250 if (result) { 1251 pr_debug 1252 ("getconfig(0x%02x) failed, result = %d\n", 1253 HFA384x_RID_CURRENTSSID, result); 1254 return; 1255 } 1256 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, 1257 (struct p80211pstrd *)&wlandev->ssid); 1258 1259 /* Collect the port status */ 1260 result = hfa384x_drvr_getconfig16(hw, 1261 HFA384x_RID_PORTSTATUS, 1262 &portstatus); 1263 if (result) { 1264 pr_debug 1265 ("getconfig(0x%02x) failed, result = %d\n", 1266 HFA384x_RID_PORTSTATUS, result); 1267 return; 1268 } 1269 wlandev->macmode = 1270 (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? 1271 WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; 1272 1273 /* signal back up to cfg80211 layer */ 1274 prism2_connect_result(wlandev, P80211ENUM_truth_false); 1275 1276 /* Get the ball rolling on the comms quality stuff */ 1277 prism2sta_commsqual_defer(&hw->commsqual_bh); 1278 } 1279 break; 1280 1281 case HFA384x_LINK_DISCONNECTED: 1282 /* This one indicates that our association is gone. We've 1283 * lost connection with the AP and/or been disassociated. 1284 * This indicates that the MAC has completely cleared it's 1285 * associated state. We * should send a deauth indication 1286 * (implying disassoc) up * to the MLME. 1287 * Response: 1288 * Indicate Deauthentication 1289 * Block Transmits, Ignore receives of data frames 1290 */ 1291 if (wlandev->netdev->type == ARPHRD_ETHER) 1292 netdev_info(wlandev->netdev, 1293 "linkstatus=DISCONNECTED (unhandled)\n"); 1294 wlandev->macmode = WLAN_MACMODE_NONE; 1295 1296 netif_carrier_off(wlandev->netdev); 1297 1298 /* signal back up to cfg80211 layer */ 1299 prism2_disconnected(wlandev); 1300 1301 break; 1302 1303 case HFA384x_LINK_AP_CHANGE: 1304 /* This one indicates that the MAC has decided to and 1305 * successfully completed a change to another AP. We 1306 * should probably implement a reassociation indication 1307 * in response to this one. I'm thinking that the 1308 * p80211 layer needs to be notified in case of 1309 * buffering/queueing issues. User mode also needs to be 1310 * notified so that any BSS dependent elements can be 1311 * updated. 1312 * associated state. We * should send a deauth indication 1313 * (implying disassoc) up * to the MLME. 1314 * Response: 1315 * Indicate Reassociation 1316 * Enable Transmits, Receives and pass up data frames 1317 */ 1318 netdev_info(wlandev->netdev, "linkstatus=AP_CHANGE\n"); 1319 1320 result = hfa384x_drvr_getconfig(hw, 1321 HFA384x_RID_CURRENTBSSID, 1322 wlandev->bssid, WLAN_BSSID_LEN); 1323 if (result) { 1324 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1325 HFA384x_RID_CURRENTBSSID, result); 1326 return; 1327 } 1328 1329 result = hfa384x_drvr_getconfig(hw, 1330 HFA384x_RID_CURRENTSSID, 1331 &ssid, sizeof(ssid)); 1332 if (result) { 1333 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1334 HFA384x_RID_CURRENTSSID, result); 1335 return; 1336 } 1337 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, 1338 (struct p80211pstrd *)&wlandev->ssid); 1339 1340 hw->link_status = HFA384x_LINK_CONNECTED; 1341 netif_carrier_on(wlandev->netdev); 1342 1343 /* signal back up to cfg80211 layer */ 1344 prism2_roamed(wlandev); 1345 1346 break; 1347 1348 case HFA384x_LINK_AP_OUTOFRANGE: 1349 /* This one indicates that the MAC has decided that the 1350 * AP is out of range, but hasn't found a better candidate 1351 * so the MAC maintains its "associated" state in case 1352 * we get back in range. We should block transmits and 1353 * receives in this state. Do we need an indication here? 1354 * Probably not since a polling user-mode element would 1355 * get this status from p2PortStatus(FD40). What about 1356 * p80211? 1357 * Response: 1358 * Block Transmits, Ignore receives of data frames 1359 */ 1360 netdev_info(wlandev->netdev, "linkstatus=AP_OUTOFRANGE (unhandled)\n"); 1361 1362 netif_carrier_off(wlandev->netdev); 1363 1364 break; 1365 1366 case HFA384x_LINK_AP_INRANGE: 1367 /* This one indicates that the MAC has decided that the 1368 * AP is back in range. We continue working with our 1369 * existing association. 1370 * Response: 1371 * Enable Transmits, Receives and pass up data frames 1372 */ 1373 netdev_info(wlandev->netdev, "linkstatus=AP_INRANGE\n"); 1374 1375 hw->link_status = HFA384x_LINK_CONNECTED; 1376 netif_carrier_on(wlandev->netdev); 1377 1378 break; 1379 1380 case HFA384x_LINK_ASSOCFAIL: 1381 /* This one is actually a peer to CONNECTED. We've 1382 * requested a join for a given SSID and optionally BSSID. 1383 * We can use this one to indicate authentication and 1384 * association failures. The trick is going to be 1385 * 1) identifying the failure, and 2) state management. 1386 * Response: 1387 * Disable Transmits, Ignore receives of data frames 1388 */ 1389 if (hw->join_ap && --hw->join_retries > 0) { 1390 struct hfa384x_join_request_data joinreq; 1391 1392 joinreq = hw->joinreq; 1393 /* Send the join request */ 1394 hfa384x_drvr_setconfig(hw, 1395 HFA384x_RID_JOINREQUEST, 1396 &joinreq, 1397 HFA384x_RID_JOINREQUEST_LEN); 1398 netdev_info(wlandev->netdev, 1399 "linkstatus=ASSOCFAIL (re-submitting join)\n"); 1400 } else { 1401 netdev_info(wlandev->netdev, "linkstatus=ASSOCFAIL (unhandled)\n"); 1402 } 1403 1404 netif_carrier_off(wlandev->netdev); 1405 1406 /* signal back up to cfg80211 layer */ 1407 prism2_connect_result(wlandev, P80211ENUM_truth_true); 1408 1409 break; 1410 1411 default: 1412 /* This is bad, IO port problems? */ 1413 netdev_warn(wlandev->netdev, 1414 "unknown linkstatus=0x%02x\n", hw->link_status); 1415 return; 1416 } 1417 1418 wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); 1419 } 1420 1421 /* 1422 * prism2sta_inf_linkstatus 1423 * 1424 * Handles the receipt of a Link Status info frame. 1425 * 1426 * Arguments: 1427 * wlandev wlan device structure 1428 * inf ptr to info frame (contents in hfa384x order) 1429 * 1430 * Returns: 1431 * nothing 1432 * 1433 * Side effects: 1434 * 1435 * Call context: 1436 * interrupt 1437 */ 1438 static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, 1439 struct hfa384x_inf_frame *inf) 1440 { 1441 struct hfa384x *hw = wlandev->priv; 1442 1443 hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); 1444 1445 schedule_work(&hw->link_bh); 1446 } 1447 1448 /* 1449 * prism2sta_inf_assocstatus 1450 * 1451 * Handles the receipt of an Association Status info frame. Should 1452 * be present in APs only. 1453 * 1454 * Arguments: 1455 * wlandev wlan device structure 1456 * inf ptr to info frame (contents in hfa384x order) 1457 * 1458 * Returns: 1459 * nothing 1460 * 1461 * Side effects: 1462 * 1463 * Call context: 1464 * interrupt 1465 */ 1466 static void prism2sta_inf_assocstatus(struct wlandevice *wlandev, 1467 struct hfa384x_inf_frame *inf) 1468 { 1469 struct hfa384x *hw = wlandev->priv; 1470 struct hfa384x_assoc_status rec; 1471 int i; 1472 1473 memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); 1474 le16_to_cpus(&rec.assocstatus); 1475 le16_to_cpus(&rec.reason); 1476 1477 /* 1478 * Find the address in the list of authenticated stations. 1479 * If it wasn't found, then this address has not been previously 1480 * authenticated and something weird has happened if this is 1481 * anything other than an "authentication failed" message. 1482 * If the address was found, then set the "associated" flag for 1483 * that station, based on whether the station is associating or 1484 * losing its association. Something weird has also happened 1485 * if we find the address in the list of authenticated stations 1486 * but we are getting an "authentication failed" message. 1487 */ 1488 1489 for (i = 0; i < hw->authlist.cnt; i++) 1490 if (ether_addr_equal(rec.sta_addr, hw->authlist.addr[i])) 1491 break; 1492 1493 if (i >= hw->authlist.cnt) { 1494 if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) 1495 netdev_warn(wlandev->netdev, 1496 "assocstatus info frame received for non-authenticated station.\n"); 1497 } else { 1498 hw->authlist.assoc[i] = 1499 (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || 1500 rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); 1501 1502 if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) 1503 netdev_warn(wlandev->netdev, 1504 "authfail assocstatus info frame received for authenticated station.\n"); 1505 } 1506 } 1507 1508 /* 1509 * prism2sta_inf_authreq 1510 * 1511 * Handles the receipt of an Authentication Request info frame. Should 1512 * be present in APs only. 1513 * 1514 * Arguments: 1515 * wlandev wlan device structure 1516 * inf ptr to info frame (contents in hfa384x order) 1517 * 1518 * Returns: 1519 * nothing 1520 * 1521 * Side effects: 1522 * 1523 * Call context: 1524 * interrupt 1525 * 1526 */ 1527 static void prism2sta_inf_authreq(struct wlandevice *wlandev, 1528 struct hfa384x_inf_frame *inf) 1529 { 1530 struct hfa384x *hw = wlandev->priv; 1531 struct sk_buff *skb; 1532 1533 skb = dev_alloc_skb(sizeof(*inf)); 1534 if (skb) { 1535 skb_put(skb, sizeof(*inf)); 1536 memcpy(skb->data, inf, sizeof(*inf)); 1537 skb_queue_tail(&hw->authq, skb); 1538 schedule_work(&hw->link_bh); 1539 } 1540 } 1541 1542 static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, 1543 struct hfa384x_inf_frame *inf) 1544 { 1545 struct hfa384x *hw = wlandev->priv; 1546 struct hfa384x_authenticate_station_data rec; 1547 1548 int i, added, result, cnt; 1549 u8 *addr; 1550 1551 /* 1552 * Build the AuthenticateStation record. Initialize it for denying 1553 * authentication. 1554 */ 1555 1556 ether_addr_copy(rec.address, inf->info.authreq.sta_addr); 1557 rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); 1558 1559 /* 1560 * Authenticate based on the access mode. 1561 */ 1562 1563 switch (hw->accessmode) { 1564 case WLAN_ACCESS_NONE: 1565 1566 /* 1567 * Deny all new authentications. However, if a station 1568 * is ALREADY authenticated, then accept it. 1569 */ 1570 1571 for (i = 0; i < hw->authlist.cnt; i++) 1572 if (ether_addr_equal(rec.address, 1573 hw->authlist.addr[i])) { 1574 rec.status = cpu_to_le16(P80211ENUM_status_successful); 1575 break; 1576 } 1577 1578 break; 1579 1580 case WLAN_ACCESS_ALL: 1581 1582 /* 1583 * Allow all authentications. 1584 */ 1585 1586 rec.status = cpu_to_le16(P80211ENUM_status_successful); 1587 break; 1588 1589 case WLAN_ACCESS_ALLOW: 1590 1591 /* 1592 * Only allow the authentication if the MAC address 1593 * is in the list of allowed addresses. 1594 * 1595 * Since this is the interrupt handler, we may be here 1596 * while the access list is in the middle of being 1597 * updated. Choose the list which is currently okay. 1598 * See "prism2mib_priv_accessallow()" for details. 1599 */ 1600 1601 if (hw->allow.modify == 0) { 1602 cnt = hw->allow.cnt; 1603 addr = hw->allow.addr[0]; 1604 } else { 1605 cnt = hw->allow.cnt1; 1606 addr = hw->allow.addr1[0]; 1607 } 1608 1609 for (i = 0; i < cnt; i++, addr += ETH_ALEN) 1610 if (ether_addr_equal(rec.address, addr)) { 1611 rec.status = cpu_to_le16(P80211ENUM_status_successful); 1612 break; 1613 } 1614 1615 break; 1616 1617 case WLAN_ACCESS_DENY: 1618 1619 /* 1620 * Allow the authentication UNLESS the MAC address is 1621 * in the list of denied addresses. 1622 * 1623 * Since this is the interrupt handler, we may be here 1624 * while the access list is in the middle of being 1625 * updated. Choose the list which is currently okay. 1626 * See "prism2mib_priv_accessdeny()" for details. 1627 */ 1628 1629 if (hw->deny.modify == 0) { 1630 cnt = hw->deny.cnt; 1631 addr = hw->deny.addr[0]; 1632 } else { 1633 cnt = hw->deny.cnt1; 1634 addr = hw->deny.addr1[0]; 1635 } 1636 1637 rec.status = cpu_to_le16(P80211ENUM_status_successful); 1638 1639 for (i = 0; i < cnt; i++, addr += ETH_ALEN) 1640 if (ether_addr_equal(rec.address, addr)) { 1641 rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); 1642 break; 1643 } 1644 1645 break; 1646 } 1647 1648 /* 1649 * If the authentication is okay, then add the MAC address to the 1650 * list of authenticated stations. Don't add the address if it 1651 * is already in the list. (802.11b does not seem to disallow 1652 * a station from issuing an authentication request when the 1653 * station is already authenticated. Does this sort of thing 1654 * ever happen? We might as well do the check just in case.) 1655 */ 1656 1657 added = 0; 1658 1659 if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) { 1660 for (i = 0; i < hw->authlist.cnt; i++) 1661 if (ether_addr_equal(rec.address, 1662 hw->authlist.addr[i])) 1663 break; 1664 1665 if (i >= hw->authlist.cnt) { 1666 if (hw->authlist.cnt >= WLAN_AUTH_MAX) { 1667 rec.status = cpu_to_le16(P80211ENUM_status_ap_full); 1668 } else { 1669 ether_addr_copy(hw->authlist.addr[hw->authlist.cnt], 1670 rec.address); 1671 hw->authlist.cnt++; 1672 added = 1; 1673 } 1674 } 1675 } 1676 1677 /* 1678 * Send back the results of the authentication. If this doesn't work, 1679 * then make sure to remove the address from the authenticated list if 1680 * it was added. 1681 */ 1682 1683 rec.algorithm = inf->info.authreq.algorithm; 1684 1685 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, 1686 &rec, sizeof(rec)); 1687 if (result) { 1688 if (added) 1689 hw->authlist.cnt--; 1690 netdev_err(wlandev->netdev, 1691 "setconfig(authenticatestation) failed, result=%d\n", 1692 result); 1693 } 1694 } 1695 1696 /* 1697 * prism2sta_inf_psusercnt 1698 * 1699 * Handles the receipt of a PowerSaveUserCount info frame. Should 1700 * be present in APs only. 1701 * 1702 * Arguments: 1703 * wlandev wlan device structure 1704 * inf ptr to info frame (contents in hfa384x order) 1705 * 1706 * Returns: 1707 * nothing 1708 * 1709 * Side effects: 1710 * 1711 * Call context: 1712 * interrupt 1713 */ 1714 static void prism2sta_inf_psusercnt(struct wlandevice *wlandev, 1715 struct hfa384x_inf_frame *inf) 1716 { 1717 struct hfa384x *hw = wlandev->priv; 1718 1719 hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt); 1720 } 1721 1722 /* 1723 * prism2sta_ev_info 1724 * 1725 * Handles the Info event. 1726 * 1727 * Arguments: 1728 * wlandev wlan device structure 1729 * inf ptr to a generic info frame 1730 * 1731 * Returns: 1732 * nothing 1733 * 1734 * Side effects: 1735 * 1736 * Call context: 1737 * interrupt 1738 */ 1739 void prism2sta_ev_info(struct wlandevice *wlandev, 1740 struct hfa384x_inf_frame *inf) 1741 { 1742 le16_to_cpus(&inf->infotype); 1743 /* Dispatch */ 1744 switch (inf->infotype) { 1745 case HFA384x_IT_HANDOVERADDR: 1746 prism2sta_inf_handover(wlandev, inf); 1747 break; 1748 case HFA384x_IT_COMMTALLIES: 1749 prism2sta_inf_tallies(wlandev, inf); 1750 break; 1751 case HFA384x_IT_HOSTSCANRESULTS: 1752 prism2sta_inf_hostscanresults(wlandev, inf); 1753 break; 1754 case HFA384x_IT_SCANRESULTS: 1755 prism2sta_inf_scanresults(wlandev, inf); 1756 break; 1757 case HFA384x_IT_CHINFORESULTS: 1758 prism2sta_inf_chinforesults(wlandev, inf); 1759 break; 1760 case HFA384x_IT_LINKSTATUS: 1761 prism2sta_inf_linkstatus(wlandev, inf); 1762 break; 1763 case HFA384x_IT_ASSOCSTATUS: 1764 prism2sta_inf_assocstatus(wlandev, inf); 1765 break; 1766 case HFA384x_IT_AUTHREQ: 1767 prism2sta_inf_authreq(wlandev, inf); 1768 break; 1769 case HFA384x_IT_PSUSERCNT: 1770 prism2sta_inf_psusercnt(wlandev, inf); 1771 break; 1772 case HFA384x_IT_KEYIDCHANGED: 1773 netdev_warn(wlandev->netdev, "Unhandled IT_KEYIDCHANGED\n"); 1774 break; 1775 case HFA384x_IT_ASSOCREQ: 1776 netdev_warn(wlandev->netdev, "Unhandled IT_ASSOCREQ\n"); 1777 break; 1778 case HFA384x_IT_MICFAILURE: 1779 netdev_warn(wlandev->netdev, "Unhandled IT_MICFAILURE\n"); 1780 break; 1781 default: 1782 netdev_warn(wlandev->netdev, 1783 "Unknown info type=0x%02x\n", inf->infotype); 1784 break; 1785 } 1786 } 1787 1788 /* 1789 * prism2sta_ev_txexc 1790 * 1791 * Handles the TxExc event. A Transmit Exception event indicates 1792 * that the MAC's TX process was unsuccessful - so the packet did 1793 * not get transmitted. 1794 * 1795 * Arguments: 1796 * wlandev wlan device structure 1797 * status tx frame status word 1798 * 1799 * Returns: 1800 * nothing 1801 * 1802 * Side effects: 1803 * 1804 * Call context: 1805 * interrupt 1806 */ 1807 void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status) 1808 { 1809 pr_debug("TxExc status=0x%x.\n", status); 1810 } 1811 1812 /* 1813 * prism2sta_ev_tx 1814 * 1815 * Handles the Tx event. 1816 * 1817 * Arguments: 1818 * wlandev wlan device structure 1819 * status tx frame status word 1820 * Returns: 1821 * nothing 1822 * 1823 * Side effects: 1824 * 1825 * Call context: 1826 * interrupt 1827 */ 1828 void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status) 1829 { 1830 pr_debug("Tx Complete, status=0x%04x\n", status); 1831 /* update linux network stats */ 1832 wlandev->netdev->stats.tx_packets++; 1833 } 1834 1835 /* 1836 * prism2sta_ev_alloc 1837 * 1838 * Handles the Alloc event. 1839 * 1840 * Arguments: 1841 * wlandev wlan device structure 1842 * 1843 * Returns: 1844 * nothing 1845 * 1846 * Side effects: 1847 * 1848 * Call context: 1849 * interrupt 1850 */ 1851 void prism2sta_ev_alloc(struct wlandevice *wlandev) 1852 { 1853 netif_wake_queue(wlandev->netdev); 1854 } 1855 1856 /* 1857 * create_wlan 1858 * 1859 * Called at module init time. This creates the struct wlandevice structure 1860 * and initializes it with relevant bits. 1861 * 1862 * Arguments: 1863 * none 1864 * 1865 * Returns: 1866 * the created struct wlandevice structure. 1867 * 1868 * Side effects: 1869 * also allocates the priv/hw structures. 1870 * 1871 * Call context: 1872 * process thread 1873 * 1874 */ 1875 static struct wlandevice *create_wlan(void) 1876 { 1877 struct wlandevice *wlandev = NULL; 1878 struct hfa384x *hw = NULL; 1879 1880 /* Alloc our structures */ 1881 wlandev = kzalloc(sizeof(*wlandev), GFP_KERNEL); 1882 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 1883 1884 if (!wlandev || !hw) { 1885 kfree(wlandev); 1886 kfree(hw); 1887 return NULL; 1888 } 1889 1890 /* Initialize the network device object. */ 1891 wlandev->nsdname = dev_info; 1892 wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; 1893 wlandev->priv = hw; 1894 wlandev->open = prism2sta_open; 1895 wlandev->close = prism2sta_close; 1896 wlandev->reset = prism2sta_reset; 1897 wlandev->txframe = prism2sta_txframe; 1898 wlandev->mlmerequest = prism2sta_mlmerequest; 1899 wlandev->set_multicast_list = prism2sta_setmulticast; 1900 wlandev->tx_timeout = hfa384x_tx_timeout; 1901 1902 wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN; 1903 1904 /* Initialize the device private data structure. */ 1905 hw->dot11_desired_bss_type = 1; 1906 1907 return wlandev; 1908 } 1909 1910 void prism2sta_commsqual_defer(struct work_struct *data) 1911 { 1912 struct hfa384x *hw = container_of(data, struct hfa384x, commsqual_bh); 1913 struct wlandevice *wlandev = hw->wlandev; 1914 struct hfa384x_bytestr32 ssid; 1915 struct p80211msg_dot11req_mibget msg; 1916 struct p80211item_uint32 *mibitem = (struct p80211item_uint32 *) 1917 &msg.mibattribute.data; 1918 int result = 0; 1919 1920 if (hw->wlandev->hwremoved) 1921 return; 1922 1923 /* we don't care if we're in AP mode */ 1924 if ((wlandev->macmode == WLAN_MACMODE_NONE) || 1925 (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { 1926 return; 1927 } 1928 1929 /* It only makes sense to poll these in non-IBSS */ 1930 if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { 1931 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY, 1932 &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN); 1933 1934 if (result) { 1935 netdev_err(wlandev->netdev, "error fetching commsqual\n"); 1936 return; 1937 } 1938 1939 pr_debug("commsqual %d %d %d\n", 1940 le16_to_cpu(hw->qual.cq_curr_bss), 1941 le16_to_cpu(hw->qual.asl_curr_bss), 1942 le16_to_cpu(hw->qual.anl_curr_fc)); 1943 } 1944 1945 /* Get the signal rate */ 1946 msg.msgcode = DIDMSG_DOT11REQ_MIBGET; 1947 mibitem->did = DIDMIB_P2_MAC_CURRENTTXRATE; 1948 result = p80211req_dorequest(wlandev, (u8 *)&msg); 1949 1950 if (result) { 1951 pr_debug("get signal rate failed, result = %d\n", 1952 result); 1953 return; 1954 } 1955 1956 switch (mibitem->data) { 1957 case HFA384x_RATEBIT_1: 1958 hw->txrate = 10; 1959 break; 1960 case HFA384x_RATEBIT_2: 1961 hw->txrate = 20; 1962 break; 1963 case HFA384x_RATEBIT_5dot5: 1964 hw->txrate = 55; 1965 break; 1966 case HFA384x_RATEBIT_11: 1967 hw->txrate = 110; 1968 break; 1969 default: 1970 pr_debug("Bad ratebit (%d)\n", mibitem->data); 1971 } 1972 1973 /* Lastly, we need to make sure the BSSID didn't change on us */ 1974 result = hfa384x_drvr_getconfig(hw, 1975 HFA384x_RID_CURRENTBSSID, 1976 wlandev->bssid, WLAN_BSSID_LEN); 1977 if (result) { 1978 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1979 HFA384x_RID_CURRENTBSSID, result); 1980 return; 1981 } 1982 1983 result = hfa384x_drvr_getconfig(hw, 1984 HFA384x_RID_CURRENTSSID, 1985 &ssid, sizeof(ssid)); 1986 if (result) { 1987 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1988 HFA384x_RID_CURRENTSSID, result); 1989 return; 1990 } 1991 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, 1992 (struct p80211pstrd *)&wlandev->ssid); 1993 1994 /* Reschedule timer */ 1995 mod_timer(&hw->commsqual_timer, jiffies + HZ); 1996 } 1997 1998 void prism2sta_commsqual_timer(struct timer_list *t) 1999 { 2000 struct hfa384x *hw = from_timer(hw, t, commsqual_timer); 2001 2002 schedule_work(&hw->commsqual_bh); 2003 } 2004