0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 #include <linux/module.h>
0055 #include <linux/kernel.h>
0056 #include <linux/sched.h>
0057 #include <linux/types.h>
0058 #include <linux/slab.h>
0059 #include <linux/wireless.h>
0060 #include <linux/netdevice.h>
0061 #include <linux/workqueue.h>
0062 #include <linux/byteorder/generic.h>
0063 #include <linux/etherdevice.h>
0064
0065 #include <linux/io.h>
0066 #include <linux/delay.h>
0067 #include <asm/byteorder.h>
0068 #include <linux/if_arp.h>
0069 #include <linux/if_ether.h>
0070 #include <linux/bitops.h>
0071
0072 #include "p80211types.h"
0073 #include "p80211hdr.h"
0074 #include "p80211mgmt.h"
0075 #include "p80211conv.h"
0076 #include "p80211msg.h"
0077 #include "p80211netdev.h"
0078 #include "p80211req.h"
0079 #include "p80211metadef.h"
0080 #include "p80211metastruct.h"
0081 #include "hfa384x.h"
0082 #include "prism2mgmt.h"
0083
0084 static char *dev_info = "prism2_usb";
0085 static struct wlandevice *create_wlan(void);
0086
0087 int prism2_reset_holdtime = 30;
0088 int prism2_reset_settletime = 100;
0089
0090 static int prism2_doreset;
0091
0092 module_param(prism2_doreset, int, 0644);
0093 MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
0094
0095 module_param(prism2_reset_holdtime, int, 0644);
0096 MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms");
0097 module_param(prism2_reset_settletime, int, 0644);
0098 MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
0099
0100 MODULE_LICENSE("Dual MPL/GPL");
0101
0102 static int prism2sta_open(struct wlandevice *wlandev);
0103 static int prism2sta_close(struct wlandevice *wlandev);
0104 static void prism2sta_reset(struct wlandevice *wlandev);
0105 static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb,
0106 struct p80211_hdr *p80211_hdr,
0107 struct p80211_metawep *p80211_wep);
0108 static int prism2sta_mlmerequest(struct wlandevice *wlandev,
0109 struct p80211msg *msg);
0110 static int prism2sta_getcardinfo(struct wlandevice *wlandev);
0111 static int prism2sta_globalsetup(struct wlandevice *wlandev);
0112 static int prism2sta_setmulticast(struct wlandevice *wlandev,
0113 struct net_device *dev);
0114
0115 static void prism2sta_inf_handover(struct wlandevice *wlandev,
0116 struct hfa384x_inf_frame *inf);
0117 static void prism2sta_inf_tallies(struct wlandevice *wlandev,
0118 struct hfa384x_inf_frame *inf);
0119 static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev,
0120 struct hfa384x_inf_frame *inf);
0121 static void prism2sta_inf_scanresults(struct wlandevice *wlandev,
0122 struct hfa384x_inf_frame *inf);
0123 static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
0124 struct hfa384x_inf_frame *inf);
0125 static void prism2sta_inf_linkstatus(struct wlandevice *wlandev,
0126 struct hfa384x_inf_frame *inf);
0127 static void prism2sta_inf_assocstatus(struct wlandevice *wlandev,
0128 struct hfa384x_inf_frame *inf);
0129 static void prism2sta_inf_authreq(struct wlandevice *wlandev,
0130 struct hfa384x_inf_frame *inf);
0131 static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
0132 struct hfa384x_inf_frame *inf);
0133 static void prism2sta_inf_psusercnt(struct wlandevice *wlandev,
0134 struct hfa384x_inf_frame *inf);
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static int prism2sta_open(struct wlandevice *wlandev)
0158 {
0159
0160
0161
0162
0163
0164
0165
0166
0167 return 0;
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 static int prism2sta_close(struct wlandevice *wlandev)
0192 {
0193
0194
0195
0196
0197
0198
0199 return 0;
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 static void prism2sta_reset(struct wlandevice *wlandev)
0220 {
0221 }
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb,
0245 struct p80211_hdr *p80211_hdr,
0246 struct p80211_metawep *p80211_wep)
0247 {
0248 struct hfa384x *hw = wlandev->priv;
0249
0250
0251 if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
0252 HOSTWEP_PRIVACYINVOKED) {
0253 p80211_hdr->frame_control |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
0254 }
0255
0256 return hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 static int prism2sta_mlmerequest(struct wlandevice *wlandev,
0284 struct p80211msg *msg)
0285 {
0286 struct hfa384x *hw = wlandev->priv;
0287
0288 int result = 0;
0289
0290 switch (msg->msgcode) {
0291 case DIDMSG_DOT11REQ_MIBGET:
0292 pr_debug("Received mibget request\n");
0293 result = prism2mgmt_mibset_mibget(wlandev, msg);
0294 break;
0295 case DIDMSG_DOT11REQ_MIBSET:
0296 pr_debug("Received mibset request\n");
0297 result = prism2mgmt_mibset_mibget(wlandev, msg);
0298 break;
0299 case DIDMSG_DOT11REQ_SCAN:
0300 pr_debug("Received scan request\n");
0301 result = prism2mgmt_scan(wlandev, msg);
0302 break;
0303 case DIDMSG_DOT11REQ_SCAN_RESULTS:
0304 pr_debug("Received scan_results request\n");
0305 result = prism2mgmt_scan_results(wlandev, msg);
0306 break;
0307 case DIDMSG_DOT11REQ_START:
0308 pr_debug("Received mlme start request\n");
0309 result = prism2mgmt_start(wlandev, msg);
0310 break;
0311
0312
0313
0314 case DIDMSG_P2REQ_READPDA:
0315 pr_debug("Received mlme readpda request\n");
0316 result = prism2mgmt_readpda(wlandev, msg);
0317 break;
0318 case DIDMSG_P2REQ_RAMDL_STATE:
0319 pr_debug("Received mlme ramdl_state request\n");
0320 result = prism2mgmt_ramdl_state(wlandev, msg);
0321 break;
0322 case DIDMSG_P2REQ_RAMDL_WRITE:
0323 pr_debug("Received mlme ramdl_write request\n");
0324 result = prism2mgmt_ramdl_write(wlandev, msg);
0325 break;
0326 case DIDMSG_P2REQ_FLASHDL_STATE:
0327 pr_debug("Received mlme flashdl_state request\n");
0328 result = prism2mgmt_flashdl_state(wlandev, msg);
0329 break;
0330 case DIDMSG_P2REQ_FLASHDL_WRITE:
0331 pr_debug("Received mlme flashdl_write request\n");
0332 result = prism2mgmt_flashdl_write(wlandev, msg);
0333 break;
0334
0335
0336
0337 case DIDMSG_LNXREQ_HOSTWEP:
0338 break;
0339 case DIDMSG_LNXREQ_IFSTATE: {
0340 struct p80211msg_lnxreq_ifstate *ifstatemsg;
0341
0342 pr_debug("Received mlme ifstate request\n");
0343 ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg;
0344 result = prism2sta_ifstate(wlandev,
0345 ifstatemsg->ifstate.data);
0346 ifstatemsg->resultcode.status =
0347 P80211ENUM_msgitem_status_data_ok;
0348 ifstatemsg->resultcode.data = result;
0349 result = 0;
0350 break;
0351 }
0352 case DIDMSG_LNXREQ_WLANSNIFF:
0353 pr_debug("Received mlme wlansniff request\n");
0354 result = prism2mgmt_wlansniff(wlandev, msg);
0355 break;
0356 case DIDMSG_LNXREQ_AUTOJOIN:
0357 pr_debug("Received mlme autojoin request\n");
0358 result = prism2mgmt_autojoin(wlandev, msg);
0359 break;
0360 case DIDMSG_LNXREQ_COMMSQUALITY: {
0361 struct p80211msg_lnxreq_commsquality *qualmsg;
0362
0363 pr_debug("Received commsquality request\n");
0364
0365 qualmsg = (struct p80211msg_lnxreq_commsquality *)msg;
0366
0367 qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
0368 qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
0369 qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
0370
0371 qualmsg->link.data = le16_to_cpu(hw->qual.cq_curr_bss);
0372 qualmsg->level.data = le16_to_cpu(hw->qual.asl_curr_bss);
0373 qualmsg->noise.data = le16_to_cpu(hw->qual.anl_curr_fc);
0374 qualmsg->txrate.data = hw->txrate;
0375
0376 break;
0377 }
0378 default:
0379 netdev_warn(wlandev->netdev,
0380 "Unknown mgmt request message 0x%08x",
0381 msg->msgcode);
0382 break;
0383 }
0384
0385 return result;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409 u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate)
0410 {
0411 struct hfa384x *hw = wlandev->priv;
0412 u32 result;
0413
0414 result = P80211ENUM_resultcode_implementation_failure;
0415
0416 pr_debug("Current MSD state(%d), requesting(%d)\n",
0417 wlandev->msdstate, ifstate);
0418 switch (ifstate) {
0419 case P80211ENUM_ifstate_fwload:
0420 switch (wlandev->msdstate) {
0421 case WLAN_MSD_HWPRESENT:
0422 wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING;
0423
0424
0425
0426
0427 result = hfa384x_drvr_start(hw);
0428 if (result) {
0429 netdev_err(wlandev->netdev,
0430 "hfa384x_drvr_start() failed,result=%d\n",
0431 (int)result);
0432 result =
0433 P80211ENUM_resultcode_implementation_failure;
0434 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0435 break;
0436 }
0437 wlandev->msdstate = WLAN_MSD_FWLOAD;
0438 result = P80211ENUM_resultcode_success;
0439 break;
0440 case WLAN_MSD_FWLOAD:
0441 hfa384x_cmd_initialize(hw);
0442 result = P80211ENUM_resultcode_success;
0443 break;
0444 case WLAN_MSD_RUNNING:
0445 netdev_warn(wlandev->netdev,
0446 "Cannot enter fwload state from enable state, you must disable first.\n");
0447 result = P80211ENUM_resultcode_invalid_parameters;
0448 break;
0449 case WLAN_MSD_HWFAIL:
0450 default:
0451
0452
0453
0454 result = P80211ENUM_resultcode_implementation_failure;
0455 break;
0456 }
0457 break;
0458 case P80211ENUM_ifstate_enable:
0459 switch (wlandev->msdstate) {
0460 case WLAN_MSD_HWPRESENT:
0461 case WLAN_MSD_FWLOAD:
0462 wlandev->msdstate = WLAN_MSD_RUNNING_PENDING;
0463
0464
0465
0466
0467
0468
0469
0470
0471 result = hfa384x_drvr_start(hw);
0472 if (result) {
0473 netdev_err(wlandev->netdev,
0474 "hfa384x_drvr_start() failed,result=%d\n",
0475 (int)result);
0476 result =
0477 P80211ENUM_resultcode_implementation_failure;
0478 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0479 break;
0480 }
0481
0482 result = prism2sta_getcardinfo(wlandev);
0483 if (result) {
0484 netdev_err(wlandev->netdev,
0485 "prism2sta_getcardinfo() failed,result=%d\n",
0486 (int)result);
0487 result =
0488 P80211ENUM_resultcode_implementation_failure;
0489 hfa384x_drvr_stop(hw);
0490 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0491 break;
0492 }
0493 result = prism2sta_globalsetup(wlandev);
0494 if (result) {
0495 netdev_err(wlandev->netdev,
0496 "prism2sta_globalsetup() failed,result=%d\n",
0497 (int)result);
0498 result =
0499 P80211ENUM_resultcode_implementation_failure;
0500 hfa384x_drvr_stop(hw);
0501 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0502 break;
0503 }
0504 wlandev->msdstate = WLAN_MSD_RUNNING;
0505 hw->join_ap = 0;
0506 hw->join_retries = 60;
0507 result = P80211ENUM_resultcode_success;
0508 break;
0509 case WLAN_MSD_RUNNING:
0510
0511 result = P80211ENUM_resultcode_success;
0512 break;
0513 case WLAN_MSD_HWFAIL:
0514 default:
0515
0516
0517
0518 result = P80211ENUM_resultcode_implementation_failure;
0519 break;
0520 }
0521 break;
0522 case P80211ENUM_ifstate_disable:
0523 switch (wlandev->msdstate) {
0524 case WLAN_MSD_HWPRESENT:
0525
0526 result = P80211ENUM_resultcode_success;
0527 break;
0528 case WLAN_MSD_FWLOAD:
0529 case WLAN_MSD_RUNNING:
0530 wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
0531
0532
0533
0534
0535
0536
0537 if (!wlandev->hwremoved)
0538 netif_carrier_off(wlandev->netdev);
0539
0540 hfa384x_drvr_stop(hw);
0541
0542 wlandev->macmode = WLAN_MACMODE_NONE;
0543 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0544 result = P80211ENUM_resultcode_success;
0545 break;
0546 case WLAN_MSD_HWFAIL:
0547 default:
0548
0549
0550
0551 result = P80211ENUM_resultcode_implementation_failure;
0552 break;
0553 }
0554 break;
0555 default:
0556 result = P80211ENUM_resultcode_invalid_parameters;
0557 break;
0558 }
0559
0560 return result;
0561 }
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582 static int prism2sta_getcardinfo(struct wlandevice *wlandev)
0583 {
0584 int result = 0;
0585 struct hfa384x *hw = wlandev->priv;
0586 u16 temp;
0587 u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
0588 u8 addr[ETH_ALEN];
0589
0590
0591
0592
0593 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
0594 &hw->ident_nic,
0595 sizeof(struct hfa384x_compident));
0596 if (result) {
0597 netdev_err(wlandev->netdev, "Failed to retrieve NICIDENTITY\n");
0598 goto failed;
0599 }
0600
0601
0602 le16_to_cpus(&hw->ident_nic.id);
0603 le16_to_cpus(&hw->ident_nic.variant);
0604 le16_to_cpus(&hw->ident_nic.major);
0605 le16_to_cpus(&hw->ident_nic.minor);
0606
0607 netdev_info(wlandev->netdev, "ident: nic h/w: id=0x%02x %d.%d.%d\n",
0608 hw->ident_nic.id, hw->ident_nic.major,
0609 hw->ident_nic.minor, hw->ident_nic.variant);
0610
0611
0612 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
0613 &hw->ident_pri_fw,
0614 sizeof(struct hfa384x_compident));
0615 if (result) {
0616 netdev_err(wlandev->netdev, "Failed to retrieve PRIIDENTITY\n");
0617 goto failed;
0618 }
0619
0620
0621 le16_to_cpus(&hw->ident_pri_fw.id);
0622 le16_to_cpus(&hw->ident_pri_fw.variant);
0623 le16_to_cpus(&hw->ident_pri_fw.major);
0624 le16_to_cpus(&hw->ident_pri_fw.minor);
0625
0626 netdev_info(wlandev->netdev, "ident: pri f/w: id=0x%02x %d.%d.%d\n",
0627 hw->ident_pri_fw.id, hw->ident_pri_fw.major,
0628 hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
0629
0630
0631 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
0632 &hw->ident_sta_fw,
0633 sizeof(struct hfa384x_compident));
0634 if (result) {
0635 netdev_err(wlandev->netdev, "Failed to retrieve STAIDENTITY\n");
0636 goto failed;
0637 }
0638
0639 if (hw->ident_nic.id < 0x8000) {
0640 netdev_err(wlandev->netdev,
0641 "FATAL: Card is not an Intersil Prism2/2.5/3\n");
0642 result = -1;
0643 goto failed;
0644 }
0645
0646
0647 le16_to_cpus(&hw->ident_sta_fw.id);
0648 le16_to_cpus(&hw->ident_sta_fw.variant);
0649 le16_to_cpus(&hw->ident_sta_fw.major);
0650 le16_to_cpus(&hw->ident_sta_fw.minor);
0651
0652
0653 hw->mm_mods = hw->ident_sta_fw.variant & GENMASK(15, 14);
0654 hw->ident_sta_fw.variant &= ~((u16)GENMASK(15, 14));
0655
0656 if (hw->ident_sta_fw.id == 0x1f) {
0657 netdev_info(wlandev->netdev,
0658 "ident: sta f/w: id=0x%02x %d.%d.%d\n",
0659 hw->ident_sta_fw.id, hw->ident_sta_fw.major,
0660 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
0661 } else {
0662 netdev_info(wlandev->netdev,
0663 "ident: ap f/w: id=0x%02x %d.%d.%d\n",
0664 hw->ident_sta_fw.id, hw->ident_sta_fw.major,
0665 hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
0666 netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmware loaded!\n");
0667 goto failed;
0668 }
0669
0670
0671 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
0672 &hw->cap_sup_mfi,
0673 sizeof(struct hfa384x_caplevel));
0674 if (result) {
0675 netdev_err(wlandev->netdev, "Failed to retrieve MFISUPRANGE\n");
0676 goto failed;
0677 }
0678
0679
0680
0681
0682 le16_to_cpus(&hw->cap_sup_mfi.role);
0683 le16_to_cpus(&hw->cap_sup_mfi.id);
0684 le16_to_cpus(&hw->cap_sup_mfi.variant);
0685 le16_to_cpus(&hw->cap_sup_mfi.bottom);
0686 le16_to_cpus(&hw->cap_sup_mfi.top);
0687
0688 netdev_info(wlandev->netdev,
0689 "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0690 hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
0691 hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
0692 hw->cap_sup_mfi.top);
0693
0694
0695 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
0696 &hw->cap_sup_cfi,
0697 sizeof(struct hfa384x_caplevel));
0698 if (result) {
0699 netdev_err(wlandev->netdev, "Failed to retrieve CFISUPRANGE\n");
0700 goto failed;
0701 }
0702
0703
0704
0705
0706 le16_to_cpus(&hw->cap_sup_cfi.role);
0707 le16_to_cpus(&hw->cap_sup_cfi.id);
0708 le16_to_cpus(&hw->cap_sup_cfi.variant);
0709 le16_to_cpus(&hw->cap_sup_cfi.bottom);
0710 le16_to_cpus(&hw->cap_sup_cfi.top);
0711
0712 netdev_info(wlandev->netdev,
0713 "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0714 hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
0715 hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
0716 hw->cap_sup_cfi.top);
0717
0718
0719 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
0720 &hw->cap_sup_pri,
0721 sizeof(struct hfa384x_caplevel));
0722 if (result) {
0723 netdev_err(wlandev->netdev, "Failed to retrieve PRISUPRANGE\n");
0724 goto failed;
0725 }
0726
0727
0728
0729
0730 le16_to_cpus(&hw->cap_sup_pri.role);
0731 le16_to_cpus(&hw->cap_sup_pri.id);
0732 le16_to_cpus(&hw->cap_sup_pri.variant);
0733 le16_to_cpus(&hw->cap_sup_pri.bottom);
0734 le16_to_cpus(&hw->cap_sup_pri.top);
0735
0736 netdev_info(wlandev->netdev,
0737 "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0738 hw->cap_sup_pri.role, hw->cap_sup_pri.id,
0739 hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
0740 hw->cap_sup_pri.top);
0741
0742
0743 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
0744 &hw->cap_sup_sta,
0745 sizeof(struct hfa384x_caplevel));
0746 if (result) {
0747 netdev_err(wlandev->netdev, "Failed to retrieve STASUPRANGE\n");
0748 goto failed;
0749 }
0750
0751
0752
0753
0754 le16_to_cpus(&hw->cap_sup_sta.role);
0755 le16_to_cpus(&hw->cap_sup_sta.id);
0756 le16_to_cpus(&hw->cap_sup_sta.variant);
0757 le16_to_cpus(&hw->cap_sup_sta.bottom);
0758 le16_to_cpus(&hw->cap_sup_sta.top);
0759
0760 if (hw->cap_sup_sta.id == 0x04) {
0761 netdev_info(wlandev->netdev,
0762 "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0763 hw->cap_sup_sta.role, hw->cap_sup_sta.id,
0764 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
0765 hw->cap_sup_sta.top);
0766 } else {
0767 netdev_info(wlandev->netdev,
0768 "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0769 hw->cap_sup_sta.role, hw->cap_sup_sta.id,
0770 hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
0771 hw->cap_sup_sta.top);
0772 }
0773
0774
0775 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
0776 &hw->cap_act_pri_cfi,
0777 sizeof(struct hfa384x_caplevel));
0778 if (result) {
0779 netdev_err(wlandev->netdev, "Failed to retrieve PRI_CFIACTRANGES\n");
0780 goto failed;
0781 }
0782
0783
0784
0785
0786 le16_to_cpus(&hw->cap_act_pri_cfi.role);
0787 le16_to_cpus(&hw->cap_act_pri_cfi.id);
0788 le16_to_cpus(&hw->cap_act_pri_cfi.variant);
0789 le16_to_cpus(&hw->cap_act_pri_cfi.bottom);
0790 le16_to_cpus(&hw->cap_act_pri_cfi.top);
0791
0792 netdev_info(wlandev->netdev,
0793 "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0794 hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
0795 hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
0796 hw->cap_act_pri_cfi.top);
0797
0798
0799 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
0800 &hw->cap_act_sta_cfi,
0801 sizeof(struct hfa384x_caplevel));
0802 if (result) {
0803 netdev_err(wlandev->netdev, "Failed to retrieve STA_CFIACTRANGES\n");
0804 goto failed;
0805 }
0806
0807
0808
0809
0810 le16_to_cpus(&hw->cap_act_sta_cfi.role);
0811 le16_to_cpus(&hw->cap_act_sta_cfi.id);
0812 le16_to_cpus(&hw->cap_act_sta_cfi.variant);
0813 le16_to_cpus(&hw->cap_act_sta_cfi.bottom);
0814 le16_to_cpus(&hw->cap_act_sta_cfi.top);
0815
0816 netdev_info(wlandev->netdev,
0817 "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0818 hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
0819 hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
0820 hw->cap_act_sta_cfi.top);
0821
0822
0823 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
0824 &hw->cap_act_sta_mfi,
0825 sizeof(struct hfa384x_caplevel));
0826 if (result) {
0827 netdev_err(wlandev->netdev, "Failed to retrieve STA_MFIACTRANGES\n");
0828 goto failed;
0829 }
0830
0831
0832
0833
0834 le16_to_cpus(&hw->cap_act_sta_mfi.role);
0835 le16_to_cpus(&hw->cap_act_sta_mfi.id);
0836 le16_to_cpus(&hw->cap_act_sta_mfi.variant);
0837 le16_to_cpus(&hw->cap_act_sta_mfi.bottom);
0838 le16_to_cpus(&hw->cap_act_sta_mfi.top);
0839
0840 netdev_info(wlandev->netdev,
0841 "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
0842 hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
0843 hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
0844 hw->cap_act_sta_mfi.top);
0845
0846
0847 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
0848 snum, HFA384x_RID_NICSERIALNUMBER_LEN);
0849 if (!result) {
0850 netdev_info(wlandev->netdev, "Prism2 card SN: %*pE\n",
0851 HFA384x_RID_NICSERIALNUMBER_LEN, snum);
0852 } else {
0853 netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n");
0854 goto failed;
0855 }
0856
0857
0858 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
0859 addr, ETH_ALEN);
0860 if (result != 0) {
0861 netdev_err(wlandev->netdev, "Failed to retrieve mac address\n");
0862 goto failed;
0863 }
0864 eth_hw_addr_set(wlandev->netdev, addr);
0865
0866
0867 wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE;
0868
0869
0870 hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp);
0871 if (temp)
0872 wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP;
0873
0874
0875 hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp);
0876 hw->dbmadjust = temp;
0877
0878
0879 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
0880 hw->ident_sta_fw.minor,
0881 hw->ident_sta_fw.variant) <
0882 HFA384x_FIRMWARE_VERSION(1, 5, 5)) {
0883 wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
0884 }
0885
0886
0887
0888 goto done;
0889 failed:
0890 netdev_err(wlandev->netdev, "Failed, result=%d\n", result);
0891 done:
0892 return result;
0893 }
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913 static int prism2sta_globalsetup(struct wlandevice *wlandev)
0914 {
0915 struct hfa384x *hw = wlandev->priv;
0916
0917
0918 return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
0919 WLAN_DATA_MAXLEN);
0920 }
0921
0922 static int prism2sta_setmulticast(struct wlandevice *wlandev,
0923 struct net_device *dev)
0924 {
0925 int result = 0;
0926 struct hfa384x *hw = wlandev->priv;
0927
0928 u16 promisc;
0929
0930
0931 if (hw->state != HFA384x_STATE_RUNNING)
0932 goto exit;
0933
0934 if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
0935 promisc = P80211ENUM_truth_true;
0936 else
0937 promisc = P80211ENUM_truth_false;
0938
0939 result =
0940 hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE,
0941 promisc);
0942 exit:
0943 return result;
0944 }
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964 static void prism2sta_inf_handover(struct wlandevice *wlandev,
0965 struct hfa384x_inf_frame *inf)
0966 {
0967 pr_debug("received infoframe:HANDOVER (unhandled)\n");
0968 }
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987 static void prism2sta_inf_tallies(struct wlandevice *wlandev,
0988 struct hfa384x_inf_frame *inf)
0989 {
0990 struct hfa384x *hw = wlandev->priv;
0991 __le16 *src16;
0992 u32 *dst;
0993 __le32 *src32;
0994 int i;
0995 int cnt;
0996
0997
0998
0999
1000
1001
1002 cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32);
1003 if (inf->framelen > 22) {
1004 dst = (u32 *)&hw->tallies;
1005 src32 = (__le32 *)&inf->info.commtallies32;
1006 for (i = 0; i < cnt; i++, dst++, src32++)
1007 *dst += le32_to_cpu(*src32);
1008 } else {
1009 dst = (u32 *)&hw->tallies;
1010 src16 = (__le16 *)&inf->info.commtallies16;
1011 for (i = 0; i < cnt; i++, dst++, src16++)
1012 *dst += le16_to_cpu(*src16);
1013 }
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 static void prism2sta_inf_scanresults(struct wlandevice *wlandev,
1034 struct hfa384x_inf_frame *inf)
1035 {
1036 struct hfa384x *hw = wlandev->priv;
1037 int nbss;
1038 struct hfa384x_scan_result *sr = &inf->info.scanresult;
1039 int i;
1040 struct hfa384x_join_request_data joinreq;
1041 int result;
1042
1043
1044 nbss = (inf->framelen * sizeof(u16)) -
1045 sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason);
1046 nbss /= sizeof(struct hfa384x_scan_result_sub);
1047
1048
1049 pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
1050 inf->info.scanresult.scanreason, nbss);
1051 for (i = 0; i < nbss; i++) {
1052 pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n",
1053 sr->result[i].chid,
1054 sr->result[i].anl,
1055 sr->result[i].sl, sr->result[i].bcnint);
1056 pr_debug(" capinfo=0x%04x proberesp_rate=%d\n",
1057 sr->result[i].capinfo, sr->result[i].proberesp_rate);
1058 }
1059
1060 joinreq.channel = sr->result[0].chid;
1061 memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
1062 result = hfa384x_drvr_setconfig(hw,
1063 HFA384x_RID_JOINREQUEST,
1064 &joinreq, HFA384x_RID_JOINREQUEST_LEN);
1065 if (result) {
1066 netdev_err(wlandev->netdev, "setconfig(joinreq) failed, result=%d\n",
1067 result);
1068 }
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088 static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev,
1089 struct hfa384x_inf_frame *inf)
1090 {
1091 struct hfa384x *hw = wlandev->priv;
1092 int nbss;
1093
1094 nbss = (inf->framelen - 3) / 32;
1095 pr_debug("Received %d hostscan results\n", nbss);
1096
1097 if (nbss > 32)
1098 nbss = 32;
1099
1100 kfree(hw->scanresults);
1101
1102 hw->scanresults = kmemdup(inf, sizeof(*inf), GFP_ATOMIC);
1103
1104 if (nbss == 0)
1105 nbss = -1;
1106
1107
1108 hw->scanflag = nbss;
1109 wake_up_interruptible(&hw->cmdq);
1110 };
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
1130 struct hfa384x_inf_frame *inf)
1131 {
1132 struct hfa384x *hw = wlandev->priv;
1133 unsigned int i, n;
1134
1135 hw->channel_info.results.scanchannels =
1136 inf->info.chinforesult.scanchannels;
1137
1138 for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
1139 struct hfa384x_ch_info_result_sub *result;
1140 struct hfa384x_ch_info_result_sub *chinforesult;
1141 int chan;
1142
1143 if (!(hw->channel_info.results.scanchannels & (1 << i)))
1144 continue;
1145
1146 result = &inf->info.chinforesult.result[n];
1147 chan = result->chid - 1;
1148
1149 if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX)
1150 continue;
1151
1152 chinforesult = &hw->channel_info.results.result[chan];
1153 chinforesult->chid = chan;
1154 chinforesult->anl = result->anl;
1155 chinforesult->pnl = result->pnl;
1156 chinforesult->active = result->active;
1157
1158 pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
1159 chan + 1,
1160 (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE)
1161 ? "signal" : "noise",
1162 chinforesult->anl, chinforesult->pnl,
1163 (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE)
1164 ? 1 : 0);
1165 n++;
1166 }
1167 atomic_set(&hw->channel_info.done, 2);
1168
1169 hw->channel_info.count = n;
1170 }
1171
1172 void prism2sta_processing_defer(struct work_struct *data)
1173 {
1174 struct hfa384x *hw = container_of(data, struct hfa384x, link_bh);
1175 struct wlandevice *wlandev = hw->wlandev;
1176 struct hfa384x_bytestr32 ssid;
1177 int result;
1178
1179
1180 {
1181 struct sk_buff *skb;
1182 struct hfa384x_inf_frame *inf;
1183
1184 while ((skb = skb_dequeue(&hw->authq))) {
1185 inf = (struct hfa384x_inf_frame *)skb->data;
1186 prism2sta_inf_authreq_defer(wlandev, inf);
1187 }
1188 }
1189
1190
1191 if (hw->link_status == hw->link_status_new)
1192 return;
1193
1194 hw->link_status = hw->link_status_new;
1195
1196 switch (hw->link_status) {
1197 case HFA384x_LINK_NOTCONNECTED:
1198
1199
1200
1201
1202
1203
1204 netif_carrier_off(wlandev->netdev);
1205
1206 netdev_info(wlandev->netdev, "linkstatus=NOTCONNECTED (unhandled)\n");
1207 break;
1208
1209 case HFA384x_LINK_CONNECTED:
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 netif_carrier_on(wlandev->netdev);
1221
1222
1223
1224
1225 if (hw->join_ap == 1)
1226 hw->join_ap = 2;
1227 hw->join_retries = 60;
1228
1229
1230 if (wlandev->netdev->type == ARPHRD_ETHER) {
1231 u16 portstatus;
1232
1233 netdev_info(wlandev->netdev, "linkstatus=CONNECTED\n");
1234
1235
1236
1237
1238 result = hfa384x_drvr_getconfig(hw,
1239 HFA384x_RID_CURRENTBSSID,
1240 wlandev->bssid,
1241 WLAN_BSSID_LEN);
1242 if (result) {
1243 pr_debug
1244 ("getconfig(0x%02x) failed, result = %d\n",
1245 HFA384x_RID_CURRENTBSSID, result);
1246 return;
1247 }
1248
1249 result = hfa384x_drvr_getconfig(hw,
1250 HFA384x_RID_CURRENTSSID,
1251 &ssid, sizeof(ssid));
1252 if (result) {
1253 pr_debug
1254 ("getconfig(0x%02x) failed, result = %d\n",
1255 HFA384x_RID_CURRENTSSID, result);
1256 return;
1257 }
1258 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid,
1259 (struct p80211pstrd *)&wlandev->ssid);
1260
1261
1262 result = hfa384x_drvr_getconfig16(hw,
1263 HFA384x_RID_PORTSTATUS,
1264 &portstatus);
1265 if (result) {
1266 pr_debug
1267 ("getconfig(0x%02x) failed, result = %d\n",
1268 HFA384x_RID_PORTSTATUS, result);
1269 return;
1270 }
1271 wlandev->macmode =
1272 (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
1273 WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
1274
1275
1276 prism2_connect_result(wlandev, P80211ENUM_truth_false);
1277
1278
1279 prism2sta_commsqual_defer(&hw->commsqual_bh);
1280 }
1281 break;
1282
1283 case HFA384x_LINK_DISCONNECTED:
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293 if (wlandev->netdev->type == ARPHRD_ETHER)
1294 netdev_info(wlandev->netdev,
1295 "linkstatus=DISCONNECTED (unhandled)\n");
1296 wlandev->macmode = WLAN_MACMODE_NONE;
1297
1298 netif_carrier_off(wlandev->netdev);
1299
1300
1301 prism2_disconnected(wlandev);
1302
1303 break;
1304
1305 case HFA384x_LINK_AP_CHANGE:
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 netdev_info(wlandev->netdev, "linkstatus=AP_CHANGE\n");
1321
1322 result = hfa384x_drvr_getconfig(hw,
1323 HFA384x_RID_CURRENTBSSID,
1324 wlandev->bssid, WLAN_BSSID_LEN);
1325 if (result) {
1326 pr_debug("getconfig(0x%02x) failed, result = %d\n",
1327 HFA384x_RID_CURRENTBSSID, result);
1328 return;
1329 }
1330
1331 result = hfa384x_drvr_getconfig(hw,
1332 HFA384x_RID_CURRENTSSID,
1333 &ssid, sizeof(ssid));
1334 if (result) {
1335 pr_debug("getconfig(0x%02x) failed, result = %d\n",
1336 HFA384x_RID_CURRENTSSID, result);
1337 return;
1338 }
1339 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid,
1340 (struct p80211pstrd *)&wlandev->ssid);
1341
1342 hw->link_status = HFA384x_LINK_CONNECTED;
1343 netif_carrier_on(wlandev->netdev);
1344
1345
1346 prism2_roamed(wlandev);
1347
1348 break;
1349
1350 case HFA384x_LINK_AP_OUTOFRANGE:
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 netdev_info(wlandev->netdev, "linkstatus=AP_OUTOFRANGE (unhandled)\n");
1363
1364 netif_carrier_off(wlandev->netdev);
1365
1366 break;
1367
1368 case HFA384x_LINK_AP_INRANGE:
1369
1370
1371
1372
1373
1374
1375 netdev_info(wlandev->netdev, "linkstatus=AP_INRANGE\n");
1376
1377 hw->link_status = HFA384x_LINK_CONNECTED;
1378 netif_carrier_on(wlandev->netdev);
1379
1380 break;
1381
1382 case HFA384x_LINK_ASSOCFAIL:
1383
1384
1385
1386
1387
1388
1389
1390
1391 if (hw->join_ap && --hw->join_retries > 0) {
1392 struct hfa384x_join_request_data joinreq;
1393
1394 joinreq = hw->joinreq;
1395
1396 hfa384x_drvr_setconfig(hw,
1397 HFA384x_RID_JOINREQUEST,
1398 &joinreq,
1399 HFA384x_RID_JOINREQUEST_LEN);
1400 netdev_info(wlandev->netdev,
1401 "linkstatus=ASSOCFAIL (re-submitting join)\n");
1402 } else {
1403 netdev_info(wlandev->netdev, "linkstatus=ASSOCFAIL (unhandled)\n");
1404 }
1405
1406 netif_carrier_off(wlandev->netdev);
1407
1408
1409 prism2_connect_result(wlandev, P80211ENUM_truth_true);
1410
1411 break;
1412
1413 default:
1414
1415 netdev_warn(wlandev->netdev,
1416 "unknown linkstatus=0x%02x\n", hw->link_status);
1417 return;
1418 }
1419
1420 wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
1421 }
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440 static void prism2sta_inf_linkstatus(struct wlandevice *wlandev,
1441 struct hfa384x_inf_frame *inf)
1442 {
1443 struct hfa384x *hw = wlandev->priv;
1444
1445 hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
1446
1447 schedule_work(&hw->link_bh);
1448 }
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468 static void prism2sta_inf_assocstatus(struct wlandevice *wlandev,
1469 struct hfa384x_inf_frame *inf)
1470 {
1471 struct hfa384x *hw = wlandev->priv;
1472 struct hfa384x_assoc_status rec;
1473 int i;
1474
1475 memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
1476 le16_to_cpus(&rec.assocstatus);
1477 le16_to_cpus(&rec.reason);
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 for (i = 0; i < hw->authlist.cnt; i++)
1492 if (ether_addr_equal(rec.sta_addr, hw->authlist.addr[i]))
1493 break;
1494
1495 if (i >= hw->authlist.cnt) {
1496 if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
1497 netdev_warn(wlandev->netdev,
1498 "assocstatus info frame received for non-authenticated station.\n");
1499 } else {
1500 hw->authlist.assoc[i] =
1501 (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
1502 rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
1503
1504 if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
1505 netdev_warn(wlandev->netdev,
1506 "authfail assocstatus info frame received for authenticated station.\n");
1507 }
1508 }
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529 static void prism2sta_inf_authreq(struct wlandevice *wlandev,
1530 struct hfa384x_inf_frame *inf)
1531 {
1532 struct hfa384x *hw = wlandev->priv;
1533 struct sk_buff *skb;
1534
1535 skb = dev_alloc_skb(sizeof(*inf));
1536 if (skb) {
1537 skb_put(skb, sizeof(*inf));
1538 memcpy(skb->data, inf, sizeof(*inf));
1539 skb_queue_tail(&hw->authq, skb);
1540 schedule_work(&hw->link_bh);
1541 }
1542 }
1543
1544 static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
1545 struct hfa384x_inf_frame *inf)
1546 {
1547 struct hfa384x *hw = wlandev->priv;
1548 struct hfa384x_authenticate_station_data rec;
1549
1550 int i, added, result, cnt;
1551 u8 *addr;
1552
1553
1554
1555
1556
1557
1558 ether_addr_copy(rec.address, inf->info.authreq.sta_addr);
1559 rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure);
1560
1561
1562
1563
1564
1565 switch (hw->accessmode) {
1566 case WLAN_ACCESS_NONE:
1567
1568
1569
1570
1571
1572
1573 for (i = 0; i < hw->authlist.cnt; i++)
1574 if (ether_addr_equal(rec.address,
1575 hw->authlist.addr[i])) {
1576 rec.status = cpu_to_le16(P80211ENUM_status_successful);
1577 break;
1578 }
1579
1580 break;
1581
1582 case WLAN_ACCESS_ALL:
1583
1584
1585
1586
1587
1588 rec.status = cpu_to_le16(P80211ENUM_status_successful);
1589 break;
1590
1591 case WLAN_ACCESS_ALLOW:
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 if (hw->allow.modify == 0) {
1604 cnt = hw->allow.cnt;
1605 addr = hw->allow.addr[0];
1606 } else {
1607 cnt = hw->allow.cnt1;
1608 addr = hw->allow.addr1[0];
1609 }
1610
1611 for (i = 0; i < cnt; i++, addr += ETH_ALEN)
1612 if (ether_addr_equal(rec.address, addr)) {
1613 rec.status = cpu_to_le16(P80211ENUM_status_successful);
1614 break;
1615 }
1616
1617 break;
1618
1619 case WLAN_ACCESS_DENY:
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631 if (hw->deny.modify == 0) {
1632 cnt = hw->deny.cnt;
1633 addr = hw->deny.addr[0];
1634 } else {
1635 cnt = hw->deny.cnt1;
1636 addr = hw->deny.addr1[0];
1637 }
1638
1639 rec.status = cpu_to_le16(P80211ENUM_status_successful);
1640
1641 for (i = 0; i < cnt; i++, addr += ETH_ALEN)
1642 if (ether_addr_equal(rec.address, addr)) {
1643 rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure);
1644 break;
1645 }
1646
1647 break;
1648 }
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 added = 0;
1660
1661 if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) {
1662 for (i = 0; i < hw->authlist.cnt; i++)
1663 if (ether_addr_equal(rec.address,
1664 hw->authlist.addr[i]))
1665 break;
1666
1667 if (i >= hw->authlist.cnt) {
1668 if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
1669 rec.status = cpu_to_le16(P80211ENUM_status_ap_full);
1670 } else {
1671 ether_addr_copy(hw->authlist.addr[hw->authlist.cnt],
1672 rec.address);
1673 hw->authlist.cnt++;
1674 added = 1;
1675 }
1676 }
1677 }
1678
1679
1680
1681
1682
1683
1684
1685 rec.algorithm = inf->info.authreq.algorithm;
1686
1687 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
1688 &rec, sizeof(rec));
1689 if (result) {
1690 if (added)
1691 hw->authlist.cnt--;
1692 netdev_err(wlandev->netdev,
1693 "setconfig(authenticatestation) failed, result=%d\n",
1694 result);
1695 }
1696 }
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716 static void prism2sta_inf_psusercnt(struct wlandevice *wlandev,
1717 struct hfa384x_inf_frame *inf)
1718 {
1719 struct hfa384x *hw = wlandev->priv;
1720
1721 hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
1722 }
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741 void prism2sta_ev_info(struct wlandevice *wlandev,
1742 struct hfa384x_inf_frame *inf)
1743 {
1744 le16_to_cpus(&inf->infotype);
1745
1746 switch (inf->infotype) {
1747 case HFA384x_IT_HANDOVERADDR:
1748 prism2sta_inf_handover(wlandev, inf);
1749 break;
1750 case HFA384x_IT_COMMTALLIES:
1751 prism2sta_inf_tallies(wlandev, inf);
1752 break;
1753 case HFA384x_IT_HOSTSCANRESULTS:
1754 prism2sta_inf_hostscanresults(wlandev, inf);
1755 break;
1756 case HFA384x_IT_SCANRESULTS:
1757 prism2sta_inf_scanresults(wlandev, inf);
1758 break;
1759 case HFA384x_IT_CHINFORESULTS:
1760 prism2sta_inf_chinforesults(wlandev, inf);
1761 break;
1762 case HFA384x_IT_LINKSTATUS:
1763 prism2sta_inf_linkstatus(wlandev, inf);
1764 break;
1765 case HFA384x_IT_ASSOCSTATUS:
1766 prism2sta_inf_assocstatus(wlandev, inf);
1767 break;
1768 case HFA384x_IT_AUTHREQ:
1769 prism2sta_inf_authreq(wlandev, inf);
1770 break;
1771 case HFA384x_IT_PSUSERCNT:
1772 prism2sta_inf_psusercnt(wlandev, inf);
1773 break;
1774 case HFA384x_IT_KEYIDCHANGED:
1775 netdev_warn(wlandev->netdev, "Unhandled IT_KEYIDCHANGED\n");
1776 break;
1777 case HFA384x_IT_ASSOCREQ:
1778 netdev_warn(wlandev->netdev, "Unhandled IT_ASSOCREQ\n");
1779 break;
1780 case HFA384x_IT_MICFAILURE:
1781 netdev_warn(wlandev->netdev, "Unhandled IT_MICFAILURE\n");
1782 break;
1783 default:
1784 netdev_warn(wlandev->netdev,
1785 "Unknown info type=0x%02x\n", inf->infotype);
1786 break;
1787 }
1788 }
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809 void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status)
1810 {
1811 pr_debug("TxExc status=0x%x.\n", status);
1812 }
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830 void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status)
1831 {
1832 pr_debug("Tx Complete, status=0x%04x\n", status);
1833
1834 wlandev->netdev->stats.tx_packets++;
1835 }
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853 void prism2sta_ev_alloc(struct wlandevice *wlandev)
1854 {
1855 netif_wake_queue(wlandev->netdev);
1856 }
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877 static struct wlandevice *create_wlan(void)
1878 {
1879 struct wlandevice *wlandev = NULL;
1880 struct hfa384x *hw = NULL;
1881
1882
1883 wlandev = kzalloc(sizeof(*wlandev), GFP_KERNEL);
1884 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
1885
1886 if (!wlandev || !hw) {
1887 kfree(wlandev);
1888 kfree(hw);
1889 return NULL;
1890 }
1891
1892
1893 wlandev->nsdname = dev_info;
1894 wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
1895 wlandev->priv = hw;
1896 wlandev->open = prism2sta_open;
1897 wlandev->close = prism2sta_close;
1898 wlandev->reset = prism2sta_reset;
1899 wlandev->txframe = prism2sta_txframe;
1900 wlandev->mlmerequest = prism2sta_mlmerequest;
1901 wlandev->set_multicast_list = prism2sta_setmulticast;
1902 wlandev->tx_timeout = hfa384x_tx_timeout;
1903
1904 wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN;
1905
1906
1907 hw->dot11_desired_bss_type = 1;
1908
1909 return wlandev;
1910 }
1911
1912 void prism2sta_commsqual_defer(struct work_struct *data)
1913 {
1914 struct hfa384x *hw = container_of(data, struct hfa384x, commsqual_bh);
1915 struct wlandevice *wlandev = hw->wlandev;
1916 struct hfa384x_bytestr32 ssid;
1917 struct p80211msg_dot11req_mibget msg;
1918 struct p80211item_uint32 *mibitem = (struct p80211item_uint32 *)
1919 &msg.mibattribute.data;
1920 int result = 0;
1921
1922 if (hw->wlandev->hwremoved)
1923 return;
1924
1925
1926 if ((wlandev->macmode == WLAN_MACMODE_NONE) ||
1927 (wlandev->macmode == WLAN_MACMODE_ESS_AP)) {
1928 return;
1929 }
1930
1931
1932 if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) {
1933 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY,
1934 &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN);
1935
1936 if (result) {
1937 netdev_err(wlandev->netdev, "error fetching commsqual\n");
1938 return;
1939 }
1940
1941 pr_debug("commsqual %d %d %d\n",
1942 le16_to_cpu(hw->qual.cq_curr_bss),
1943 le16_to_cpu(hw->qual.asl_curr_bss),
1944 le16_to_cpu(hw->qual.anl_curr_fc));
1945 }
1946
1947
1948 msg.msgcode = DIDMSG_DOT11REQ_MIBGET;
1949 mibitem->did = DIDMIB_P2_MAC_CURRENTTXRATE;
1950 result = p80211req_dorequest(wlandev, (u8 *)&msg);
1951
1952 if (result) {
1953 pr_debug("get signal rate failed, result = %d\n",
1954 result);
1955 return;
1956 }
1957
1958 switch (mibitem->data) {
1959 case HFA384x_RATEBIT_1:
1960 hw->txrate = 10;
1961 break;
1962 case HFA384x_RATEBIT_2:
1963 hw->txrate = 20;
1964 break;
1965 case HFA384x_RATEBIT_5dot5:
1966 hw->txrate = 55;
1967 break;
1968 case HFA384x_RATEBIT_11:
1969 hw->txrate = 110;
1970 break;
1971 default:
1972 pr_debug("Bad ratebit (%d)\n", mibitem->data);
1973 }
1974
1975
1976 result = hfa384x_drvr_getconfig(hw,
1977 HFA384x_RID_CURRENTBSSID,
1978 wlandev->bssid, WLAN_BSSID_LEN);
1979 if (result) {
1980 pr_debug("getconfig(0x%02x) failed, result = %d\n",
1981 HFA384x_RID_CURRENTBSSID, result);
1982 return;
1983 }
1984
1985 result = hfa384x_drvr_getconfig(hw,
1986 HFA384x_RID_CURRENTSSID,
1987 &ssid, sizeof(ssid));
1988 if (result) {
1989 pr_debug("getconfig(0x%02x) failed, result = %d\n",
1990 HFA384x_RID_CURRENTSSID, result);
1991 return;
1992 }
1993 prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid,
1994 (struct p80211pstrd *)&wlandev->ssid);
1995
1996
1997 mod_timer(&hw->commsqual_timer, jiffies + HZ);
1998 }
1999
2000 void prism2sta_commsqual_timer(struct timer_list *t)
2001 {
2002 struct hfa384x *hw = from_timer(hw, t, commsqual_timer);
2003
2004 schedule_work(&hw->commsqual_bh);
2005 }