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
0055
0056
0057
0058
0059
0060
0061 #include <linux/if_arp.h>
0062 #include <linux/module.h>
0063 #include <linux/kernel.h>
0064 #include <linux/wait.h>
0065 #include <linux/sched.h>
0066 #include <linux/types.h>
0067 #include <linux/wireless.h>
0068 #include <linux/netdevice.h>
0069 #include <linux/delay.h>
0070 #include <linux/io.h>
0071 #include <asm/byteorder.h>
0072 #include <linux/random.h>
0073 #include <linux/usb.h>
0074 #include <linux/bitops.h>
0075
0076 #include "p80211types.h"
0077 #include "p80211hdr.h"
0078 #include "p80211mgmt.h"
0079 #include "p80211conv.h"
0080 #include "p80211msg.h"
0081 #include "p80211netdev.h"
0082 #include "p80211metadef.h"
0083 #include "p80211metastruct.h"
0084 #include "hfa384x.h"
0085 #include "prism2mgmt.h"
0086
0087
0088 static inline u16 p80211rate_to_p2bit(u32 rate)
0089 {
0090 switch (rate & ~BIT(7)) {
0091 case 2:
0092 return BIT(0);
0093 case 4:
0094 return BIT(1);
0095 case 11:
0096 return BIT(2);
0097 case 22:
0098 return BIT(3);
0099 default:
0100 return 0;
0101 }
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp)
0130 {
0131 int result = 0;
0132 struct hfa384x *hw = wlandev->priv;
0133 struct p80211msg_dot11req_scan *msg = msgp;
0134 u16 roamingmode, word;
0135 int i, timeout;
0136 int istmpenable = 0;
0137
0138 struct hfa384x_host_scan_request_data scanreq;
0139
0140
0141 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
0142 hw->ident_sta_fw.minor,
0143 hw->ident_sta_fw.variant) <
0144 HFA384x_FIRMWARE_VERSION(1, 3, 2)) {
0145 netdev_err(wlandev->netdev,
0146 "HostScan not supported with current firmware (<1.3.2).\n");
0147 result = 1;
0148 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
0149 goto exit;
0150 }
0151
0152 memset(&scanreq, 0, sizeof(scanreq));
0153
0154
0155 result = hfa384x_drvr_getconfig16(hw,
0156 HFA384x_RID_CNFROAMINGMODE,
0157 &roamingmode);
0158 if (result) {
0159 netdev_err(wlandev->netdev,
0160 "getconfig(ROAMMODE) failed. result=%d\n", result);
0161 msg->resultcode.data =
0162 P80211ENUM_resultcode_implementation_failure;
0163 goto exit;
0164 }
0165
0166
0167 result = hfa384x_drvr_setconfig16(hw,
0168 HFA384x_RID_CNFROAMINGMODE,
0169 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
0170 if (result) {
0171 netdev_err(wlandev->netdev,
0172 "setconfig(ROAMINGMODE) failed. result=%d\n",
0173 result);
0174 msg->resultcode.data =
0175 P80211ENUM_resultcode_implementation_failure;
0176 goto exit;
0177 }
0178
0179
0180 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
0181 hw->ident_sta_fw.minor,
0182 hw->ident_sta_fw.variant) >
0183 HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
0184 if (msg->scantype.data != P80211ENUM_scantype_active)
0185 word = msg->maxchanneltime.data;
0186 else
0187 word = 0;
0188
0189 result =
0190 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
0191 word);
0192 if (result) {
0193 netdev_warn(wlandev->netdev,
0194 "Passive scan not supported with current firmware. (<1.5.1)\n");
0195 }
0196 }
0197
0198
0199 word = HFA384x_RATEBIT_2;
0200 scanreq.tx_rate = cpu_to_le16(word);
0201
0202
0203 word = 0;
0204 for (i = 0; i < msg->channellist.data.len; i++) {
0205 u8 channel = msg->channellist.data.data[i];
0206
0207 if (channel > 14)
0208 continue;
0209
0210 word |= (1 << (channel - 1));
0211 }
0212 scanreq.channel_list = cpu_to_le16(word);
0213
0214
0215 scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len);
0216 memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
0217
0218
0219 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
0220 if (result) {
0221 netdev_err(wlandev->netdev,
0222 "getconfig(PORTSTATUS) failed. result=%d\n", result);
0223 msg->resultcode.data =
0224 P80211ENUM_resultcode_implementation_failure;
0225 goto exit;
0226 }
0227 if (word == HFA384x_PORTSTATUS_DISABLED) {
0228 __le16 wordbuf[17];
0229
0230 result = hfa384x_drvr_setconfig16(hw,
0231 HFA384x_RID_CNFROAMINGMODE,
0232 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
0233 if (result) {
0234 netdev_err(wlandev->netdev,
0235 "setconfig(ROAMINGMODE) failed. result=%d\n",
0236 result);
0237 msg->resultcode.data =
0238 P80211ENUM_resultcode_implementation_failure;
0239 goto exit;
0240 }
0241
0242
0243
0244 wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN);
0245 get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
0246 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
0247 wordbuf,
0248 HFA384x_RID_CNFOWNSSID_LEN);
0249 if (result) {
0250 netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n");
0251 msg->resultcode.data =
0252 P80211ENUM_resultcode_implementation_failure;
0253 goto exit;
0254 }
0255 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
0256 wordbuf,
0257 HFA384x_RID_CNFDESIREDSSID_LEN);
0258 if (result) {
0259 netdev_err(wlandev->netdev,
0260 "Failed to set DesiredSSID.\n");
0261 msg->resultcode.data =
0262 P80211ENUM_resultcode_implementation_failure;
0263 goto exit;
0264 }
0265
0266 result = hfa384x_drvr_setconfig16(hw,
0267 HFA384x_RID_CNFPORTTYPE,
0268 HFA384x_PORTTYPE_IBSS);
0269 if (result) {
0270 netdev_err(wlandev->netdev,
0271 "Failed to set CNFPORTTYPE.\n");
0272 msg->resultcode.data =
0273 P80211ENUM_resultcode_implementation_failure;
0274 goto exit;
0275 }
0276
0277 result = hfa384x_drvr_setconfig16(hw,
0278 HFA384x_RID_CREATEIBSS,
0279 HFA384x_CREATEIBSS_JOINCREATEIBSS);
0280 if (result) {
0281 netdev_err(wlandev->netdev,
0282 "Failed to set CREATEIBSS.\n");
0283 msg->resultcode.data =
0284 P80211ENUM_resultcode_implementation_failure;
0285 goto exit;
0286 }
0287 result = hfa384x_drvr_enable(hw, 0);
0288 if (result) {
0289 netdev_err(wlandev->netdev,
0290 "drvr_enable(0) failed. result=%d\n",
0291 result);
0292 msg->resultcode.data =
0293 P80211ENUM_resultcode_implementation_failure;
0294 goto exit;
0295 }
0296 istmpenable = 1;
0297 }
0298
0299
0300 timeout = msg->channellist.data.len * msg->maxchanneltime.data;
0301 timeout = (timeout * HZ) / 1000;
0302
0303
0304 hw->scanflag = 0;
0305
0306 result = hfa384x_drvr_setconfig(hw,
0307 HFA384x_RID_HOSTSCAN, &scanreq,
0308 sizeof(scanreq));
0309 if (result) {
0310 netdev_err(wlandev->netdev,
0311 "setconfig(SCANREQUEST) failed. result=%d\n",
0312 result);
0313 msg->resultcode.data =
0314 P80211ENUM_resultcode_implementation_failure;
0315 goto exit;
0316 }
0317
0318
0319 wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
0320
0321 msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
0322 if (hw->scanflag == -1)
0323 hw->scanflag = 0;
0324
0325 msg->numbss.data = hw->scanflag;
0326
0327 hw->scanflag = 0;
0328
0329
0330 if (istmpenable) {
0331 result = hfa384x_drvr_disable(hw, 0);
0332 if (result) {
0333 netdev_err(wlandev->netdev,
0334 "drvr_disable(0) failed. result=%d\n",
0335 result);
0336 msg->resultcode.data =
0337 P80211ENUM_resultcode_implementation_failure;
0338 goto exit;
0339 }
0340 }
0341
0342
0343 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
0344 roamingmode);
0345 if (result) {
0346 netdev_err(wlandev->netdev,
0347 "setconfig(ROAMMODE) failed. result=%d\n", result);
0348 msg->resultcode.data =
0349 P80211ENUM_resultcode_implementation_failure;
0350 goto exit;
0351 }
0352
0353 result = 0;
0354 msg->resultcode.data = P80211ENUM_resultcode_success;
0355
0356 exit:
0357 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0358
0359 return result;
0360 }
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp)
0384 {
0385 int result = 0;
0386 struct p80211msg_dot11req_scan_results *req;
0387 struct hfa384x *hw = wlandev->priv;
0388 struct hfa384x_hscan_result_sub *item = NULL;
0389
0390 int count;
0391
0392 req = msgp;
0393
0394 req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0395
0396 if (!hw->scanresults) {
0397 netdev_err(wlandev->netdev,
0398 "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
0399 result = 2;
0400 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
0401 goto exit;
0402 }
0403
0404 count = (hw->scanresults->framelen - 3) / 32;
0405 if (count > HFA384x_SCANRESULT_MAX)
0406 count = HFA384x_SCANRESULT_MAX;
0407
0408 if (req->bssindex.data >= count) {
0409 netdev_dbg(wlandev->netdev,
0410 "requested index (%d) out of range (%d)\n",
0411 req->bssindex.data, count);
0412 result = 2;
0413 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
0414 goto exit;
0415 }
0416
0417 item = &hw->scanresults->info.hscanresult.result[req->bssindex.data];
0418
0419 req->signal.status = P80211ENUM_msgitem_status_data_ok;
0420 req->noise.status = P80211ENUM_msgitem_status_data_ok;
0421 req->signal.data = le16_to_cpu(item->sl);
0422 req->noise.data = le16_to_cpu(item->anl);
0423
0424
0425 req->bssid.status = P80211ENUM_msgitem_status_data_ok;
0426 req->bssid.data.len = WLAN_BSSID_LEN;
0427 memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
0428
0429
0430 req->ssid.status = P80211ENUM_msgitem_status_data_ok;
0431 req->ssid.data.len = le16_to_cpu(item->ssid.len);
0432 req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN);
0433 memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
0434
0435
0436 for (count = 0; count < 10; count++)
0437 if (item->supprates[count] == 0)
0438 break;
0439
0440 #define REQBASICRATE(N) \
0441 do { \
0442 if ((count >= (N)) && DOT11_RATE5_ISBASIC_GET( \
0443 item->supprates[(N) - 1])) { \
0444 req->basicrate ## N .data = item->supprates[(N) - 1]; \
0445 req->basicrate ## N .status = \
0446 P80211ENUM_msgitem_status_data_ok; \
0447 } \
0448 } while (0)
0449
0450 REQBASICRATE(1);
0451 REQBASICRATE(2);
0452 REQBASICRATE(3);
0453 REQBASICRATE(4);
0454 REQBASICRATE(5);
0455 REQBASICRATE(6);
0456 REQBASICRATE(7);
0457 REQBASICRATE(8);
0458
0459 #define REQSUPPRATE(N) \
0460 do { \
0461 if (count >= (N)) { \
0462 req->supprate ## N .data = item->supprates[(N) - 1]; \
0463 req->supprate ## N .status = \
0464 P80211ENUM_msgitem_status_data_ok; \
0465 } \
0466 } while (0)
0467
0468 REQSUPPRATE(1);
0469 REQSUPPRATE(2);
0470 REQSUPPRATE(3);
0471 REQSUPPRATE(4);
0472 REQSUPPRATE(5);
0473 REQSUPPRATE(6);
0474 REQSUPPRATE(7);
0475 REQSUPPRATE(8);
0476
0477
0478 req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
0479 req->beaconperiod.data = le16_to_cpu(item->bcnint);
0480
0481
0482 req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
0483 req->timestamp.data = jiffies;
0484 req->localtime.status = P80211ENUM_msgitem_status_data_ok;
0485 req->localtime.data = jiffies;
0486
0487
0488 req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
0489 req->ibssatimwindow.data = le16_to_cpu(item->atim);
0490
0491
0492 req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
0493 req->dschannel.data = le16_to_cpu(item->chid);
0494
0495
0496 count = le16_to_cpu(item->capinfo);
0497 req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
0498 req->capinfo.data = count;
0499
0500
0501 req->privacy.status = P80211ENUM_msgitem_status_data_ok;
0502 req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
0503
0504
0505 req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
0506 req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
0507
0508
0509 req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
0510 req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
0511
0512
0513 req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
0514 req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
0515 P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
0516
0517 result = 0;
0518 req->resultcode.data = P80211ENUM_resultcode_success;
0519
0520 exit:
0521 return result;
0522 }
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 int prism2mgmt_start(struct wlandevice *wlandev, void *msgp)
0545 {
0546 int result = 0;
0547 struct hfa384x *hw = wlandev->priv;
0548 struct p80211msg_dot11req_start *msg = msgp;
0549
0550 struct p80211pstrd *pstr;
0551 u8 bytebuf[80];
0552 struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
0553 u16 word;
0554
0555 wlandev->macmode = WLAN_MACMODE_NONE;
0556
0557
0558 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
0559
0560
0561
0562 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
0563 hw->ident_sta_fw.minor,
0564 hw->ident_sta_fw.variant) <
0565 HFA384x_FIRMWARE_VERSION(0, 8, 3)) {
0566
0567 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0568 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
0569 goto done;
0570 }
0571
0572 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0573
0574
0575
0576
0577 pstr = (struct p80211pstrd *)&msg->ssid.data;
0578 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
0579 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
0580 bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
0581 if (result) {
0582 netdev_err(wlandev->netdev, "Failed to set CnfOwnSSID\n");
0583 goto failed;
0584 }
0585 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
0586 bytebuf,
0587 HFA384x_RID_CNFDESIREDSSID_LEN);
0588 if (result) {
0589 netdev_err(wlandev->netdev, "Failed to set CnfDesiredSSID\n");
0590 goto failed;
0591 }
0592
0593
0594
0595 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
0596
0597
0598 word = msg->beaconperiod.data;
0599 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
0600 if (result) {
0601 netdev_err(wlandev->netdev,
0602 "Failed to set beacon period=%d.\n", word);
0603 goto failed;
0604 }
0605
0606
0607 word = msg->dschannel.data;
0608 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
0609 if (result) {
0610 netdev_err(wlandev->netdev,
0611 "Failed to set channel=%d.\n", word);
0612 goto failed;
0613 }
0614
0615 word = p80211rate_to_p2bit(msg->basicrate1.data);
0616 if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok)
0617 word |= p80211rate_to_p2bit(msg->basicrate2.data);
0618
0619 if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok)
0620 word |= p80211rate_to_p2bit(msg->basicrate3.data);
0621
0622 if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok)
0623 word |= p80211rate_to_p2bit(msg->basicrate4.data);
0624
0625 if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok)
0626 word |= p80211rate_to_p2bit(msg->basicrate5.data);
0627
0628 if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok)
0629 word |= p80211rate_to_p2bit(msg->basicrate6.data);
0630
0631 if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok)
0632 word |= p80211rate_to_p2bit(msg->basicrate7.data);
0633
0634 if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok)
0635 word |= p80211rate_to_p2bit(msg->basicrate8.data);
0636
0637 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
0638 if (result) {
0639 netdev_err(wlandev->netdev,
0640 "Failed to set basicrates=%d.\n", word);
0641 goto failed;
0642 }
0643
0644
0645 word = p80211rate_to_p2bit(msg->operationalrate1.data);
0646 if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok)
0647 word |= p80211rate_to_p2bit(msg->operationalrate2.data);
0648
0649 if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok)
0650 word |= p80211rate_to_p2bit(msg->operationalrate3.data);
0651
0652 if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok)
0653 word |= p80211rate_to_p2bit(msg->operationalrate4.data);
0654
0655 if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok)
0656 word |= p80211rate_to_p2bit(msg->operationalrate5.data);
0657
0658 if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok)
0659 word |= p80211rate_to_p2bit(msg->operationalrate6.data);
0660
0661 if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok)
0662 word |= p80211rate_to_p2bit(msg->operationalrate7.data);
0663
0664 if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok)
0665 word |= p80211rate_to_p2bit(msg->operationalrate8.data);
0666
0667 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
0668 if (result) {
0669 netdev_err(wlandev->netdev,
0670 "Failed to set supprates=%d.\n", word);
0671 goto failed;
0672 }
0673
0674 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
0675 if (result) {
0676 netdev_err(wlandev->netdev, "Failed to set txrates=%d.\n",
0677 word);
0678 goto failed;
0679 }
0680
0681
0682 if (msg->bsstype.data == P80211ENUM_bsstype_independent) {
0683 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
0684
0685 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
0686 }
0687
0688
0689 result = hfa384x_drvr_enable(hw, 0);
0690 if (result) {
0691 netdev_err(wlandev->netdev,
0692 "Enable macport failed, result=%d.\n", result);
0693 goto failed;
0694 }
0695
0696 msg->resultcode.data = P80211ENUM_resultcode_success;
0697
0698 goto done;
0699 failed:
0700 netdev_dbg(wlandev->netdev,
0701 "Failed to set a config option, result=%d\n", result);
0702 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
0703
0704 done:
0705 return 0;
0706 }
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727 int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp)
0728 {
0729 struct hfa384x *hw = wlandev->priv;
0730 struct p80211msg_p2req_readpda *msg = msgp;
0731 int result;
0732
0733
0734
0735
0736 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
0737 netdev_err(wlandev->netdev,
0738 "PDA may only be read in the fwload state.\n");
0739 msg->resultcode.data =
0740 P80211ENUM_resultcode_implementation_failure;
0741 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0742 } else {
0743
0744
0745
0746 result = hfa384x_drvr_readpda(hw,
0747 msg->pda.data,
0748 HFA384x_PDA_LEN_MAX);
0749 if (result) {
0750 netdev_err(wlandev->netdev,
0751 "hfa384x_drvr_readpda() failed, result=%d\n",
0752 result);
0753
0754 msg->resultcode.data =
0755 P80211ENUM_resultcode_implementation_failure;
0756 msg->resultcode.status =
0757 P80211ENUM_msgitem_status_data_ok;
0758 return 0;
0759 }
0760 msg->pda.status = P80211ENUM_msgitem_status_data_ok;
0761 msg->resultcode.data = P80211ENUM_resultcode_success;
0762 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0763 }
0764
0765 return 0;
0766 }
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794 int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp)
0795 {
0796 struct hfa384x *hw = wlandev->priv;
0797 struct p80211msg_p2req_ramdl_state *msg = msgp;
0798
0799 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
0800 netdev_err(wlandev->netdev,
0801 "ramdl_state(): may only be called in the fwload state.\n");
0802 msg->resultcode.data =
0803 P80211ENUM_resultcode_implementation_failure;
0804 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0805 return 0;
0806 }
0807
0808
0809
0810
0811
0812
0813 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0814 if (msg->enable.data == P80211ENUM_truth_true) {
0815 if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) {
0816 msg->resultcode.data =
0817 P80211ENUM_resultcode_implementation_failure;
0818 } else {
0819 msg->resultcode.data = P80211ENUM_resultcode_success;
0820 }
0821 } else {
0822 hfa384x_drvr_ramdl_disable(hw);
0823 msg->resultcode.data = P80211ENUM_resultcode_success;
0824 }
0825
0826 return 0;
0827 }
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850 int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp)
0851 {
0852 struct hfa384x *hw = wlandev->priv;
0853 struct p80211msg_p2req_ramdl_write *msg = msgp;
0854 u32 addr;
0855 u32 len;
0856 u8 *buf;
0857
0858 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
0859 netdev_err(wlandev->netdev,
0860 "ramdl_write(): may only be called in the fwload state.\n");
0861 msg->resultcode.data =
0862 P80211ENUM_resultcode_implementation_failure;
0863 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0864 return 0;
0865 }
0866
0867 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0868
0869 if (msg->len.data > sizeof(msg->data.data)) {
0870 msg->resultcode.status =
0871 P80211ENUM_resultcode_invalid_parameters;
0872 return 0;
0873 }
0874
0875 addr = msg->addr.data;
0876 len = msg->len.data;
0877 buf = msg->data.data;
0878 if (hfa384x_drvr_ramdl_write(hw, addr, buf, len))
0879 msg->resultcode.data = P80211ENUM_resultcode_refused;
0880
0881 msg->resultcode.data = P80211ENUM_resultcode_success;
0882
0883 return 0;
0884 }
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912 int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
0913 {
0914 int result = 0;
0915 struct hfa384x *hw = wlandev->priv;
0916 struct p80211msg_p2req_flashdl_state *msg = msgp;
0917
0918 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
0919 netdev_err(wlandev->netdev,
0920 "flashdl_state(): may only be called in the fwload state.\n");
0921 msg->resultcode.data =
0922 P80211ENUM_resultcode_implementation_failure;
0923 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0924 return 0;
0925 }
0926
0927
0928
0929
0930
0931
0932 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0933 if (msg->enable.data == P80211ENUM_truth_true) {
0934 if (hfa384x_drvr_flashdl_enable(hw)) {
0935 msg->resultcode.data =
0936 P80211ENUM_resultcode_implementation_failure;
0937 } else {
0938 msg->resultcode.data = P80211ENUM_resultcode_success;
0939 }
0940 } else {
0941 hfa384x_drvr_flashdl_disable(hw);
0942 msg->resultcode.data = P80211ENUM_resultcode_success;
0943
0944
0945
0946
0947
0948
0949
0950 wlandev->msdstate = WLAN_MSD_HWPRESENT;
0951 result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
0952 if (result != P80211ENUM_resultcode_success) {
0953 netdev_err(wlandev->netdev,
0954 "prism2sta_ifstate(fwload) failed, P80211ENUM_resultcode=%d\n",
0955 result);
0956 msg->resultcode.data =
0957 P80211ENUM_resultcode_implementation_failure;
0958 result = -1;
0959 }
0960 }
0961
0962 return result;
0963 }
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984 int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp)
0985 {
0986 struct hfa384x *hw = wlandev->priv;
0987 struct p80211msg_p2req_flashdl_write *msg = msgp;
0988 u32 addr;
0989 u32 len;
0990 u8 *buf;
0991
0992 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
0993 netdev_err(wlandev->netdev,
0994 "flashdl_write(): may only be called in the fwload state.\n");
0995 msg->resultcode.data =
0996 P80211ENUM_resultcode_implementation_failure;
0997 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
0998 return 0;
0999 }
1000
1001
1002
1003
1004
1005
1006 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1007
1008 if (msg->len.data > sizeof(msg->data.data)) {
1009 msg->resultcode.status =
1010 P80211ENUM_resultcode_invalid_parameters;
1011 return 0;
1012 }
1013
1014 addr = msg->addr.data;
1015 len = msg->len.data;
1016 buf = msg->data.data;
1017 if (hfa384x_drvr_flashdl_write(hw, addr, buf, len))
1018 msg->resultcode.data = P80211ENUM_resultcode_refused;
1019
1020 msg->resultcode.data = P80211ENUM_resultcode_success;
1021
1022 return 0;
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp)
1046 {
1047 struct hfa384x *hw = wlandev->priv;
1048 int result = 0;
1049 u16 reg;
1050 u16 port_type;
1051 struct p80211msg_lnxreq_autojoin *msg = msgp;
1052 struct p80211pstrd *pstr;
1053 u8 bytebuf[256];
1054 struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
1055
1056 wlandev->macmode = WLAN_MACMODE_NONE;
1057
1058
1059 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
1060
1061
1062 hfa384x_drvr_disable(hw, 0);
1063
1064
1065
1066 hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
1067
1068
1069 if (msg->authtype.data == P80211ENUM_authalg_sharedkey)
1070 reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
1071 else
1072 reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
1073
1074 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
1075
1076
1077 memset(bytebuf, 0, 256);
1078 pstr = (struct p80211pstrd *)&msg->ssid.data;
1079 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
1080 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
1081 bytebuf,
1082 HFA384x_RID_CNFDESIREDSSID_LEN);
1083 port_type = HFA384x_PORTTYPE_BSS;
1084
1085 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
1086
1087
1088 hfa384x_drvr_enable(hw, 0);
1089
1090
1091 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1092 msg->resultcode.data = P80211ENUM_resultcode_success;
1093
1094 return result;
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117 int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp)
1118 {
1119 int result = 0;
1120 struct p80211msg_lnxreq_wlansniff *msg = msgp;
1121
1122 struct hfa384x *hw = wlandev->priv;
1123 u16 word;
1124
1125 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1126 switch (msg->enable.data) {
1127 case P80211ENUM_truth_false:
1128
1129 if (wlandev->netdev->type == ARPHRD_ETHER) {
1130 msg->resultcode.data =
1131 P80211ENUM_resultcode_invalid_parameters;
1132 return 0;
1133 }
1134
1135 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
1136 if (result) {
1137 netdev_dbg(wlandev->netdev,
1138 "failed to disable monitor mode, result=%d\n",
1139 result);
1140 goto failed;
1141 }
1142
1143 result = hfa384x_drvr_disable(hw, 0);
1144 if (result) {
1145 netdev_dbg
1146 (wlandev->netdev,
1147 "failed to disable port 0 after sniffing, result=%d\n",
1148 result);
1149 goto failed;
1150 }
1151
1152 wlandev->netdev->type = ARPHRD_ETHER;
1153
1154
1155 result = hfa384x_drvr_setconfig16(hw,
1156 HFA384x_RID_CNFWEPFLAGS,
1157 hw->presniff_wepflags);
1158 if (result) {
1159 netdev_dbg
1160 (wlandev->netdev,
1161 "failed to restore wepflags=0x%04x, result=%d\n",
1162 hw->presniff_wepflags, result);
1163 goto failed;
1164 }
1165
1166
1167 if (hw->presniff_port_type != 0) {
1168 word = hw->presniff_port_type;
1169 result = hfa384x_drvr_setconfig16(hw,
1170 HFA384x_RID_CNFPORTTYPE,
1171 word);
1172 if (result) {
1173 netdev_dbg
1174 (wlandev->netdev,
1175 "failed to restore porttype, result=%d\n",
1176 result);
1177 goto failed;
1178 }
1179
1180
1181 result = hfa384x_drvr_enable(hw, 0);
1182 if (result) {
1183 netdev_dbg(wlandev->netdev,
1184 "failed to enable port to presniff setting, result=%d\n",
1185 result);
1186 goto failed;
1187 }
1188 } else {
1189 result = hfa384x_drvr_disable(hw, 0);
1190 }
1191
1192 netdev_info(wlandev->netdev, "monitor mode disabled\n");
1193 msg->resultcode.data = P80211ENUM_resultcode_success;
1194 return 0;
1195 case P80211ENUM_truth_true:
1196
1197 if (hw->port_enabled[0]) {
1198 if (wlandev->netdev->type == ARPHRD_ETHER) {
1199
1200 result = hfa384x_drvr_getconfig16(hw,
1201 HFA384x_RID_CNFPORTTYPE,
1202 &hw->presniff_port_type);
1203 if (result) {
1204 netdev_dbg
1205 (wlandev->netdev,
1206 "failed to read porttype, result=%d\n",
1207 result);
1208 goto failed;
1209 }
1210
1211 result = hfa384x_drvr_getconfig16(hw,
1212 HFA384x_RID_CNFWEPFLAGS,
1213 &hw->presniff_wepflags);
1214 if (result) {
1215 netdev_dbg
1216 (wlandev->netdev,
1217 "failed to read wepflags, result=%d\n",
1218 result);
1219 goto failed;
1220 }
1221 hfa384x_drvr_stop(hw);
1222 result = hfa384x_drvr_start(hw);
1223 if (result) {
1224 netdev_dbg(wlandev->netdev,
1225 "failed to restart the card for sniffing, result=%d\n",
1226 result);
1227 goto failed;
1228 }
1229 } else {
1230
1231 result = hfa384x_drvr_disable(hw, 0);
1232 if (result) {
1233 netdev_dbg(wlandev->netdev,
1234 "failed to enable port for sniffing, result=%d\n",
1235 result);
1236 goto failed;
1237 }
1238 }
1239 } else {
1240 hw->presniff_port_type = 0;
1241 }
1242
1243
1244 word = msg->channel.data;
1245 result = hfa384x_drvr_setconfig16(hw,
1246 HFA384x_RID_CNFOWNCHANNEL,
1247 word);
1248 hw->sniff_channel = word;
1249
1250 if (result) {
1251 netdev_dbg(wlandev->netdev,
1252 "failed to set channel %d, result=%d\n",
1253 word, result);
1254 goto failed;
1255 }
1256
1257
1258 if (wlandev->netdev->type != ARPHRD_ETHER) {
1259
1260 word = HFA384x_PORTTYPE_PSUEDOIBSS;
1261 result = hfa384x_drvr_setconfig16(hw,
1262 HFA384x_RID_CNFPORTTYPE,
1263 word);
1264 if (result) {
1265 netdev_dbg
1266 (wlandev->netdev,
1267 "failed to set porttype %d, result=%d\n",
1268 word, result);
1269 goto failed;
1270 }
1271 if ((msg->keepwepflags.status ==
1272 P80211ENUM_msgitem_status_data_ok) &&
1273 (msg->keepwepflags.data != P80211ENUM_truth_true)) {
1274
1275 word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
1276 HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
1277 result =
1278 hfa384x_drvr_setconfig16(hw,
1279 HFA384x_RID_CNFWEPFLAGS,
1280 word);
1281 }
1282
1283 if (result) {
1284 netdev_dbg
1285 (wlandev->netdev,
1286 "failed to set wepflags=0x%04x, result=%d\n",
1287 word, result);
1288 goto failed;
1289 }
1290 }
1291
1292
1293 if ((msg->stripfcs.status ==
1294 P80211ENUM_msgitem_status_data_ok) &&
1295 (msg->stripfcs.data == P80211ENUM_truth_true)) {
1296 hw->sniff_fcs = 0;
1297 } else {
1298 hw->sniff_fcs = 1;
1299 }
1300
1301
1302 if (msg->packet_trunc.status ==
1303 P80211ENUM_msgitem_status_data_ok) {
1304 hw->sniff_truncate = msg->packet_trunc.data;
1305 } else {
1306 hw->sniff_truncate = 0;
1307 }
1308
1309
1310 result = hfa384x_drvr_enable(hw, 0);
1311 if (result) {
1312 netdev_dbg
1313 (wlandev->netdev,
1314 "failed to enable port for sniffing, result=%d\n",
1315 result);
1316 goto failed;
1317 }
1318
1319 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
1320 if (result) {
1321 netdev_dbg(wlandev->netdev,
1322 "failed to enable monitor mode, result=%d\n",
1323 result);
1324 goto failed;
1325 }
1326
1327 if (wlandev->netdev->type == ARPHRD_ETHER)
1328 netdev_info(wlandev->netdev, "monitor mode enabled\n");
1329
1330
1331
1332 if ((msg->prismheader.status ==
1333 P80211ENUM_msgitem_status_data_ok) &&
1334 (msg->prismheader.data == P80211ENUM_truth_true)) {
1335 hw->sniffhdr = 0;
1336 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1337 } else if ((msg->wlanheader.status ==
1338 P80211ENUM_msgitem_status_data_ok) &&
1339 (msg->wlanheader.data == P80211ENUM_truth_true)) {
1340 hw->sniffhdr = 1;
1341 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1342 } else {
1343 wlandev->netdev->type = ARPHRD_IEEE80211;
1344 }
1345
1346 msg->resultcode.data = P80211ENUM_resultcode_success;
1347 return 0;
1348 default:
1349 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
1350 return 0;
1351 }
1352
1353 failed:
1354 msg->resultcode.data = P80211ENUM_resultcode_refused;
1355 return 0;
1356 }