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