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/moduleparam.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 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* Not currently implented. 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 int result; 247 248 /* If necessary, set the 802.11 WEP bit */ 249 if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == 250 HOSTWEP_PRIVACYINVOKED) { 251 p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); 252 } 253 254 result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep); 255 256 return result; 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----------------------------------------------------------------*/ 283static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg) 284{ 285 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 286 287 int result = 0; 288 289 switch (msg->msgcode) { 290 case DIDmsg_dot11req_mibget: 291 pr_debug("Received mibget request\n"); 292 result = prism2mgmt_mibset_mibget(wlandev, msg); 293 break; 294 case DIDmsg_dot11req_mibset: 295 pr_debug("Received mibset request\n"); 296 result = prism2mgmt_mibset_mibget(wlandev, msg); 297 break; 298 case DIDmsg_dot11req_scan: 299 pr_debug("Received scan request\n"); 300 result = prism2mgmt_scan(wlandev, msg); 301 break; 302 case DIDmsg_dot11req_scan_results: 303 pr_debug("Received scan_results request\n"); 304 result = prism2mgmt_scan_results(wlandev, msg); 305 break; 306 case DIDmsg_dot11req_start: 307 pr_debug("Received mlme start request\n"); 308 result = prism2mgmt_start(wlandev, msg); 309 break; 310 /* 311 * Prism2 specific messages 312 */ 313 case DIDmsg_p2req_readpda: 314 pr_debug("Received mlme readpda request\n"); 315 result = prism2mgmt_readpda(wlandev, msg); 316 break; 317 case DIDmsg_p2req_ramdl_state: 318 pr_debug("Received mlme ramdl_state request\n"); 319 result = prism2mgmt_ramdl_state(wlandev, msg); 320 break; 321 case DIDmsg_p2req_ramdl_write: 322 pr_debug("Received mlme ramdl_write request\n"); 323 result = prism2mgmt_ramdl_write(wlandev, msg); 324 break; 325 case DIDmsg_p2req_flashdl_state: 326 pr_debug("Received mlme flashdl_state request\n"); 327 result = prism2mgmt_flashdl_state(wlandev, msg); 328 break; 329 case DIDmsg_p2req_flashdl_write: 330 pr_debug("Received mlme flashdl_write request\n"); 331 result = prism2mgmt_flashdl_write(wlandev, msg); 332 break; 333 /* 334 * Linux specific messages 335 */ 336 case DIDmsg_lnxreq_hostwep: 337 break; /* ignore me. */ 338 case DIDmsg_lnxreq_ifstate: 339 { 340 struct p80211msg_lnxreq_ifstate *ifstatemsg; 341 342 pr_debug("Received mlme ifstate request\n"); 343 ifstatemsg = (struct p80211msg_lnxreq_ifstate *) msg; 344 result = 345 prism2sta_ifstate(wlandev, 346 ifstatemsg->ifstate.data); 347 ifstatemsg->resultcode.status = 348 P80211ENUM_msgitem_status_data_ok; 349 ifstatemsg->resultcode.data = result; 350 result = 0; 351 } 352 break; 353 case DIDmsg_lnxreq_wlansniff: 354 pr_debug("Received mlme wlansniff request\n"); 355 result = prism2mgmt_wlansniff(wlandev, msg); 356 break; 357 case DIDmsg_lnxreq_autojoin: 358 pr_debug("Received mlme autojoin request\n"); 359 result = prism2mgmt_autojoin(wlandev, msg); 360 break; 361 case DIDmsg_lnxreq_commsquality:{ 362 struct p80211msg_lnxreq_commsquality *qualmsg; 363 364 pr_debug("Received commsquality request\n"); 365 366 qualmsg = (struct p80211msg_lnxreq_commsquality *) msg; 367 368 qualmsg->link.status = 369 P80211ENUM_msgitem_status_data_ok; 370 qualmsg->level.status = 371 P80211ENUM_msgitem_status_data_ok; 372 qualmsg->noise.status = 373 P80211ENUM_msgitem_status_data_ok; 374 375 qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS); 376 qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS); 377 qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC); 378 qualmsg->txrate.data = hw->txrate; 379 380 break; 381 } 382 default: 383 netdev_warn(wlandev->netdev, 384 "Unknown mgmt request message 0x%08x", 385 msg->msgcode); 386 break; 387 } 388 389 return result; 390} 391 392/*---------------------------------------------------------------- 393* prism2sta_ifstate 394* 395* Interface state. This is the primary WLAN interface enable/disable 396* handler. Following the driver/load/deviceprobe sequence, this 397* function must be called with a state of "enable" before any other 398* commands will be accepted. 399* 400* Arguments: 401* wlandev wlan device structure 402* msgp ptr to msg buffer 403* 404* Returns: 405* A p80211 message resultcode value. 406* 407* Side effects: 408* 409* Call context: 410* process thread (usually) 411* interrupt 412----------------------------------------------------------------*/ 413u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) 414{ 415 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 416 u32 result; 417 418 result = P80211ENUM_resultcode_implementation_failure; 419 420 pr_debug("Current MSD state(%d), requesting(%d)\n", 421 wlandev->msdstate, ifstate); 422 switch (ifstate) { 423 case P80211ENUM_ifstate_fwload: 424 switch (wlandev->msdstate) { 425 case WLAN_MSD_HWPRESENT: 426 wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING; 427 /* 428 * Initialize the device+driver sufficiently 429 * for firmware loading. 430 */ 431 result = hfa384x_drvr_start(hw); 432 if (result) { 433 netdev_err(wlandev->netdev, 434 "hfa384x_drvr_start() failed,result=%d\n", (int)result); 435 result = 436 P80211ENUM_resultcode_implementation_failure; 437 wlandev->msdstate = WLAN_MSD_HWPRESENT; 438 break; 439 } 440 wlandev->msdstate = WLAN_MSD_FWLOAD; 441 result = P80211ENUM_resultcode_success; 442 break; 443 case WLAN_MSD_FWLOAD: 444 hfa384x_cmd_initialize(hw); 445 result = P80211ENUM_resultcode_success; 446 break; 447 case WLAN_MSD_RUNNING: 448 netdev_warn(wlandev->netdev, 449 "Cannot enter fwload state from enable state, you must disable first.\n"); 450 result = P80211ENUM_resultcode_invalid_parameters; 451 break; 452 case WLAN_MSD_HWFAIL: 453 default: 454 /* probe() had a problem or the msdstate contains 455 * an unrecognized value, there's nothing we can do. 456 */ 457 result = P80211ENUM_resultcode_implementation_failure; 458 break; 459 } 460 break; 461 case P80211ENUM_ifstate_enable: 462 switch (wlandev->msdstate) { 463 case WLAN_MSD_HWPRESENT: 464 case WLAN_MSD_FWLOAD: 465 wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; 466 /* Initialize the device+driver for full 467 * operation. Note that this might me an FWLOAD to 468 * to RUNNING transition so we must not do a chip 469 * or board level reset. Note that on failure, 470 * the MSD state is set to HWPRESENT because we 471 * can't make any assumptions about the state 472 * of the hardware or a previous firmware load. 473 */ 474 result = hfa384x_drvr_start(hw); 475 if (result) { 476 netdev_err(wlandev->netdev, 477 "hfa384x_drvr_start() failed,result=%d\n", (int)result); 478 result = 479 P80211ENUM_resultcode_implementation_failure; 480 wlandev->msdstate = WLAN_MSD_HWPRESENT; 481 break; 482 } 483 484 result = prism2sta_getcardinfo(wlandev); 485 if (result) { 486 netdev_err(wlandev->netdev, 487 "prism2sta_getcardinfo() failed,result=%d\n", (int)result); 488 result = 489 P80211ENUM_resultcode_implementation_failure; 490 hfa384x_drvr_stop(hw); 491 wlandev->msdstate = WLAN_MSD_HWPRESENT; 492 break; 493 } 494 result = prism2sta_globalsetup(wlandev); 495 if (result) { 496 netdev_err(wlandev->netdev, 497 "prism2sta_globalsetup() failed,result=%d\n", (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----------------------------------------------------------------*/ 582static int prism2sta_getcardinfo(wlandevice_t *wlandev) 583{ 584 int result = 0; 585 hfa384x_t *hw = (hfa384x_t *) 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(hfa384x_compident_t)); 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 hw->ident_nic.id = le16_to_cpu(hw->ident_nic.id); 602 hw->ident_nic.variant = le16_to_cpu(hw->ident_nic.variant); 603 hw->ident_nic.major = le16_to_cpu(hw->ident_nic.major); 604 hw->ident_nic.minor = le16_to_cpu(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(hfa384x_compident_t)); 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 hw->ident_pri_fw.id = le16_to_cpu(hw->ident_pri_fw.id); 621 hw->ident_pri_fw.variant = le16_to_cpu(hw->ident_pri_fw.variant); 622 hw->ident_pri_fw.major = le16_to_cpu(hw->ident_pri_fw.major); 623 hw->ident_pri_fw.minor = le16_to_cpu(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(hfa384x_compident_t)); 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 hw->ident_sta_fw.id = le16_to_cpu(hw->ident_sta_fw.id); 647 hw->ident_sta_fw.variant = le16_to_cpu(hw->ident_sta_fw.variant); 648 hw->ident_sta_fw.major = le16_to_cpu(hw->ident_sta_fw.major); 649 hw->ident_sta_fw.minor = le16_to_cpu(hw->ident_sta_fw.minor); 650 651 /* strip out the 'special' variant bits */ 652 hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15)); 653 hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15))); 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 firmeare 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(hfa384x_caplevel_t)); 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 hw->cap_sup_mfi.role = le16_to_cpu(hw->cap_sup_mfi.role); 681 hw->cap_sup_mfi.id = le16_to_cpu(hw->cap_sup_mfi.id); 682 hw->cap_sup_mfi.variant = le16_to_cpu(hw->cap_sup_mfi.variant); 683 hw->cap_sup_mfi.bottom = le16_to_cpu(hw->cap_sup_mfi.bottom); 684 hw->cap_sup_mfi.top = le16_to_cpu(hw->cap_sup_mfi.top); 685 686 netdev_info(wlandev->netdev, 687 "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 688 hw->cap_sup_mfi.role, hw->cap_sup_mfi.id, 689 hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom, 690 hw->cap_sup_mfi.top); 691 692 /* Compatibility range, Controller supplier */ 693 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE, 694 &hw->cap_sup_cfi, 695 sizeof(hfa384x_caplevel_t)); 696 if (result) { 697 netdev_err(wlandev->netdev, "Failed to retrieve CFISUPRANGE\n"); 698 goto failed; 699 } 700 701 /* get all the Compatibility range, controller interface supplier 702 fields in byte order */ 703 hw->cap_sup_cfi.role = le16_to_cpu(hw->cap_sup_cfi.role); 704 hw->cap_sup_cfi.id = le16_to_cpu(hw->cap_sup_cfi.id); 705 hw->cap_sup_cfi.variant = le16_to_cpu(hw->cap_sup_cfi.variant); 706 hw->cap_sup_cfi.bottom = le16_to_cpu(hw->cap_sup_cfi.bottom); 707 hw->cap_sup_cfi.top = le16_to_cpu(hw->cap_sup_cfi.top); 708 709 netdev_info(wlandev->netdev, 710 "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 711 hw->cap_sup_cfi.role, hw->cap_sup_cfi.id, 712 hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom, 713 hw->cap_sup_cfi.top); 714 715 /* Compatibility range, Primary f/w supplier */ 716 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE, 717 &hw->cap_sup_pri, 718 sizeof(hfa384x_caplevel_t)); 719 if (result) { 720 netdev_err(wlandev->netdev, "Failed to retrieve PRISUPRANGE\n"); 721 goto failed; 722 } 723 724 /* get all the Compatibility range, primary firmware supplier 725 fields in byte order */ 726 hw->cap_sup_pri.role = le16_to_cpu(hw->cap_sup_pri.role); 727 hw->cap_sup_pri.id = le16_to_cpu(hw->cap_sup_pri.id); 728 hw->cap_sup_pri.variant = le16_to_cpu(hw->cap_sup_pri.variant); 729 hw->cap_sup_pri.bottom = le16_to_cpu(hw->cap_sup_pri.bottom); 730 hw->cap_sup_pri.top = le16_to_cpu(hw->cap_sup_pri.top); 731 732 netdev_info(wlandev->netdev, 733 "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 734 hw->cap_sup_pri.role, hw->cap_sup_pri.id, 735 hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom, 736 hw->cap_sup_pri.top); 737 738 /* Compatibility range, Station f/w supplier */ 739 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE, 740 &hw->cap_sup_sta, 741 sizeof(hfa384x_caplevel_t)); 742 if (result) { 743 netdev_err(wlandev->netdev, "Failed to retrieve STASUPRANGE\n"); 744 goto failed; 745 } 746 747 /* get all the Compatibility range, station firmware supplier 748 fields in byte order */ 749 hw->cap_sup_sta.role = le16_to_cpu(hw->cap_sup_sta.role); 750 hw->cap_sup_sta.id = le16_to_cpu(hw->cap_sup_sta.id); 751 hw->cap_sup_sta.variant = le16_to_cpu(hw->cap_sup_sta.variant); 752 hw->cap_sup_sta.bottom = le16_to_cpu(hw->cap_sup_sta.bottom); 753 hw->cap_sup_sta.top = le16_to_cpu(hw->cap_sup_sta.top); 754 755 if (hw->cap_sup_sta.id == 0x04) { 756 netdev_info(wlandev->netdev, 757 "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 758 hw->cap_sup_sta.role, hw->cap_sup_sta.id, 759 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, 760 hw->cap_sup_sta.top); 761 } else { 762 netdev_info(wlandev->netdev, 763 "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 764 hw->cap_sup_sta.role, hw->cap_sup_sta.id, 765 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, 766 hw->cap_sup_sta.top); 767 } 768 769 /* Compatibility range, primary f/w actor, CFI supplier */ 770 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES, 771 &hw->cap_act_pri_cfi, 772 sizeof(hfa384x_caplevel_t)); 773 if (result) { 774 netdev_err(wlandev->netdev, "Failed to retrieve PRI_CFIACTRANGES\n"); 775 goto failed; 776 } 777 778 /* get all the Compatibility range, primary f/w actor, CFI supplier 779 fields in byte order */ 780 hw->cap_act_pri_cfi.role = le16_to_cpu(hw->cap_act_pri_cfi.role); 781 hw->cap_act_pri_cfi.id = le16_to_cpu(hw->cap_act_pri_cfi.id); 782 hw->cap_act_pri_cfi.variant = le16_to_cpu(hw->cap_act_pri_cfi.variant); 783 hw->cap_act_pri_cfi.bottom = le16_to_cpu(hw->cap_act_pri_cfi.bottom); 784 hw->cap_act_pri_cfi.top = le16_to_cpu(hw->cap_act_pri_cfi.top); 785 786 netdev_info(wlandev->netdev, 787 "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 788 hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id, 789 hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom, 790 hw->cap_act_pri_cfi.top); 791 792 /* Compatibility range, sta f/w actor, CFI supplier */ 793 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES, 794 &hw->cap_act_sta_cfi, 795 sizeof(hfa384x_caplevel_t)); 796 if (result) { 797 netdev_err(wlandev->netdev, "Failed to retrieve STA_CFIACTRANGES\n"); 798 goto failed; 799 } 800 801 /* get all the Compatibility range, station f/w actor, CFI supplier 802 fields in byte order */ 803 hw->cap_act_sta_cfi.role = le16_to_cpu(hw->cap_act_sta_cfi.role); 804 hw->cap_act_sta_cfi.id = le16_to_cpu(hw->cap_act_sta_cfi.id); 805 hw->cap_act_sta_cfi.variant = le16_to_cpu(hw->cap_act_sta_cfi.variant); 806 hw->cap_act_sta_cfi.bottom = le16_to_cpu(hw->cap_act_sta_cfi.bottom); 807 hw->cap_act_sta_cfi.top = le16_to_cpu(hw->cap_act_sta_cfi.top); 808 809 netdev_info(wlandev->netdev, 810 "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 811 hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id, 812 hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom, 813 hw->cap_act_sta_cfi.top); 814 815 /* Compatibility range, sta f/w actor, MFI supplier */ 816 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES, 817 &hw->cap_act_sta_mfi, 818 sizeof(hfa384x_caplevel_t)); 819 if (result) { 820 netdev_err(wlandev->netdev, "Failed to retrieve STA_MFIACTRANGES\n"); 821 goto failed; 822 } 823 824 /* get all the Compatibility range, station f/w actor, MFI supplier 825 fields in byte order */ 826 hw->cap_act_sta_mfi.role = le16_to_cpu(hw->cap_act_sta_mfi.role); 827 hw->cap_act_sta_mfi.id = le16_to_cpu(hw->cap_act_sta_mfi.id); 828 hw->cap_act_sta_mfi.variant = le16_to_cpu(hw->cap_act_sta_mfi.variant); 829 hw->cap_act_sta_mfi.bottom = le16_to_cpu(hw->cap_act_sta_mfi.bottom); 830 hw->cap_act_sta_mfi.top = le16_to_cpu(hw->cap_act_sta_mfi.top); 831 832 netdev_info(wlandev->netdev, 833 "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", 834 hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id, 835 hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom, 836 hw->cap_act_sta_mfi.top); 837 838 /* Serial Number */ 839 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, 840 snum, HFA384x_RID_NICSERIALNUMBER_LEN); 841 if (!result) { 842 netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n", 843 HFA384x_RID_NICSERIALNUMBER_LEN, snum); 844 } else { 845 netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); 846 goto failed; 847 } 848 849 /* Collect the MAC address */ 850 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR, 851 wlandev->netdev->dev_addr, ETH_ALEN); 852 if (result != 0) { 853 netdev_err(wlandev->netdev, "Failed to retrieve mac address\n"); 854 goto failed; 855 } 856 857 /* short preamble is always implemented */ 858 wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE; 859 860 /* find out if hardware wep is implemented */ 861 hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp); 862 if (temp) 863 wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP; 864 865 /* get the dBm Scaling constant */ 866 hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp); 867 hw->dbmadjust = temp; 868 869 /* Only enable scan by default on newer firmware */ 870 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, 871 hw->ident_sta_fw.minor, 872 hw->ident_sta_fw.variant) < 873 HFA384x_FIRMWARE_VERSION(1, 5, 5)) { 874 wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN; 875 } 876 877 /* TODO: Set any internally managed config items */ 878 879 goto done; 880failed: 881 netdev_err(wlandev->netdev, "Failed, result=%d\n", result); 882done: 883 return result; 884} 885 886/*---------------------------------------------------------------- 887* prism2sta_globalsetup 888* 889* Set any global RIDs that we want to set at device activation. 890* 891* Arguments: 892* wlandev wlan device structure 893* 894* Returns: 895* 0 success 896* >0 f/w reported error 897* <0 driver reported error 898* 899* Side effects: 900* 901* Call context: 902* process thread 903----------------------------------------------------------------*/ 904static int prism2sta_globalsetup(wlandevice_t *wlandev) 905{ 906 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 907 908 /* Set the maximum frame size */ 909 return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 910 WLAN_DATA_MAXLEN); 911} 912 913static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev) 914{ 915 int result = 0; 916 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 917 918 u16 promisc; 919 920 /* If we're not ready, what's the point? */ 921 if (hw->state != HFA384x_STATE_RUNNING) 922 goto exit; 923 924 if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) 925 promisc = P80211ENUM_truth_true; 926 else 927 promisc = P80211ENUM_truth_false; 928 929 result = 930 hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, 931 promisc); 932exit: 933 return result; 934} 935 936/*---------------------------------------------------------------- 937* prism2sta_inf_handover 938* 939* Handles the receipt of a Handover info frame. Should only be present 940* in APs only. 941* 942* Arguments: 943* wlandev wlan device structure 944* inf ptr to info frame (contents in hfa384x order) 945* 946* Returns: 947* nothing 948* 949* Side effects: 950* 951* Call context: 952* interrupt 953----------------------------------------------------------------*/ 954static void prism2sta_inf_handover(wlandevice_t *wlandev, 955 hfa384x_InfFrame_t *inf) 956{ 957 pr_debug("received infoframe:HANDOVER (unhandled)\n"); 958} 959 960/*---------------------------------------------------------------- 961* prism2sta_inf_tallies 962* 963* Handles the receipt of a CommTallies info frame. 964* 965* Arguments: 966* wlandev wlan device structure 967* inf ptr to info frame (contents in hfa384x order) 968* 969* Returns: 970* nothing 971* 972* Side effects: 973* 974* Call context: 975* interrupt 976----------------------------------------------------------------*/ 977static void prism2sta_inf_tallies(wlandevice_t *wlandev, 978 hfa384x_InfFrame_t *inf) 979{ 980 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 981 u16 *src16; 982 u32 *dst; 983 u32 *src32; 984 int i; 985 int cnt; 986 987 /* 988 ** Determine if these are 16-bit or 32-bit tallies, based on the 989 ** record length of the info record. 990 */ 991 992 cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32); 993 if (inf->framelen > 22) { 994 dst = (u32 *) &hw->tallies; 995 src32 = (u32 *) &inf->info.commtallies32; 996 for (i = 0; i < cnt; i++, dst++, src32++) 997 *dst += le32_to_cpu(*src32); 998 } else { 999 dst = (u32 *) &hw->tallies; 1000 src16 = (u16 *) &inf->info.commtallies16; 1001 for (i = 0; i < cnt; i++, dst++, src16++) 1002 *dst += le16_to_cpu(*src16); 1003 } 1004} 1005 1006/*---------------------------------------------------------------- 1007* prism2sta_inf_scanresults 1008* 1009* Handles the receipt of a Scan Results info frame. 1010* 1011* Arguments: 1012* wlandev wlan device structure 1013* inf ptr to info frame (contents in hfa384x order) 1014* 1015* Returns: 1016* nothing 1017* 1018* Side effects: 1019* 1020* Call context: 1021* interrupt 1022----------------------------------------------------------------*/ 1023static void prism2sta_inf_scanresults(wlandevice_t *wlandev, 1024 hfa384x_InfFrame_t *inf) 1025{ 1026 1027 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1028 int nbss; 1029 hfa384x_ScanResult_t *sr = &(inf->info.scanresult); 1030 int i; 1031 hfa384x_JoinRequest_data_t joinreq; 1032 int result; 1033 1034 /* Get the number of results, first in bytes, then in results */ 1035 nbss = (inf->framelen * sizeof(u16)) - 1036 sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason); 1037 nbss /= sizeof(hfa384x_ScanResultSub_t); 1038 1039 /* Print em */ 1040 pr_debug("rx scanresults, reason=%d, nbss=%d:\n", 1041 inf->info.scanresult.scanreason, nbss); 1042 for (i = 0; i < nbss; i++) { 1043 pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n", 1044 sr->result[i].chid, 1045 sr->result[i].anl, 1046 sr->result[i].sl, sr->result[i].bcnint); 1047 pr_debug(" capinfo=0x%04x proberesp_rate=%d\n", 1048 sr->result[i].capinfo, sr->result[i].proberesp_rate); 1049 } 1050 /* issue a join request */ 1051 joinreq.channel = sr->result[0].chid; 1052 memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN); 1053 result = hfa384x_drvr_setconfig(hw, 1054 HFA384x_RID_JOINREQUEST, 1055 &joinreq, HFA384x_RID_JOINREQUEST_LEN); 1056 if (result) { 1057 netdev_err(wlandev->netdev, "setconfig(joinreq) failed, result=%d\n", 1058 result); 1059 } 1060} 1061 1062/*---------------------------------------------------------------- 1063* prism2sta_inf_hostscanresults 1064* 1065* Handles the receipt of a Scan Results info frame. 1066* 1067* Arguments: 1068* wlandev wlan device structure 1069* inf ptr to info frame (contents in hfa384x order) 1070* 1071* Returns: 1072* nothing 1073* 1074* Side effects: 1075* 1076* Call context: 1077* interrupt 1078----------------------------------------------------------------*/ 1079static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev, 1080 hfa384x_InfFrame_t *inf) 1081{ 1082 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1083 int nbss; 1084 1085 nbss = (inf->framelen - 3) / 32; 1086 pr_debug("Received %d hostscan results\n", nbss); 1087 1088 if (nbss > 32) 1089 nbss = 32; 1090 1091 kfree(hw->scanresults); 1092 1093 hw->scanresults = kmemdup(inf, sizeof(hfa384x_InfFrame_t), GFP_ATOMIC); 1094 1095 if (nbss == 0) 1096 nbss = -1; 1097 1098 /* Notify/wake the sleeping caller. */ 1099 hw->scanflag = nbss; 1100 wake_up_interruptible(&hw->cmdq); 1101}; 1102 1103/*---------------------------------------------------------------- 1104* prism2sta_inf_chinforesults 1105* 1106* Handles the receipt of a Channel Info Results info frame. 1107* 1108* Arguments: 1109* wlandev wlan device structure 1110* inf ptr to info frame (contents in hfa384x order) 1111* 1112* Returns: 1113* nothing 1114* 1115* Side effects: 1116* 1117* Call context: 1118* interrupt 1119----------------------------------------------------------------*/ 1120static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, 1121 hfa384x_InfFrame_t *inf) 1122{ 1123 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1124 unsigned int i, n; 1125 1126 hw->channel_info.results.scanchannels = 1127 le16_to_cpu(inf->info.chinforesult.scanchannels); 1128 1129 for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { 1130 hfa384x_ChInfoResultSub_t *result; 1131 hfa384x_ChInfoResultSub_t *chinforesult; 1132 int chan; 1133 1134 if (!(hw->channel_info.results.scanchannels & (1 << i))) 1135 continue; 1136 1137 result = &inf->info.chinforesult.result[n]; 1138 chan = le16_to_cpu(result->chid) - 1; 1139 1140 if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) 1141 continue; 1142 1143 chinforesult = &hw->channel_info.results.result[chan]; 1144 chinforesult->chid = chan; 1145 chinforesult->anl = le16_to_cpu(result->anl); 1146 chinforesult->pnl = le16_to_cpu(result->pnl); 1147 chinforesult->active = le16_to_cpu(result->active); 1148 1149 pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", 1150 chan + 1, 1151 (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) 1152 ? "signal" : "noise", 1153 chinforesult->anl, chinforesult->pnl, 1154 (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) 1155 ? 1 : 0); 1156 n++; 1157 } 1158 atomic_set(&hw->channel_info.done, 2); 1159 1160 hw->channel_info.count = n; 1161} 1162 1163void prism2sta_processing_defer(struct work_struct *data) 1164{ 1165 hfa384x_t *hw = container_of(data, struct hfa384x, link_bh); 1166 wlandevice_t *wlandev = hw->wlandev; 1167 hfa384x_bytestr32_t ssid; 1168 int result; 1169 1170 /* First let's process the auth frames */ 1171 { 1172 struct sk_buff *skb; 1173 hfa384x_InfFrame_t *inf; 1174 1175 while ((skb = skb_dequeue(&hw->authq))) { 1176 inf = (hfa384x_InfFrame_t *) skb->data; 1177 prism2sta_inf_authreq_defer(wlandev, inf); 1178 } 1179 1180 } 1181 1182 /* Now let's handle the linkstatus stuff */ 1183 if (hw->link_status == hw->link_status_new) 1184 return; 1185 1186 hw->link_status = hw->link_status_new; 1187 1188 switch (hw->link_status) { 1189 case HFA384x_LINK_NOTCONNECTED: 1190 /* I'm currently assuming that this is the initial link 1191 * state. It should only be possible immediately 1192 * following an Enable command. 1193 * Response: 1194 * Block Transmits, Ignore receives of data frames 1195 */ 1196 netif_carrier_off(wlandev->netdev); 1197 1198 netdev_info(wlandev->netdev, "linkstatus=NOTCONNECTED (unhandled)\n"); 1199 break; 1200 1201 case HFA384x_LINK_CONNECTED: 1202 /* This one indicates a successful scan/join/auth/assoc. 1203 * When we have the full MLME complement, this event will 1204 * signify successful completion of both mlme_authenticate 1205 * and mlme_associate. State management will get a little 1206 * ugly here. 1207 * Response: 1208 * Indicate authentication and/or association 1209 * Enable Transmits, Receives and pass up data frames 1210 */ 1211 1212 netif_carrier_on(wlandev->netdev); 1213 1214 /* If we are joining a specific AP, set our 1215 * state and reset retries 1216 */ 1217 if (hw->join_ap == 1) 1218 hw->join_ap = 2; 1219 hw->join_retries = 60; 1220 1221 /* Don't call this in monitor mode */ 1222 if (wlandev->netdev->type == ARPHRD_ETHER) { 1223 u16 portstatus; 1224 1225 netdev_info(wlandev->netdev, "linkstatus=CONNECTED\n"); 1226 1227 /* For non-usb devices, we can use the sync versions */ 1228 /* Collect the BSSID, and set state to allow tx */ 1229 1230 result = hfa384x_drvr_getconfig(hw, 1231 HFA384x_RID_CURRENTBSSID, 1232 wlandev->bssid, 1233 WLAN_BSSID_LEN); 1234 if (result) { 1235 pr_debug 1236 ("getconfig(0x%02x) failed, result = %d\n", 1237 HFA384x_RID_CURRENTBSSID, result); 1238 return; 1239 } 1240 1241 result = hfa384x_drvr_getconfig(hw, 1242 HFA384x_RID_CURRENTSSID, 1243 &ssid, sizeof(ssid)); 1244 if (result) { 1245 pr_debug 1246 ("getconfig(0x%02x) failed, result = %d\n", 1247 HFA384x_RID_CURRENTSSID, result); 1248 return; 1249 } 1250 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, 1251 (p80211pstrd_t *) & 1252 wlandev->ssid); 1253 1254 /* Collect the port status */ 1255 result = hfa384x_drvr_getconfig16(hw, 1256 HFA384x_RID_PORTSTATUS, 1257 &portstatus); 1258 if (result) { 1259 pr_debug 1260 ("getconfig(0x%02x) failed, result = %d\n", 1261 HFA384x_RID_PORTSTATUS, result); 1262 return; 1263 } 1264 wlandev->macmode = 1265 (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? 1266 WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; 1267 1268 /* signal back up to cfg80211 layer */ 1269 prism2_connect_result(wlandev, P80211ENUM_truth_false); 1270 1271 /* Get the ball rolling on the comms quality stuff */ 1272 prism2sta_commsqual_defer(&hw->commsqual_bh); 1273 } 1274 break; 1275 1276 case HFA384x_LINK_DISCONNECTED: 1277 /* This one indicates that our association is gone. We've 1278 * lost connection with the AP and/or been disassociated. 1279 * This indicates that the MAC has completely cleared it's 1280 * associated state. We * should send a deauth indication 1281 * (implying disassoc) up * to the MLME. 1282 * Response: 1283 * Indicate Deauthentication 1284 * Block Transmits, Ignore receives of data frames 1285 */ 1286 if (wlandev->netdev->type == ARPHRD_ETHER) 1287 netdev_info(wlandev->netdev, 1288 "linkstatus=DISCONNECTED (unhandled)\n"); 1289 wlandev->macmode = WLAN_MACMODE_NONE; 1290 1291 netif_carrier_off(wlandev->netdev); 1292 1293 /* signal back up to cfg80211 layer */ 1294 prism2_disconnected(wlandev); 1295 1296 break; 1297 1298 case HFA384x_LINK_AP_CHANGE: 1299 /* This one indicates that the MAC has decided to and 1300 * successfully completed a change to another AP. We 1301 * should probably implement a reassociation indication 1302 * in response to this one. I'm thinking that the the 1303 * p80211 layer needs to be notified in case of 1304 * buffering/queueing issues. User mode also needs to be 1305 * notified so that any BSS dependent elements can be 1306 * updated. 1307 * associated state. We * should send a deauth indication 1308 * (implying disassoc) up * to the MLME. 1309 * Response: 1310 * Indicate Reassociation 1311 * Enable Transmits, Receives and pass up data frames 1312 */ 1313 netdev_info(wlandev->netdev, "linkstatus=AP_CHANGE\n"); 1314 1315 result = hfa384x_drvr_getconfig(hw, 1316 HFA384x_RID_CURRENTBSSID, 1317 wlandev->bssid, WLAN_BSSID_LEN); 1318 if (result) { 1319 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1320 HFA384x_RID_CURRENTBSSID, result); 1321 return; 1322 } 1323 1324 result = hfa384x_drvr_getconfig(hw, 1325 HFA384x_RID_CURRENTSSID, 1326 &ssid, sizeof(ssid)); 1327 if (result) { 1328 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1329 HFA384x_RID_CURRENTSSID, result); 1330 return; 1331 } 1332 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, 1333 (p80211pstrd_t *) &wlandev->ssid); 1334 1335 hw->link_status = HFA384x_LINK_CONNECTED; 1336 netif_carrier_on(wlandev->netdev); 1337 1338 /* signal back up to cfg80211 layer */ 1339 prism2_roamed(wlandev); 1340 1341 break; 1342 1343 case HFA384x_LINK_AP_OUTOFRANGE: 1344 /* This one indicates that the MAC has decided that the 1345 * AP is out of range, but hasn't found a better candidate 1346 * so the MAC maintains its "associated" state in case 1347 * we get back in range. We should block transmits and 1348 * receives in this state. Do we need an indication here? 1349 * Probably not since a polling user-mode element would 1350 * get this status from from p2PortStatus(FD40). What about 1351 * p80211? 1352 * Response: 1353 * Block Transmits, Ignore receives of data frames 1354 */ 1355 netdev_info(wlandev->netdev, "linkstatus=AP_OUTOFRANGE (unhandled)\n"); 1356 1357 netif_carrier_off(wlandev->netdev); 1358 1359 break; 1360 1361 case HFA384x_LINK_AP_INRANGE: 1362 /* This one indicates that the MAC has decided that the 1363 * AP is back in range. We continue working with our 1364 * existing association. 1365 * Response: 1366 * Enable Transmits, Receives and pass up data frames 1367 */ 1368 netdev_info(wlandev->netdev, "linkstatus=AP_INRANGE\n"); 1369 1370 hw->link_status = HFA384x_LINK_CONNECTED; 1371 netif_carrier_on(wlandev->netdev); 1372 1373 break; 1374 1375 case HFA384x_LINK_ASSOCFAIL: 1376 /* This one is actually a peer to CONNECTED. We've 1377 * requested a join for a given SSID and optionally BSSID. 1378 * We can use this one to indicate authentication and 1379 * association failures. The trick is going to be 1380 * 1) identifying the failure, and 2) state management. 1381 * Response: 1382 * Disable Transmits, Ignore receives of data frames 1383 */ 1384 if (hw->join_ap && --hw->join_retries > 0) { 1385 hfa384x_JoinRequest_data_t joinreq; 1386 1387 joinreq = hw->joinreq; 1388 /* Send the join request */ 1389 hfa384x_drvr_setconfig(hw, 1390 HFA384x_RID_JOINREQUEST, 1391 &joinreq, 1392 HFA384x_RID_JOINREQUEST_LEN); 1393 netdev_info(wlandev->netdev, 1394 "linkstatus=ASSOCFAIL (re-submitting join)\n"); 1395 } else { 1396 netdev_info(wlandev->netdev, "linkstatus=ASSOCFAIL (unhandled)\n"); 1397 } 1398 1399 netif_carrier_off(wlandev->netdev); 1400 1401 /* signal back up to cfg80211 layer */ 1402 prism2_connect_result(wlandev, P80211ENUM_truth_true); 1403 1404 break; 1405 1406 default: 1407 /* This is bad, IO port problems? */ 1408 netdev_warn(wlandev->netdev, 1409 "unknown linkstatus=0x%02x\n", hw->link_status); 1410 return; 1411 } 1412 1413 wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); 1414} 1415 1416/*---------------------------------------------------------------- 1417* prism2sta_inf_linkstatus 1418* 1419* Handles the receipt of a Link Status info frame. 1420* 1421* Arguments: 1422* wlandev wlan device structure 1423* inf ptr to info frame (contents in hfa384x order) 1424* 1425* Returns: 1426* nothing 1427* 1428* Side effects: 1429* 1430* Call context: 1431* interrupt 1432----------------------------------------------------------------*/ 1433static void prism2sta_inf_linkstatus(wlandevice_t *wlandev, 1434 hfa384x_InfFrame_t *inf) 1435{ 1436 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1437 1438 hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); 1439 1440 schedule_work(&hw->link_bh); 1441} 1442 1443/*---------------------------------------------------------------- 1444* prism2sta_inf_assocstatus 1445* 1446* Handles the receipt of an Association Status info frame. Should 1447* be present in APs only. 1448* 1449* Arguments: 1450* wlandev wlan device structure 1451* inf ptr to info frame (contents in hfa384x order) 1452* 1453* Returns: 1454* nothing 1455* 1456* Side effects: 1457* 1458* Call context: 1459* interrupt 1460----------------------------------------------------------------*/ 1461static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, 1462 hfa384x_InfFrame_t *inf) 1463{ 1464 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1465 hfa384x_AssocStatus_t rec; 1466 int i; 1467 1468 memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); 1469 rec.assocstatus = le16_to_cpu(rec.assocstatus); 1470 rec.reason = le16_to_cpu(rec.reason); 1471 1472 /* 1473 ** Find the address in the list of authenticated stations. 1474 ** If it wasn't found, then this address has not been previously 1475 ** authenticated and something weird has happened if this is 1476 ** anything other than an "authentication failed" message. 1477 ** If the address was found, then set the "associated" flag for 1478 ** that station, based on whether the station is associating or 1479 ** losing its association. Something weird has also happened 1480 ** if we find the address in the list of authenticated stations 1481 ** but we are getting an "authentication failed" message. 1482 */ 1483 1484 for (i = 0; i < hw->authlist.cnt; i++) 1485 if (memcmp(rec.sta_addr, hw->authlist.addr[i], ETH_ALEN) == 0) 1486 break; 1487 1488 if (i >= hw->authlist.cnt) { 1489 if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) 1490 netdev_warn(wlandev->netdev, 1491 "assocstatus info frame received for non-authenticated station.\n"); 1492 } else { 1493 hw->authlist.assoc[i] = 1494 (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || 1495 rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); 1496 1497 if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) 1498 netdev_warn(wlandev->netdev, 1499"authfail assocstatus info frame received for authenticated station.\n"); 1500 } 1501} 1502 1503/*---------------------------------------------------------------- 1504* prism2sta_inf_authreq 1505* 1506* Handles the receipt of an Authentication Request info frame. Should 1507* be present in APs only. 1508* 1509* Arguments: 1510* wlandev wlan device structure 1511* inf ptr to info frame (contents in hfa384x order) 1512* 1513* Returns: 1514* nothing 1515* 1516* Side effects: 1517* 1518* Call context: 1519* interrupt 1520* 1521----------------------------------------------------------------*/ 1522static void prism2sta_inf_authreq(wlandevice_t *wlandev, 1523 hfa384x_InfFrame_t *inf) 1524{ 1525 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1526 struct sk_buff *skb; 1527 1528 skb = dev_alloc_skb(sizeof(*inf)); 1529 if (skb) { 1530 skb_put(skb, sizeof(*inf)); 1531 memcpy(skb->data, inf, sizeof(*inf)); 1532 skb_queue_tail(&hw->authq, skb); 1533 schedule_work(&hw->link_bh); 1534 } 1535} 1536 1537static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, 1538 hfa384x_InfFrame_t *inf) 1539{ 1540 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1541 hfa384x_authenticateStation_data_t rec; 1542 1543 int i, added, result, cnt; 1544 u8 *addr; 1545 1546 /* 1547 ** Build the AuthenticateStation record. Initialize it for denying 1548 ** authentication. 1549 */ 1550 1551 memcpy(rec.address, inf->info.authreq.sta_addr, ETH_ALEN); 1552 rec.status = P80211ENUM_status_unspec_failure; 1553 1554 /* 1555 ** Authenticate based on the access mode. 1556 */ 1557 1558 switch (hw->accessmode) { 1559 case WLAN_ACCESS_NONE: 1560 1561 /* 1562 ** Deny all new authentications. However, if a station 1563 ** is ALREADY authenticated, then accept it. 1564 */ 1565 1566 for (i = 0; i < hw->authlist.cnt; i++) 1567 if (memcmp(rec.address, hw->authlist.addr[i], 1568 ETH_ALEN) == 0) { 1569 rec.status = P80211ENUM_status_successful; 1570 break; 1571 } 1572 1573 break; 1574 1575 case WLAN_ACCESS_ALL: 1576 1577 /* 1578 ** Allow all authentications. 1579 */ 1580 1581 rec.status = P80211ENUM_status_successful; 1582 break; 1583 1584 case WLAN_ACCESS_ALLOW: 1585 1586 /* 1587 ** Only allow the authentication if the MAC address 1588 ** is in the list of allowed addresses. 1589 ** 1590 ** Since this is the interrupt handler, we may be here 1591 ** while the access list is in the middle of being 1592 ** updated. Choose the list which is currently okay. 1593 ** See "prism2mib_priv_accessallow()" for details. 1594 */ 1595 1596 if (hw->allow.modify == 0) { 1597 cnt = hw->allow.cnt; 1598 addr = hw->allow.addr[0]; 1599 } else { 1600 cnt = hw->allow.cnt1; 1601 addr = hw->allow.addr1[0]; 1602 } 1603 1604 for (i = 0; i < cnt; i++, addr += ETH_ALEN) 1605 if (memcmp(rec.address, addr, ETH_ALEN) == 0) { 1606 rec.status = P80211ENUM_status_successful; 1607 break; 1608 } 1609 1610 break; 1611 1612 case WLAN_ACCESS_DENY: 1613 1614 /* 1615 ** Allow the authentication UNLESS the MAC address is 1616 ** in the list of denied addresses. 1617 ** 1618 ** Since this is the interrupt handler, we may be here 1619 ** while the access list is in the middle of being 1620 ** updated. Choose the list which is currently okay. 1621 ** See "prism2mib_priv_accessdeny()" for details. 1622 */ 1623 1624 if (hw->deny.modify == 0) { 1625 cnt = hw->deny.cnt; 1626 addr = hw->deny.addr[0]; 1627 } else { 1628 cnt = hw->deny.cnt1; 1629 addr = hw->deny.addr1[0]; 1630 } 1631 1632 rec.status = P80211ENUM_status_successful; 1633 1634 for (i = 0; i < cnt; i++, addr += ETH_ALEN) 1635 if (memcmp(rec.address, addr, ETH_ALEN) == 0) { 1636 rec.status = P80211ENUM_status_unspec_failure; 1637 break; 1638 } 1639 1640 break; 1641 } 1642 1643 /* 1644 ** If the authentication is okay, then add the MAC address to the 1645 ** list of authenticated stations. Don't add the address if it 1646 ** is already in the list. (802.11b does not seem to disallow 1647 ** a station from issuing an authentication request when the 1648 ** station is already authenticated. Does this sort of thing 1649 ** ever happen? We might as well do the check just in case.) 1650 */ 1651 1652 added = 0; 1653 1654 if (rec.status == P80211ENUM_status_successful) { 1655 for (i = 0; i < hw->authlist.cnt; i++) 1656 if (memcmp(rec.address, hw->authlist.addr[i], ETH_ALEN) 1657 == 0) 1658 break; 1659 1660 if (i >= hw->authlist.cnt) { 1661 if (hw->authlist.cnt >= WLAN_AUTH_MAX) { 1662 rec.status = P80211ENUM_status_ap_full; 1663 } else { 1664 memcpy(hw->authlist.addr[hw->authlist.cnt], 1665 rec.address, ETH_ALEN); 1666 hw->authlist.cnt++; 1667 added = 1; 1668 } 1669 } 1670 } 1671 1672 /* 1673 ** Send back the results of the authentication. If this doesn't work, 1674 ** then make sure to remove the address from the authenticated list if 1675 ** it was added. 1676 */ 1677 1678 rec.status = cpu_to_le16(rec.status); 1679 rec.algorithm = inf->info.authreq.algorithm; 1680 1681 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, 1682 &rec, sizeof(rec)); 1683 if (result) { 1684 if (added) 1685 hw->authlist.cnt--; 1686 netdev_err(wlandev->netdev, 1687 "setconfig(authenticatestation) failed, result=%d\n", 1688 result); 1689 } 1690} 1691 1692/*---------------------------------------------------------------- 1693* prism2sta_inf_psusercnt 1694* 1695* Handles the receipt of a PowerSaveUserCount info frame. Should 1696* be present in APs only. 1697* 1698* Arguments: 1699* wlandev wlan device structure 1700* inf ptr to info frame (contents in hfa384x order) 1701* 1702* Returns: 1703* nothing 1704* 1705* Side effects: 1706* 1707* Call context: 1708* interrupt 1709----------------------------------------------------------------*/ 1710static void prism2sta_inf_psusercnt(wlandevice_t *wlandev, 1711 hfa384x_InfFrame_t *inf) 1712{ 1713 hfa384x_t *hw = (hfa384x_t *) wlandev->priv; 1714 1715 hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt); 1716} 1717 1718/*---------------------------------------------------------------- 1719* prism2sta_ev_info 1720* 1721* Handles the Info event. 1722* 1723* Arguments: 1724* wlandev wlan device structure 1725* inf ptr to a generic info frame 1726* 1727* Returns: 1728* nothing 1729* 1730* Side effects: 1731* 1732* Call context: 1733* interrupt 1734----------------------------------------------------------------*/ 1735void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) 1736{ 1737 inf->infotype = le16_to_cpu(inf->infotype); 1738 /* Dispatch */ 1739 switch (inf->infotype) { 1740 case HFA384x_IT_HANDOVERADDR: 1741 prism2sta_inf_handover(wlandev, inf); 1742 break; 1743 case HFA384x_IT_COMMTALLIES: 1744 prism2sta_inf_tallies(wlandev, inf); 1745 break; 1746 case HFA384x_IT_HOSTSCANRESULTS: 1747 prism2sta_inf_hostscanresults(wlandev, inf); 1748 break; 1749 case HFA384x_IT_SCANRESULTS: 1750 prism2sta_inf_scanresults(wlandev, inf); 1751 break; 1752 case HFA384x_IT_CHINFORESULTS: 1753 prism2sta_inf_chinforesults(wlandev, inf); 1754 break; 1755 case HFA384x_IT_LINKSTATUS: 1756 prism2sta_inf_linkstatus(wlandev, inf); 1757 break; 1758 case HFA384x_IT_ASSOCSTATUS: 1759 prism2sta_inf_assocstatus(wlandev, inf); 1760 break; 1761 case HFA384x_IT_AUTHREQ: 1762 prism2sta_inf_authreq(wlandev, inf); 1763 break; 1764 case HFA384x_IT_PSUSERCNT: 1765 prism2sta_inf_psusercnt(wlandev, inf); 1766 break; 1767 case HFA384x_IT_KEYIDCHANGED: 1768 netdev_warn(wlandev->netdev, "Unhandled IT_KEYIDCHANGED\n"); 1769 break; 1770 case HFA384x_IT_ASSOCREQ: 1771 netdev_warn(wlandev->netdev, "Unhandled IT_ASSOCREQ\n"); 1772 break; 1773 case HFA384x_IT_MICFAILURE: 1774 netdev_warn(wlandev->netdev, "Unhandled IT_MICFAILURE\n"); 1775 break; 1776 default: 1777 netdev_warn(wlandev->netdev, 1778 "Unknown info type=0x%02x\n", inf->infotype); 1779 break; 1780 } 1781} 1782 1783/*---------------------------------------------------------------- 1784* prism2sta_ev_txexc 1785* 1786* Handles the TxExc event. A Transmit Exception event indicates 1787* that the MAC's TX process was unsuccessful - so the packet did 1788* not get transmitted. 1789* 1790* Arguments: 1791* wlandev wlan device structure 1792* status tx frame status word 1793* 1794* Returns: 1795* nothing 1796* 1797* Side effects: 1798* 1799* Call context: 1800* interrupt 1801----------------------------------------------------------------*/ 1802void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status) 1803{ 1804 pr_debug("TxExc status=0x%x.\n", status); 1805} 1806 1807/*---------------------------------------------------------------- 1808* prism2sta_ev_tx 1809* 1810* Handles the Tx event. 1811* 1812* Arguments: 1813* wlandev wlan device structure 1814* status tx frame status word 1815* Returns: 1816* nothing 1817* 1818* Side effects: 1819* 1820* Call context: 1821* interrupt 1822----------------------------------------------------------------*/ 1823void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status) 1824{ 1825 pr_debug("Tx Complete, status=0x%04x\n", status); 1826 /* update linux network stats */ 1827 wlandev->netdev->stats.tx_packets++; 1828} 1829 1830/*---------------------------------------------------------------- 1831* prism2sta_ev_rx 1832* 1833* Handles the Rx event. 1834* 1835* Arguments: 1836* wlandev wlan device structure 1837* 1838* Returns: 1839* nothing 1840* 1841* Side effects: 1842* 1843* Call context: 1844* interrupt 1845----------------------------------------------------------------*/ 1846void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) 1847{ 1848 p80211netdev_rx(wlandev, skb); 1849} 1850 1851/*---------------------------------------------------------------- 1852* prism2sta_ev_alloc 1853* 1854* Handles the Alloc event. 1855* 1856* Arguments: 1857* wlandev wlan device structure 1858* 1859* Returns: 1860* nothing 1861* 1862* Side effects: 1863* 1864* Call context: 1865* interrupt 1866----------------------------------------------------------------*/ 1867void prism2sta_ev_alloc(wlandevice_t *wlandev) 1868{ 1869 netif_wake_queue(wlandev->netdev); 1870} 1871 1872/*---------------------------------------------------------------- 1873* create_wlan 1874* 1875* Called at module init time. This creates the wlandevice_t structure 1876* and initializes it with relevant bits. 1877* 1878* Arguments: 1879* none 1880* 1881* Returns: 1882* the created wlandevice_t structure. 1883* 1884* Side effects: 1885* also allocates the priv/hw structures. 1886* 1887* Call context: 1888* process thread 1889* 1890----------------------------------------------------------------*/ 1891static wlandevice_t *create_wlan(void) 1892{ 1893 wlandevice_t *wlandev = NULL; 1894 hfa384x_t *hw = NULL; 1895 1896 /* Alloc our structures */ 1897 wlandev = kzalloc(sizeof(wlandevice_t), GFP_KERNEL); 1898 hw = kzalloc(sizeof(hfa384x_t), GFP_KERNEL); 1899 1900 if (!wlandev || !hw) { 1901 pr_err("%s: Memory allocation failure.\n", dev_info); 1902 kfree(wlandev); 1903 kfree(hw); 1904 return NULL; 1905 } 1906 1907 /* Initialize the network device object. */ 1908 wlandev->nsdname = dev_info; 1909 wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; 1910 wlandev->priv = hw; 1911 wlandev->open = prism2sta_open; 1912 wlandev->close = prism2sta_close; 1913 wlandev->reset = prism2sta_reset; 1914 wlandev->txframe = prism2sta_txframe; 1915 wlandev->mlmerequest = prism2sta_mlmerequest; 1916 wlandev->set_multicast_list = prism2sta_setmulticast; 1917 wlandev->tx_timeout = hfa384x_tx_timeout; 1918 1919 wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN; 1920 1921 /* Initialize the device private data structure. */ 1922 hw->dot11_desired_bss_type = 1; 1923 1924 return wlandev; 1925} 1926 1927void prism2sta_commsqual_defer(struct work_struct *data) 1928{ 1929 hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh); 1930 wlandevice_t *wlandev = hw->wlandev; 1931 hfa384x_bytestr32_t ssid; 1932 struct p80211msg_dot11req_mibget msg; 1933 p80211item_uint32_t *mibitem = (p80211item_uint32_t *) 1934 &msg.mibattribute.data; 1935 int result = 0; 1936 1937 if (hw->wlandev->hwremoved) 1938 return; 1939 1940 /* we don't care if we're in AP mode */ 1941 if ((wlandev->macmode == WLAN_MACMODE_NONE) || 1942 (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { 1943 return; 1944 } 1945 1946 /* It only makes sense to poll these in non-IBSS */ 1947 if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { 1948 result = hfa384x_drvr_getconfig( 1949 hw, HFA384x_RID_DBMCOMMSQUALITY, 1950 &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN); 1951 1952 if (result) { 1953 netdev_err(wlandev->netdev, "error fetching commsqual\n"); 1954 return; 1955 } 1956 1957 pr_debug("commsqual %d %d %d\n", 1958 le16_to_cpu(hw->qual.CQ_currBSS), 1959 le16_to_cpu(hw->qual.ASL_currBSS), 1960 le16_to_cpu(hw->qual.ANL_currFC)); 1961 } 1962 1963 /* Get the signal rate */ 1964 msg.msgcode = DIDmsg_dot11req_mibget; 1965 mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate; 1966 result = p80211req_dorequest(wlandev, (u8 *) &msg); 1967 1968 if (result) { 1969 pr_debug("get signal rate failed, result = %d\n", 1970 result); 1971 return; 1972 } 1973 1974 switch (mibitem->data) { 1975 case HFA384x_RATEBIT_1: 1976 hw->txrate = 10; 1977 break; 1978 case HFA384x_RATEBIT_2: 1979 hw->txrate = 20; 1980 break; 1981 case HFA384x_RATEBIT_5dot5: 1982 hw->txrate = 55; 1983 break; 1984 case HFA384x_RATEBIT_11: 1985 hw->txrate = 110; 1986 break; 1987 default: 1988 pr_debug("Bad ratebit (%d)\n", mibitem->data); 1989 } 1990 1991 /* Lastly, we need to make sure the BSSID didn't change on us */ 1992 result = hfa384x_drvr_getconfig(hw, 1993 HFA384x_RID_CURRENTBSSID, 1994 wlandev->bssid, WLAN_BSSID_LEN); 1995 if (result) { 1996 pr_debug("getconfig(0x%02x) failed, result = %d\n", 1997 HFA384x_RID_CURRENTBSSID, result); 1998 return; 1999 } 2000 2001 result = hfa384x_drvr_getconfig(hw, 2002 HFA384x_RID_CURRENTSSID, 2003 &ssid, sizeof(ssid)); 2004 if (result) { 2005 pr_debug("getconfig(0x%02x) failed, result = %d\n", 2006 HFA384x_RID_CURRENTSSID, result); 2007 return; 2008 } 2009 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid, 2010 (p80211pstrd_t *) &wlandev->ssid); 2011 2012 /* Reschedule timer */ 2013 mod_timer(&hw->commsqual_timer, jiffies + HZ); 2014} 2015 2016void prism2sta_commsqual_timer(unsigned long data) 2017{ 2018 hfa384x_t *hw = (hfa384x_t *) data; 2019 2020 schedule_work(&hw->commsqual_bh); 2021} 2022