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