1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#include <linux/if_arp.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/wait.h>
65#include <linux/sched.h>
66#include <linux/types.h>
67#include <linux/wireless.h>
68#include <linux/netdevice.h>
69#include <linux/delay.h>
70#include <linux/io.h>
71#include <asm/byteorder.h>
72#include <linux/random.h>
73#include <linux/usb.h>
74#include <linux/bitops.h>
75
76#include "p80211types.h"
77#include "p80211hdr.h"
78#include "p80211mgmt.h"
79#include "p80211conv.h"
80#include "p80211msg.h"
81#include "p80211netdev.h"
82#include "p80211metadef.h"
83#include "p80211metastruct.h"
84#include "hfa384x.h"
85#include "prism2mgmt.h"
86
87
88static inline u16 p80211rate_to_p2bit(u32 rate)
89{
90 switch (rate & ~BIT(7)) {
91 case 2:
92 return BIT(0);
93 case 4:
94 return BIT(1);
95 case 11:
96 return BIT(2);
97 case 22:
98 return BIT(3);
99 default:
100 return 0;
101 }
102}
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp)
130{
131 int result = 0;
132 struct hfa384x *hw = wlandev->priv;
133 struct p80211msg_dot11req_scan *msg = msgp;
134 u16 roamingmode, word;
135 int i, timeout;
136 int istmpenable = 0;
137
138 struct hfa384x_host_scan_request_data scanreq;
139
140
141 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
142 hw->ident_sta_fw.minor,
143 hw->ident_sta_fw.variant) <
144 HFA384x_FIRMWARE_VERSION(1, 3, 2)) {
145 netdev_err(wlandev->netdev,
146 "HostScan not supported with current firmware (<1.3.2).\n");
147 result = 1;
148 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
149 goto exit;
150 }
151
152 memset(&scanreq, 0, sizeof(scanreq));
153
154
155 result = hfa384x_drvr_getconfig16(hw,
156 HFA384x_RID_CNFROAMINGMODE,
157 &roamingmode);
158 if (result) {
159 netdev_err(wlandev->netdev,
160 "getconfig(ROAMMODE) failed. result=%d\n", result);
161 msg->resultcode.data =
162 P80211ENUM_resultcode_implementation_failure;
163 goto exit;
164 }
165
166
167 result = hfa384x_drvr_setconfig16(hw,
168 HFA384x_RID_CNFROAMINGMODE,
169 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
170 if (result) {
171 netdev_err(wlandev->netdev,
172 "setconfig(ROAMINGMODE) failed. result=%d\n",
173 result);
174 msg->resultcode.data =
175 P80211ENUM_resultcode_implementation_failure;
176 goto exit;
177 }
178
179
180 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
181 hw->ident_sta_fw.minor,
182 hw->ident_sta_fw.variant) >
183 HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
184 if (msg->scantype.data != P80211ENUM_scantype_active)
185 word = msg->maxchanneltime.data;
186 else
187 word = 0;
188
189 result =
190 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
191 word);
192 if (result) {
193 netdev_warn(wlandev->netdev,
194 "Passive scan not supported with current firmware. (<1.5.1)\n");
195 }
196 }
197
198
199 word = HFA384x_RATEBIT_2;
200 scanreq.tx_rate = cpu_to_le16(word);
201
202
203 word = 0;
204 for (i = 0; i < msg->channellist.data.len; i++) {
205 u8 channel = msg->channellist.data.data[i];
206
207 if (channel > 14)
208 continue;
209
210 word |= (1 << (channel - 1));
211 }
212 scanreq.channel_list = cpu_to_le16(word);
213
214
215 scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len);
216 memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
217
218
219 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
220 if (result) {
221 netdev_err(wlandev->netdev,
222 "getconfig(PORTSTATUS) failed. result=%d\n", result);
223 msg->resultcode.data =
224 P80211ENUM_resultcode_implementation_failure;
225 goto exit;
226 }
227 if (word == HFA384x_PORTSTATUS_DISABLED) {
228 __le16 wordbuf[17];
229
230 result = hfa384x_drvr_setconfig16(hw,
231 HFA384x_RID_CNFROAMINGMODE,
232 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
233 if (result) {
234 netdev_err(wlandev->netdev,
235 "setconfig(ROAMINGMODE) failed. result=%d\n",
236 result);
237 msg->resultcode.data =
238 P80211ENUM_resultcode_implementation_failure;
239 goto exit;
240 }
241
242
243
244 wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN);
245 get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
246 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
247 wordbuf,
248 HFA384x_RID_CNFOWNSSID_LEN);
249 if (result) {
250 netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n");
251 msg->resultcode.data =
252 P80211ENUM_resultcode_implementation_failure;
253 goto exit;
254 }
255 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
256 wordbuf,
257 HFA384x_RID_CNFDESIREDSSID_LEN);
258 if (result) {
259 netdev_err(wlandev->netdev,
260 "Failed to set DesiredSSID.\n");
261 msg->resultcode.data =
262 P80211ENUM_resultcode_implementation_failure;
263 goto exit;
264 }
265
266 result = hfa384x_drvr_setconfig16(hw,
267 HFA384x_RID_CNFPORTTYPE,
268 HFA384x_PORTTYPE_IBSS);
269 if (result) {
270 netdev_err(wlandev->netdev,
271 "Failed to set CNFPORTTYPE.\n");
272 msg->resultcode.data =
273 P80211ENUM_resultcode_implementation_failure;
274 goto exit;
275 }
276
277 result = hfa384x_drvr_setconfig16(hw,
278 HFA384x_RID_CREATEIBSS,
279 HFA384x_CREATEIBSS_JOINCREATEIBSS);
280 if (result) {
281 netdev_err(wlandev->netdev,
282 "Failed to set CREATEIBSS.\n");
283 msg->resultcode.data =
284 P80211ENUM_resultcode_implementation_failure;
285 goto exit;
286 }
287 result = hfa384x_drvr_enable(hw, 0);
288 if (result) {
289 netdev_err(wlandev->netdev,
290 "drvr_enable(0) failed. result=%d\n",
291 result);
292 msg->resultcode.data =
293 P80211ENUM_resultcode_implementation_failure;
294 goto exit;
295 }
296 istmpenable = 1;
297 }
298
299
300 timeout = msg->channellist.data.len * msg->maxchanneltime.data;
301 timeout = (timeout * HZ) / 1000;
302
303
304 hw->scanflag = 0;
305
306 result = hfa384x_drvr_setconfig(hw,
307 HFA384x_RID_HOSTSCAN, &scanreq,
308 sizeof(scanreq));
309 if (result) {
310 netdev_err(wlandev->netdev,
311 "setconfig(SCANREQUEST) failed. result=%d\n",
312 result);
313 msg->resultcode.data =
314 P80211ENUM_resultcode_implementation_failure;
315 goto exit;
316 }
317
318
319 wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
320
321 msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
322 if (hw->scanflag == -1)
323 hw->scanflag = 0;
324
325 msg->numbss.data = hw->scanflag;
326
327 hw->scanflag = 0;
328
329
330 if (istmpenable) {
331 result = hfa384x_drvr_disable(hw, 0);
332 if (result) {
333 netdev_err(wlandev->netdev,
334 "drvr_disable(0) failed. result=%d\n",
335 result);
336 msg->resultcode.data =
337 P80211ENUM_resultcode_implementation_failure;
338 goto exit;
339 }
340 }
341
342
343 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
344 roamingmode);
345 if (result) {
346 netdev_err(wlandev->netdev,
347 "setconfig(ROAMMODE) failed. result=%d\n", result);
348 msg->resultcode.data =
349 P80211ENUM_resultcode_implementation_failure;
350 goto exit;
351 }
352
353 result = 0;
354 msg->resultcode.data = P80211ENUM_resultcode_success;
355
356exit:
357 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
358
359 return result;
360}
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp)
384{
385 int result = 0;
386 struct p80211msg_dot11req_scan_results *req;
387 struct hfa384x *hw = wlandev->priv;
388 struct hfa384x_hscan_result_sub *item = NULL;
389
390 int count;
391
392 req = msgp;
393
394 req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
395
396 if (!hw->scanresults) {
397 netdev_err(wlandev->netdev,
398 "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
399 result = 2;
400 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
401 goto exit;
402 }
403
404 count = (hw->scanresults->framelen - 3) / 32;
405 if (count > HFA384x_SCANRESULT_MAX)
406 count = HFA384x_SCANRESULT_MAX;
407
408 if (req->bssindex.data >= count) {
409 netdev_dbg(wlandev->netdev,
410 "requested index (%d) out of range (%d)\n",
411 req->bssindex.data, count);
412 result = 2;
413 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
414 goto exit;
415 }
416
417 item = &hw->scanresults->info.hscanresult.result[req->bssindex.data];
418
419 req->signal.status = P80211ENUM_msgitem_status_data_ok;
420 req->noise.status = P80211ENUM_msgitem_status_data_ok;
421 req->signal.data = le16_to_cpu(item->sl);
422 req->noise.data = le16_to_cpu(item->anl);
423
424
425 req->bssid.status = P80211ENUM_msgitem_status_data_ok;
426 req->bssid.data.len = WLAN_BSSID_LEN;
427 memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
428
429
430 req->ssid.status = P80211ENUM_msgitem_status_data_ok;
431 req->ssid.data.len = le16_to_cpu(item->ssid.len);
432 req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN);
433 memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
434
435
436 for (count = 0; count < 10; count++)
437 if (item->supprates[count] == 0)
438 break;
439
440#define REQBASICRATE(N) \
441 do { \
442 if ((count >= (N)) && DOT11_RATE5_ISBASIC_GET( \
443 item->supprates[(N) - 1])) { \
444 req->basicrate ## N .data = item->supprates[(N) - 1]; \
445 req->basicrate ## N .status = \
446 P80211ENUM_msgitem_status_data_ok; \
447 } \
448 } while (0)
449
450 REQBASICRATE(1);
451 REQBASICRATE(2);
452 REQBASICRATE(3);
453 REQBASICRATE(4);
454 REQBASICRATE(5);
455 REQBASICRATE(6);
456 REQBASICRATE(7);
457 REQBASICRATE(8);
458
459#define REQSUPPRATE(N) \
460 do { \
461 if (count >= (N)) { \
462 req->supprate ## N .data = item->supprates[(N) - 1]; \
463 req->supprate ## N .status = \
464 P80211ENUM_msgitem_status_data_ok; \
465 } \
466 } while (0)
467
468 REQSUPPRATE(1);
469 REQSUPPRATE(2);
470 REQSUPPRATE(3);
471 REQSUPPRATE(4);
472 REQSUPPRATE(5);
473 REQSUPPRATE(6);
474 REQSUPPRATE(7);
475 REQSUPPRATE(8);
476
477
478 req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
479 req->beaconperiod.data = le16_to_cpu(item->bcnint);
480
481
482 req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
483 req->timestamp.data = jiffies;
484 req->localtime.status = P80211ENUM_msgitem_status_data_ok;
485 req->localtime.data = jiffies;
486
487
488 req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
489 req->ibssatimwindow.data = le16_to_cpu(item->atim);
490
491
492 req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
493 req->dschannel.data = le16_to_cpu(item->chid);
494
495
496 count = le16_to_cpu(item->capinfo);
497 req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
498 req->capinfo.data = count;
499
500
501 req->privacy.status = P80211ENUM_msgitem_status_data_ok;
502 req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
503
504
505 req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
506 req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
507
508
509 req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
510 req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
511
512
513 req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
514 req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
515 P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
516
517 result = 0;
518 req->resultcode.data = P80211ENUM_resultcode_success;
519
520exit:
521 return result;
522}
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544int prism2mgmt_start(struct wlandevice *wlandev, void *msgp)
545{
546 int result = 0;
547 struct hfa384x *hw = wlandev->priv;
548 struct p80211msg_dot11req_start *msg = msgp;
549
550 struct p80211pstrd *pstr;
551 u8 bytebuf[80];
552 struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
553 u16 word;
554
555 wlandev->macmode = WLAN_MACMODE_NONE;
556
557
558 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
559
560
561
562 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
563 hw->ident_sta_fw.minor,
564 hw->ident_sta_fw.variant) <
565 HFA384x_FIRMWARE_VERSION(0, 8, 3)) {
566
567 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
568 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
569 goto done;
570 }
571
572 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
573
574
575
576
577 pstr = (struct p80211pstrd *)&msg->ssid.data;
578 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
579 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
580 bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
581 if (result) {
582 netdev_err(wlandev->netdev, "Failed to set CnfOwnSSID\n");
583 goto failed;
584 }
585 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
586 bytebuf,
587 HFA384x_RID_CNFDESIREDSSID_LEN);
588 if (result) {
589 netdev_err(wlandev->netdev, "Failed to set CnfDesiredSSID\n");
590 goto failed;
591 }
592
593
594
595 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
596
597
598 word = msg->beaconperiod.data;
599 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
600 if (result) {
601 netdev_err(wlandev->netdev,
602 "Failed to set beacon period=%d.\n", word);
603 goto failed;
604 }
605
606
607 word = msg->dschannel.data;
608 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
609 if (result) {
610 netdev_err(wlandev->netdev,
611 "Failed to set channel=%d.\n", word);
612 goto failed;
613 }
614
615 word = p80211rate_to_p2bit(msg->basicrate1.data);
616 if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok)
617 word |= p80211rate_to_p2bit(msg->basicrate2.data);
618
619 if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok)
620 word |= p80211rate_to_p2bit(msg->basicrate3.data);
621
622 if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok)
623 word |= p80211rate_to_p2bit(msg->basicrate4.data);
624
625 if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok)
626 word |= p80211rate_to_p2bit(msg->basicrate5.data);
627
628 if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok)
629 word |= p80211rate_to_p2bit(msg->basicrate6.data);
630
631 if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok)
632 word |= p80211rate_to_p2bit(msg->basicrate7.data);
633
634 if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok)
635 word |= p80211rate_to_p2bit(msg->basicrate8.data);
636
637 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
638 if (result) {
639 netdev_err(wlandev->netdev,
640 "Failed to set basicrates=%d.\n", word);
641 goto failed;
642 }
643
644
645 word = p80211rate_to_p2bit(msg->operationalrate1.data);
646 if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok)
647 word |= p80211rate_to_p2bit(msg->operationalrate2.data);
648
649 if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok)
650 word |= p80211rate_to_p2bit(msg->operationalrate3.data);
651
652 if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok)
653 word |= p80211rate_to_p2bit(msg->operationalrate4.data);
654
655 if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok)
656 word |= p80211rate_to_p2bit(msg->operationalrate5.data);
657
658 if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok)
659 word |= p80211rate_to_p2bit(msg->operationalrate6.data);
660
661 if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok)
662 word |= p80211rate_to_p2bit(msg->operationalrate7.data);
663
664 if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok)
665 word |= p80211rate_to_p2bit(msg->operationalrate8.data);
666
667 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
668 if (result) {
669 netdev_err(wlandev->netdev,
670 "Failed to set supprates=%d.\n", word);
671 goto failed;
672 }
673
674 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
675 if (result) {
676 netdev_err(wlandev->netdev, "Failed to set txrates=%d.\n",
677 word);
678 goto failed;
679 }
680
681
682 if (msg->bsstype.data == P80211ENUM_bsstype_independent) {
683 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
684
685 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
686 }
687
688
689 result = hfa384x_drvr_enable(hw, 0);
690 if (result) {
691 netdev_err(wlandev->netdev,
692 "Enable macport failed, result=%d.\n", result);
693 goto failed;
694 }
695
696 msg->resultcode.data = P80211ENUM_resultcode_success;
697
698 goto done;
699failed:
700 netdev_dbg(wlandev->netdev,
701 "Failed to set a config option, result=%d\n", result);
702 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
703
704done:
705 return 0;
706}
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp)
728{
729 struct hfa384x *hw = wlandev->priv;
730 struct p80211msg_p2req_readpda *msg = msgp;
731 int result;
732
733
734
735
736 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
737 netdev_err(wlandev->netdev,
738 "PDA may only be read in the fwload state.\n");
739 msg->resultcode.data =
740 P80211ENUM_resultcode_implementation_failure;
741 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
742 } else {
743
744
745
746 result = hfa384x_drvr_readpda(hw,
747 msg->pda.data,
748 HFA384x_PDA_LEN_MAX);
749 if (result) {
750 netdev_err(wlandev->netdev,
751 "hfa384x_drvr_readpda() failed, result=%d\n",
752 result);
753
754 msg->resultcode.data =
755 P80211ENUM_resultcode_implementation_failure;
756 msg->resultcode.status =
757 P80211ENUM_msgitem_status_data_ok;
758 return 0;
759 }
760 msg->pda.status = P80211ENUM_msgitem_status_data_ok;
761 msg->resultcode.data = P80211ENUM_resultcode_success;
762 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
763 }
764
765 return 0;
766}
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp)
795{
796 struct hfa384x *hw = wlandev->priv;
797 struct p80211msg_p2req_ramdl_state *msg = msgp;
798
799 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
800 netdev_err(wlandev->netdev,
801 "ramdl_state(): may only be called in the fwload state.\n");
802 msg->resultcode.data =
803 P80211ENUM_resultcode_implementation_failure;
804 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
805 return 0;
806 }
807
808
809
810
811
812
813 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
814 if (msg->enable.data == P80211ENUM_truth_true) {
815 if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) {
816 msg->resultcode.data =
817 P80211ENUM_resultcode_implementation_failure;
818 } else {
819 msg->resultcode.data = P80211ENUM_resultcode_success;
820 }
821 } else {
822 hfa384x_drvr_ramdl_disable(hw);
823 msg->resultcode.data = P80211ENUM_resultcode_success;
824 }
825
826 return 0;
827}
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp)
851{
852 struct hfa384x *hw = wlandev->priv;
853 struct p80211msg_p2req_ramdl_write *msg = msgp;
854 u32 addr;
855 u32 len;
856 u8 *buf;
857
858 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
859 netdev_err(wlandev->netdev,
860 "ramdl_write(): may only be called in the fwload state.\n");
861 msg->resultcode.data =
862 P80211ENUM_resultcode_implementation_failure;
863 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
864 return 0;
865 }
866
867 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
868
869 if (msg->len.data > sizeof(msg->data.data)) {
870 msg->resultcode.status =
871 P80211ENUM_resultcode_invalid_parameters;
872 return 0;
873 }
874
875 addr = msg->addr.data;
876 len = msg->len.data;
877 buf = msg->data.data;
878 if (hfa384x_drvr_ramdl_write(hw, addr, buf, len))
879 msg->resultcode.data = P80211ENUM_resultcode_refused;
880
881 msg->resultcode.data = P80211ENUM_resultcode_success;
882
883 return 0;
884}
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
913{
914 int result = 0;
915 struct hfa384x *hw = wlandev->priv;
916 struct p80211msg_p2req_flashdl_state *msg = msgp;
917
918 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
919 netdev_err(wlandev->netdev,
920 "flashdl_state(): may only be called in the fwload state.\n");
921 msg->resultcode.data =
922 P80211ENUM_resultcode_implementation_failure;
923 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
924 return 0;
925 }
926
927
928
929
930
931
932 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
933 if (msg->enable.data == P80211ENUM_truth_true) {
934 if (hfa384x_drvr_flashdl_enable(hw)) {
935 msg->resultcode.data =
936 P80211ENUM_resultcode_implementation_failure;
937 } else {
938 msg->resultcode.data = P80211ENUM_resultcode_success;
939 }
940 } else {
941 hfa384x_drvr_flashdl_disable(hw);
942 msg->resultcode.data = P80211ENUM_resultcode_success;
943
944
945
946
947
948
949
950 wlandev->msdstate = WLAN_MSD_HWPRESENT;
951 result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
952 if (result != P80211ENUM_resultcode_success) {
953 netdev_err(wlandev->netdev,
954 "prism2sta_ifstate(fwload) failed, P80211ENUM_resultcode=%d\n",
955 result);
956 msg->resultcode.data =
957 P80211ENUM_resultcode_implementation_failure;
958 result = -1;
959 }
960 }
961
962 return 0;
963}
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp)
985{
986 struct hfa384x *hw = wlandev->priv;
987 struct p80211msg_p2req_flashdl_write *msg = msgp;
988 u32 addr;
989 u32 len;
990 u8 *buf;
991
992 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
993 netdev_err(wlandev->netdev,
994 "flashdl_write(): may only be called in the fwload state.\n");
995 msg->resultcode.data =
996 P80211ENUM_resultcode_implementation_failure;
997 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
998 return 0;
999 }
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
1045int 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
1117int 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
1353failed:
1354 msg->resultcode.data = P80211ENUM_resultcode_refused;
1355 return 0;
1356}
1357