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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114#include <linux/module.h>
115#include <linux/kernel.h>
116#include <linux/sched.h>
117#include <linux/types.h>
118#include <linux/slab.h>
119#include <linux/wireless.h>
120#include <linux/netdevice.h>
121#include <linux/timer.h>
122#include <linux/io.h>
123#include <linux/delay.h>
124#include <asm/byteorder.h>
125#include <linux/bitops.h>
126#include <linux/list.h>
127#include <linux/usb.h>
128#include <linux/byteorder/generic.h>
129
130#include "p80211types.h"
131#include "p80211hdr.h"
132#include "p80211mgmt.h"
133#include "p80211conv.h"
134#include "p80211msg.h"
135#include "p80211netdev.h"
136#include "p80211req.h"
137#include "p80211metadef.h"
138#include "p80211metastruct.h"
139#include "hfa384x.h"
140#include "prism2mgmt.h"
141
142enum cmd_mode {
143 DOWAIT = 0,
144 DOASYNC
145};
146
147#define THROTTLE_JIFFIES (HZ / 8)
148#define URB_ASYNC_UNLINK 0
149#define USB_QUEUE_BULK 0
150
151#define ROUNDUP64(a) (((a) + 63) & ~63)
152
153#ifdef DEBUG_USB
154static void dbprint_urb(struct urb *urb);
155#endif
156
157static void hfa384x_int_rxmonitor(struct wlandevice *wlandev,
158 struct hfa384x_usb_rxfrm *rxfrm);
159
160static void hfa384x_usb_defer(struct work_struct *data);
161
162static int submit_rx_urb(struct hfa384x *hw, gfp_t flags);
163
164static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t flags);
165
166
167
168static void hfa384x_usbout_callback(struct urb *urb);
169static void hfa384x_ctlxout_callback(struct urb *urb);
170static void hfa384x_usbin_callback(struct urb *urb);
171
172static void
173hfa384x_usbin_txcompl(struct wlandevice *wlandev, union hfa384x_usbin *usbin);
174
175static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb);
176
177static void hfa384x_usbin_info(struct wlandevice *wlandev,
178 union hfa384x_usbin *usbin);
179
180static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin,
181 int urb_status);
182
183
184
185
186static void hfa384x_usbctlxq_run(struct hfa384x *hw);
187
188static void hfa384x_usbctlx_reqtimerfn(struct timer_list *t);
189
190static void hfa384x_usbctlx_resptimerfn(struct timer_list *t);
191
192static void hfa384x_usb_throttlefn(struct timer_list *t);
193
194static void hfa384x_usbctlx_completion_task(struct tasklet_struct *t);
195
196static void hfa384x_usbctlx_reaper_task(struct tasklet_struct *t);
197
198static int hfa384x_usbctlx_submit(struct hfa384x *hw,
199 struct hfa384x_usbctlx *ctlx);
200
201static void unlocked_usbctlx_complete(struct hfa384x *hw,
202 struct hfa384x_usbctlx *ctlx);
203
204struct usbctlx_completor {
205 int (*complete)(struct usbctlx_completor *completor);
206};
207
208static int
209hfa384x_usbctlx_complete_sync(struct hfa384x *hw,
210 struct hfa384x_usbctlx *ctlx,
211 struct usbctlx_completor *completor);
212
213static int
214unlocked_usbctlx_cancel_async(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx);
215
216static void hfa384x_cb_status(struct hfa384x *hw,
217 const struct hfa384x_usbctlx *ctlx);
218
219static int
220usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp,
221 struct hfa384x_cmdresult *result);
222
223static void
224usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp,
225 struct hfa384x_rridresult *result);
226
227
228
229static inline int
230hfa384x_docmd(struct hfa384x *hw,
231 struct hfa384x_metacmd *cmd);
232
233static int
234hfa384x_dorrid(struct hfa384x *hw,
235 enum cmd_mode mode,
236 u16 rid,
237 void *riddata,
238 unsigned int riddatalen,
239 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
240
241static int
242hfa384x_dowrid(struct hfa384x *hw,
243 enum cmd_mode mode,
244 u16 rid,
245 void *riddata,
246 unsigned int riddatalen,
247 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
248
249static int
250hfa384x_dormem(struct hfa384x *hw,
251 u16 page,
252 u16 offset,
253 void *data,
254 unsigned int len);
255
256static int
257hfa384x_dowmem(struct hfa384x *hw,
258 u16 page,
259 u16 offset,
260 void *data,
261 unsigned int len);
262
263static int hfa384x_isgood_pdrcode(u16 pdrcode);
264
265static inline const char *ctlxstr(enum ctlx_state s)
266{
267 static const char * const ctlx_str[] = {
268 "Initial state",
269 "Complete",
270 "Request failed",
271 "Request pending",
272 "Request packet submitted",
273 "Request packet completed",
274 "Response packet completed"
275 };
276
277 return ctlx_str[s];
278};
279
280static inline struct hfa384x_usbctlx *get_active_ctlx(struct hfa384x *hw)
281{
282 return list_entry(hw->ctlxq.active.next, struct hfa384x_usbctlx, list);
283}
284
285#ifdef DEBUG_USB
286void dbprint_urb(struct urb *urb)
287{
288 pr_debug("urb->pipe=0x%08x\n", urb->pipe);
289 pr_debug("urb->status=0x%08x\n", urb->status);
290 pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags);
291 pr_debug("urb->transfer_buffer=0x%08x\n",
292 (unsigned int)urb->transfer_buffer);
293 pr_debug("urb->transfer_buffer_length=0x%08x\n",
294 urb->transfer_buffer_length);
295 pr_debug("urb->actual_length=0x%08x\n", urb->actual_length);
296 pr_debug("urb->setup_packet(ctl)=0x%08x\n",
297 (unsigned int)urb->setup_packet);
298 pr_debug("urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
299 pr_debug("urb->interval(irq)=0x%08x\n", urb->interval);
300 pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count);
301 pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context);
302 pr_debug("urb->complete=0x%08x\n", (unsigned int)urb->complete);
303}
304#endif
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323static int submit_rx_urb(struct hfa384x *hw, gfp_t memflags)
324{
325 struct sk_buff *skb;
326 int result;
327
328 skb = dev_alloc_skb(sizeof(union hfa384x_usbin));
329 if (!skb) {
330 result = -ENOMEM;
331 goto done;
332 }
333
334
335 usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
336 hw->endp_in,
337 skb->data, sizeof(union hfa384x_usbin),
338 hfa384x_usbin_callback, hw->wlandev);
339
340 hw->rx_urb_skb = skb;
341
342 result = -ENOLINK;
343 if (!hw->wlandev->hwremoved &&
344 !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
345 result = usb_submit_urb(&hw->rx_urb, memflags);
346
347
348 if (result == -EPIPE) {
349 netdev_warn(hw->wlandev->netdev,
350 "%s rx pipe stalled: requesting reset\n",
351 hw->wlandev->netdev->name);
352 if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
353 schedule_work(&hw->usb_work);
354 }
355 }
356
357
358 if (result != 0) {
359 dev_kfree_skb(skb);
360 hw->rx_urb_skb = NULL;
361 }
362
363done:
364 return result;
365}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t memflags)
387{
388 struct net_device *netdev = hw->wlandev->netdev;
389 int result;
390
391 result = -ENOLINK;
392 if (netif_running(netdev)) {
393 if (!hw->wlandev->hwremoved &&
394 !test_bit(WORK_TX_HALT, &hw->usb_flags)) {
395 result = usb_submit_urb(tx_urb, memflags);
396
397
398 if (result == -EPIPE) {
399 netdev_warn(hw->wlandev->netdev,
400 "%s tx pipe stalled: requesting reset\n",
401 netdev->name);
402 set_bit(WORK_TX_HALT, &hw->usb_flags);
403 schedule_work(&hw->usb_work);
404 } else if (result == 0) {
405 netif_stop_queue(netdev);
406 }
407 }
408 }
409
410 return result;
411}
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430static void hfa384x_usb_defer(struct work_struct *data)
431{
432 struct hfa384x *hw = container_of(data, struct hfa384x, usb_work);
433 struct net_device *netdev = hw->wlandev->netdev;
434
435
436
437
438 if (hw->wlandev->hwremoved)
439 return;
440
441
442 if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
443 int ret;
444
445 usb_kill_urb(&hw->rx_urb);
446
447 ret = usb_clear_halt(hw->usb, hw->endp_in);
448 if (ret != 0) {
449 netdev_err(hw->wlandev->netdev,
450 "Failed to clear rx pipe for %s: err=%d\n",
451 netdev->name, ret);
452 } else {
453 netdev_info(hw->wlandev->netdev, "%s rx pipe reset complete.\n",
454 netdev->name);
455 clear_bit(WORK_RX_HALT, &hw->usb_flags);
456 set_bit(WORK_RX_RESUME, &hw->usb_flags);
457 }
458 }
459
460
461 if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) {
462 int ret;
463
464 ret = submit_rx_urb(hw, GFP_KERNEL);
465 if (ret != 0) {
466 netdev_err(hw->wlandev->netdev,
467 "Failed to resume %s rx pipe.\n",
468 netdev->name);
469 } else {
470 clear_bit(WORK_RX_RESUME, &hw->usb_flags);
471 }
472 }
473
474
475 if (test_bit(WORK_TX_HALT, &hw->usb_flags)) {
476 int ret;
477
478 usb_kill_urb(&hw->tx_urb);
479 ret = usb_clear_halt(hw->usb, hw->endp_out);
480 if (ret != 0) {
481 netdev_err(hw->wlandev->netdev,
482 "Failed to clear tx pipe for %s: err=%d\n",
483 netdev->name, ret);
484 } else {
485 netdev_info(hw->wlandev->netdev, "%s tx pipe reset complete.\n",
486 netdev->name);
487 clear_bit(WORK_TX_HALT, &hw->usb_flags);
488 set_bit(WORK_TX_RESUME, &hw->usb_flags);
489
490
491
492
493
494 hfa384x_usbctlxq_run(hw);
495 }
496 }
497
498
499 if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags))
500 netif_wake_queue(hw->wlandev->netdev);
501}
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525void hfa384x_create(struct hfa384x *hw, struct usb_device *usb)
526{
527 hw->usb = usb;
528
529
530 init_waitqueue_head(&hw->cmdq);
531
532
533 spin_lock_init(&hw->ctlxq.lock);
534 INIT_LIST_HEAD(&hw->ctlxq.pending);
535 INIT_LIST_HEAD(&hw->ctlxq.active);
536 INIT_LIST_HEAD(&hw->ctlxq.completing);
537 INIT_LIST_HEAD(&hw->ctlxq.reapable);
538
539
540 skb_queue_head_init(&hw->authq);
541
542 tasklet_setup(&hw->reaper_bh, hfa384x_usbctlx_reaper_task);
543 tasklet_setup(&hw->completion_bh, hfa384x_usbctlx_completion_task);
544 INIT_WORK(&hw->link_bh, prism2sta_processing_defer);
545 INIT_WORK(&hw->usb_work, hfa384x_usb_defer);
546
547 timer_setup(&hw->throttle, hfa384x_usb_throttlefn, 0);
548
549 timer_setup(&hw->resptimer, hfa384x_usbctlx_resptimerfn, 0);
550
551 timer_setup(&hw->reqtimer, hfa384x_usbctlx_reqtimerfn, 0);
552
553 usb_init_urb(&hw->rx_urb);
554 usb_init_urb(&hw->tx_urb);
555 usb_init_urb(&hw->ctlx_urb);
556
557 hw->link_status = HFA384x_LINK_NOTCONNECTED;
558 hw->state = HFA384x_STATE_INIT;
559
560 INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
561 timer_setup(&hw->commsqual_timer, prism2sta_commsqual_timer, 0);
562}
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587void hfa384x_destroy(struct hfa384x *hw)
588{
589 struct sk_buff *skb;
590
591 if (hw->state == HFA384x_STATE_RUNNING)
592 hfa384x_drvr_stop(hw);
593 hw->state = HFA384x_STATE_PREINIT;
594
595 kfree(hw->scanresults);
596 hw->scanresults = NULL;
597
598
599 while ((skb = skb_dequeue(&hw->authq)))
600 dev_kfree_skb(skb);
601}
602
603static struct hfa384x_usbctlx *usbctlx_alloc(void)
604{
605 struct hfa384x_usbctlx *ctlx;
606
607 ctlx = kzalloc(sizeof(*ctlx),
608 in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
609 if (ctlx)
610 init_completion(&ctlx->done);
611
612 return ctlx;
613}
614
615static int
616usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp,
617 struct hfa384x_cmdresult *result)
618{
619 result->status = le16_to_cpu(cmdresp->status);
620 result->resp0 = le16_to_cpu(cmdresp->resp0);
621 result->resp1 = le16_to_cpu(cmdresp->resp1);
622 result->resp2 = le16_to_cpu(cmdresp->resp2);
623
624 pr_debug("cmdresult:status=0x%04x resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
625 result->status, result->resp0, result->resp1, result->resp2);
626
627 return result->status & HFA384x_STATUS_RESULT;
628}
629
630static void
631usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp,
632 struct hfa384x_rridresult *result)
633{
634 result->rid = le16_to_cpu(rridresp->rid);
635 result->riddata = rridresp->data;
636 result->riddata_len = ((le16_to_cpu(rridresp->frmlen) - 1) * 2);
637}
638
639
640
641
642
643
644
645struct usbctlx_cmd_completor {
646 struct usbctlx_completor head;
647
648 const struct hfa384x_usb_statusresp *cmdresp;
649 struct hfa384x_cmdresult *result;
650};
651
652static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head)
653{
654 struct usbctlx_cmd_completor *complete;
655
656 complete = (struct usbctlx_cmd_completor *)head;
657 return usbctlx_get_status(complete->cmdresp, complete->result);
658}
659
660static inline struct usbctlx_completor *
661init_cmd_completor(struct usbctlx_cmd_completor *completor,
662 const struct hfa384x_usb_statusresp *cmdresp,
663 struct hfa384x_cmdresult *result)
664{
665 completor->head.complete = usbctlx_cmd_completor_fn;
666 completor->cmdresp = cmdresp;
667 completor->result = result;
668 return &completor->head;
669}
670
671
672
673
674
675
676
677struct usbctlx_rrid_completor {
678 struct usbctlx_completor head;
679
680 const struct hfa384x_usb_rridresp *rridresp;
681 void *riddata;
682 unsigned int riddatalen;
683};
684
685static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head)
686{
687 struct usbctlx_rrid_completor *complete;
688 struct hfa384x_rridresult rridresult;
689
690 complete = (struct usbctlx_rrid_completor *)head;
691 usbctlx_get_rridresult(complete->rridresp, &rridresult);
692
693
694 if (rridresult.riddata_len != complete->riddatalen) {
695 pr_warn("RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
696 rridresult.rid,
697 complete->riddatalen, rridresult.riddata_len);
698 return -ENODATA;
699 }
700
701 memcpy(complete->riddata, rridresult.riddata, complete->riddatalen);
702 return 0;
703}
704
705static inline struct usbctlx_completor *
706init_rrid_completor(struct usbctlx_rrid_completor *completor,
707 const struct hfa384x_usb_rridresp *rridresp,
708 void *riddata,
709 unsigned int riddatalen)
710{
711 completor->head.complete = usbctlx_rrid_completor_fn;
712 completor->rridresp = rridresp;
713 completor->riddata = riddata;
714 completor->riddatalen = riddatalen;
715 return &completor->head;
716}
717
718
719
720
721
722
723#define init_wrid_completor init_cmd_completor
724
725
726
727
728
729
730#define init_wmem_completor init_cmd_completor
731
732
733
734
735
736
737struct usbctlx_rmem_completor {
738 struct usbctlx_completor head;
739
740 const struct hfa384x_usb_rmemresp *rmemresp;
741 void *data;
742 unsigned int len;
743};
744
745static int usbctlx_rmem_completor_fn(struct usbctlx_completor *head)
746{
747 struct usbctlx_rmem_completor *complete =
748 (struct usbctlx_rmem_completor *)head;
749
750 pr_debug("rmemresp:len=%d\n", complete->rmemresp->frmlen);
751 memcpy(complete->data, complete->rmemresp->data, complete->len);
752 return 0;
753}
754
755static inline struct usbctlx_completor *
756init_rmem_completor(struct usbctlx_rmem_completor *completor,
757 struct hfa384x_usb_rmemresp *rmemresp,
758 void *data,
759 unsigned int len)
760{
761 completor->head.complete = usbctlx_rmem_completor_fn;
762 completor->rmemresp = rmemresp;
763 completor->data = data;
764 completor->len = len;
765 return &completor->head;
766}
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790static void hfa384x_cb_status(struct hfa384x *hw,
791 const struct hfa384x_usbctlx *ctlx)
792{
793 if (ctlx->usercb) {
794 struct hfa384x_cmdresult cmdresult;
795
796 if (ctlx->state != CTLX_COMPLETE) {
797 memset(&cmdresult, 0, sizeof(cmdresult));
798 cmdresult.status =
799 HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
800 } else {
801 usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
802 }
803
804 ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
805 }
806}
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828int hfa384x_cmd_initialize(struct hfa384x *hw)
829{
830 int result = 0;
831 int i;
832 struct hfa384x_metacmd cmd;
833
834 cmd.cmd = HFA384x_CMDCODE_INIT;
835 cmd.parm0 = 0;
836 cmd.parm1 = 0;
837 cmd.parm2 = 0;
838
839 result = hfa384x_docmd(hw, &cmd);
840
841 pr_debug("cmdresp.init: status=0x%04x, resp0=0x%04x, resp1=0x%04x, resp2=0x%04x\n",
842 cmd.result.status,
843 cmd.result.resp0, cmd.result.resp1, cmd.result.resp2);
844 if (result == 0) {
845 for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
846 hw->port_enabled[i] = 0;
847 }
848
849 hw->link_status = HFA384x_LINK_NOTCONNECTED;
850
851 return result;
852}
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport)
876{
877 struct hfa384x_metacmd cmd;
878
879 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
880 HFA384x_CMD_MACPORT_SET(macport);
881 cmd.parm0 = 0;
882 cmd.parm1 = 0;
883 cmd.parm2 = 0;
884
885 return hfa384x_docmd(hw, &cmd);
886}
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport)
910{
911 struct hfa384x_metacmd cmd;
912
913 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
914 HFA384x_CMD_MACPORT_SET(macport);
915 cmd.parm0 = 0;
916 cmd.parm1 = 0;
917 cmd.parm2 = 0;
918
919 return hfa384x_docmd(hw, &cmd);
920}
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable)
953{
954 struct hfa384x_metacmd cmd;
955
956 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
957 HFA384x_CMD_AINFO_SET(enable);
958 cmd.parm0 = 0;
959 cmd.parm1 = 0;
960 cmd.parm2 = 0;
961
962 return hfa384x_docmd(hw, &cmd);
963}
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004int hfa384x_cmd_download(struct hfa384x *hw, u16 mode, u16 lowaddr,
1005 u16 highaddr, u16 codelen)
1006{
1007 struct hfa384x_metacmd cmd;
1008
1009 pr_debug("mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
1010 mode, lowaddr, highaddr, codelen);
1011
1012 cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
1013 HFA384x_CMD_PROGMODE_SET(mode));
1014
1015 cmd.parm0 = lowaddr;
1016 cmd.parm1 = highaddr;
1017 cmd.parm2 = codelen;
1018
1019 return hfa384x_docmd(hw, &cmd);
1020}
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046int hfa384x_corereset(struct hfa384x *hw, int holdtime,
1047 int settletime, int genesis)
1048{
1049 int result;
1050
1051 result = usb_reset_device(hw->usb);
1052 if (result < 0) {
1053 netdev_err(hw->wlandev->netdev, "usb_reset_device() failed, result=%d.\n",
1054 result);
1055 }
1056
1057 return result;
1058}
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085static int hfa384x_usbctlx_complete_sync(struct hfa384x *hw,
1086 struct hfa384x_usbctlx *ctlx,
1087 struct usbctlx_completor *completor)
1088{
1089 unsigned long flags;
1090 int result;
1091
1092 result = wait_for_completion_interruptible(&ctlx->done);
1093
1094 spin_lock_irqsave(&hw->ctlxq.lock, flags);
1095
1096
1097
1098
1099
1100cleanup:
1101 if (hw->wlandev->hwremoved) {
1102 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1103 result = -ENODEV;
1104 } else if (result != 0) {
1105 int runqueue = 0;
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 if (ctlx == get_active_ctlx(hw)) {
1117 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1118
1119 del_singleshot_timer_sync(&hw->reqtimer);
1120 del_singleshot_timer_sync(&hw->resptimer);
1121 hw->req_timer_done = 1;
1122 hw->resp_timer_done = 1;
1123 usb_kill_urb(&hw->ctlx_urb);
1124
1125 spin_lock_irqsave(&hw->ctlxq.lock, flags);
1126
1127 runqueue = 1;
1128
1129
1130
1131
1132
1133 if (hw->wlandev->hwremoved)
1134 goto cleanup;
1135 }
1136
1137
1138
1139
1140
1141
1142 ctlx->reapable = 1;
1143 ctlx->state = CTLX_REQ_FAILED;
1144 list_move_tail(&ctlx->list, &hw->ctlxq.completing);
1145
1146 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1147
1148 if (runqueue)
1149 hfa384x_usbctlxq_run(hw);
1150 } else {
1151 if (ctlx->state == CTLX_COMPLETE) {
1152 result = completor->complete(completor);
1153 } else {
1154 netdev_warn(hw->wlandev->netdev, "CTLX[%d] error: state(%s)\n",
1155 le16_to_cpu(ctlx->outbuf.type),
1156 ctlxstr(ctlx->state));
1157 result = -EIO;
1158 }
1159
1160 list_del(&ctlx->list);
1161 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1162 kfree(ctlx);
1163 }
1164
1165 return result;
1166}
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196static inline int
1197hfa384x_docmd(struct hfa384x *hw,
1198 struct hfa384x_metacmd *cmd)
1199{
1200 int result;
1201 struct hfa384x_usbctlx *ctlx;
1202
1203 ctlx = usbctlx_alloc();
1204 if (!ctlx) {
1205 result = -ENOMEM;
1206 goto done;
1207 }
1208
1209
1210 ctlx->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ);
1211 ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd);
1212 ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0);
1213 ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1);
1214 ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(cmd->parm2);
1215
1216 ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
1217
1218 pr_debug("cmdreq: cmd=0x%04x parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
1219 cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
1220
1221 ctlx->reapable = DOWAIT;
1222 ctlx->cmdcb = NULL;
1223 ctlx->usercb = NULL;
1224 ctlx->usercb_data = NULL;
1225
1226 result = hfa384x_usbctlx_submit(hw, ctlx);
1227 if (result != 0) {
1228 kfree(ctlx);
1229 } else {
1230 struct usbctlx_cmd_completor cmd_completor;
1231 struct usbctlx_completor *completor;
1232
1233 completor = init_cmd_completor(&cmd_completor,
1234 &ctlx->inbuf.cmdresp,
1235 &cmd->result);
1236
1237 result = hfa384x_usbctlx_complete_sync(hw, ctlx, completor);
1238 }
1239
1240done:
1241 return result;
1242}
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281static int
1282hfa384x_dorrid(struct hfa384x *hw,
1283 enum cmd_mode mode,
1284 u16 rid,
1285 void *riddata,
1286 unsigned int riddatalen,
1287 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
1288{
1289 int result;
1290 struct hfa384x_usbctlx *ctlx;
1291
1292 ctlx = usbctlx_alloc();
1293 if (!ctlx) {
1294 result = -ENOMEM;
1295 goto done;
1296 }
1297
1298
1299 ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ);
1300 ctlx->outbuf.rridreq.frmlen =
1301 cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid));
1302 ctlx->outbuf.rridreq.rid = cpu_to_le16(rid);
1303
1304 ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
1305
1306 ctlx->reapable = mode;
1307 ctlx->cmdcb = cmdcb;
1308 ctlx->usercb = usercb;
1309 ctlx->usercb_data = usercb_data;
1310
1311
1312 result = hfa384x_usbctlx_submit(hw, ctlx);
1313 if (result != 0) {
1314 kfree(ctlx);
1315 } else if (mode == DOWAIT) {
1316 struct usbctlx_rrid_completor completor;
1317
1318 result =
1319 hfa384x_usbctlx_complete_sync(hw, ctlx,
1320 init_rrid_completor
1321 (&completor,
1322 &ctlx->inbuf.rridresp,
1323 riddata, riddatalen));
1324 }
1325
1326done:
1327 return result;
1328}
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363static int
1364hfa384x_dowrid(struct hfa384x *hw,
1365 enum cmd_mode mode,
1366 u16 rid,
1367 void *riddata,
1368 unsigned int riddatalen,
1369 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
1370{
1371 int result;
1372 struct hfa384x_usbctlx *ctlx;
1373
1374 ctlx = usbctlx_alloc();
1375 if (!ctlx) {
1376 result = -ENOMEM;
1377 goto done;
1378 }
1379
1380
1381 ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ);
1382 ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof
1383 (ctlx->outbuf.wridreq.rid) +
1384 riddatalen + 1) / 2);
1385 ctlx->outbuf.wridreq.rid = cpu_to_le16(rid);
1386 memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
1387
1388 ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
1389 sizeof(ctlx->outbuf.wridreq.frmlen) +
1390 sizeof(ctlx->outbuf.wridreq.rid) + riddatalen;
1391
1392 ctlx->reapable = mode;
1393 ctlx->cmdcb = cmdcb;
1394 ctlx->usercb = usercb;
1395 ctlx->usercb_data = usercb_data;
1396
1397
1398 result = hfa384x_usbctlx_submit(hw, ctlx);
1399 if (result != 0) {
1400 kfree(ctlx);
1401 } else if (mode == DOWAIT) {
1402 struct usbctlx_cmd_completor completor;
1403 struct hfa384x_cmdresult wridresult;
1404
1405 result = hfa384x_usbctlx_complete_sync(hw,
1406 ctlx,
1407 init_wrid_completor
1408 (&completor,
1409 &ctlx->inbuf.wridresp,
1410 &wridresult));
1411 }
1412
1413done:
1414 return result;
1415}
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446static int
1447hfa384x_dormem(struct hfa384x *hw,
1448 u16 page,
1449 u16 offset,
1450 void *data,
1451 unsigned int len)
1452{
1453 int result;
1454 struct hfa384x_usbctlx *ctlx;
1455
1456 ctlx = usbctlx_alloc();
1457 if (!ctlx) {
1458 result = -ENOMEM;
1459 goto done;
1460 }
1461
1462
1463 ctlx->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ);
1464 ctlx->outbuf.rmemreq.frmlen =
1465 cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) +
1466 sizeof(ctlx->outbuf.rmemreq.page) + len);
1467 ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset);
1468 ctlx->outbuf.rmemreq.page = cpu_to_le16(page);
1469
1470 ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
1471
1472 pr_debug("type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
1473 ctlx->outbuf.rmemreq.type,
1474 ctlx->outbuf.rmemreq.frmlen,
1475 ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page);
1476
1477 pr_debug("pktsize=%zd\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
1478
1479 ctlx->reapable = DOWAIT;
1480 ctlx->cmdcb = NULL;
1481 ctlx->usercb = NULL;
1482 ctlx->usercb_data = NULL;
1483
1484 result = hfa384x_usbctlx_submit(hw, ctlx);
1485 if (result != 0) {
1486 kfree(ctlx);
1487 } else {
1488 struct usbctlx_rmem_completor completor;
1489
1490 result =
1491 hfa384x_usbctlx_complete_sync(hw, ctlx,
1492 init_rmem_completor
1493 (&completor,
1494 &ctlx->inbuf.rmemresp, data,
1495 len));
1496 }
1497
1498done:
1499 return result;
1500}
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532static int
1533hfa384x_dowmem(struct hfa384x *hw,
1534 u16 page,
1535 u16 offset,
1536 void *data,
1537 unsigned int len)
1538{
1539 int result;
1540 struct hfa384x_usbctlx *ctlx;
1541
1542 pr_debug("page=0x%04x offset=0x%04x len=%d\n", page, offset, len);
1543
1544 ctlx = usbctlx_alloc();
1545 if (!ctlx) {
1546 result = -ENOMEM;
1547 goto done;
1548 }
1549
1550
1551 ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ);
1552 ctlx->outbuf.wmemreq.frmlen =
1553 cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) +
1554 sizeof(ctlx->outbuf.wmemreq.page) + len);
1555 ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset);
1556 ctlx->outbuf.wmemreq.page = cpu_to_le16(page);
1557 memcpy(ctlx->outbuf.wmemreq.data, data, len);
1558
1559 ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
1560 sizeof(ctlx->outbuf.wmemreq.frmlen) +
1561 sizeof(ctlx->outbuf.wmemreq.offset) +
1562 sizeof(ctlx->outbuf.wmemreq.page) + len;
1563
1564 ctlx->reapable = DOWAIT;
1565 ctlx->cmdcb = NULL;
1566 ctlx->usercb = NULL;
1567 ctlx->usercb_data = NULL;
1568
1569 result = hfa384x_usbctlx_submit(hw, ctlx);
1570 if (result != 0) {
1571 kfree(ctlx);
1572 } else {
1573 struct usbctlx_cmd_completor completor;
1574 struct hfa384x_cmdresult wmemresult;
1575
1576 result = hfa384x_usbctlx_complete_sync(hw,
1577 ctlx,
1578 init_wmem_completor
1579 (&completor,
1580 &ctlx->inbuf.wmemresp,
1581 &wmemresult));
1582 }
1583
1584done:
1585 return result;
1586}
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611int hfa384x_drvr_disable(struct hfa384x *hw, u16 macport)
1612{
1613 int result = 0;
1614
1615 if ((!hw->isap && macport != 0) ||
1616 (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
1617 !(hw->port_enabled[macport])) {
1618 result = -EINVAL;
1619 } else {
1620 result = hfa384x_cmd_disable(hw, macport);
1621 if (result == 0)
1622 hw->port_enabled[macport] = 0;
1623 }
1624 return result;
1625}
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650int hfa384x_drvr_enable(struct hfa384x *hw, u16 macport)
1651{
1652 int result = 0;
1653
1654 if ((!hw->isap && macport != 0) ||
1655 (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
1656 (hw->port_enabled[macport])) {
1657 result = -EINVAL;
1658 } else {
1659 result = hfa384x_cmd_enable(hw, macport);
1660 if (result == 0)
1661 hw->port_enabled[macport] = 1;
1662 }
1663 return result;
1664}
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688int hfa384x_drvr_flashdl_enable(struct hfa384x *hw)
1689{
1690 int result = 0;
1691 int i;
1692
1693
1694 for (i = 0; i < HFA384x_PORTID_MAX; i++) {
1695 if (hw->port_enabled[i]) {
1696 pr_debug("called when port enabled.\n");
1697 return -EINVAL;
1698 }
1699 }
1700
1701
1702 if (hw->dlstate != HFA384x_DLSTATE_DISABLED)
1703 return -EINVAL;
1704
1705
1706 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
1707 &hw->bufinfo, sizeof(hw->bufinfo));
1708 if (result)
1709 return result;
1710
1711 le16_to_cpus(&hw->bufinfo.page);
1712 le16_to_cpus(&hw->bufinfo.offset);
1713 le16_to_cpus(&hw->bufinfo.len);
1714 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
1715 &hw->dltimeout);
1716 if (result)
1717 return result;
1718
1719 le16_to_cpus(&hw->dltimeout);
1720
1721 pr_debug("flashdl_enable\n");
1722
1723 hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
1724
1725 return result;
1726}
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748int hfa384x_drvr_flashdl_disable(struct hfa384x *hw)
1749{
1750
1751 if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
1752 return -EINVAL;
1753
1754 pr_debug("flashdl_enable\n");
1755
1756
1757
1758 hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
1759 hw->dlstate = HFA384x_DLSTATE_DISABLED;
1760
1761 return 0;
1762}
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr,
1795 void *buf, u32 len)
1796{
1797 int result = 0;
1798 u32 dlbufaddr;
1799 int nburns;
1800 u32 burnlen;
1801 u32 burndaddr;
1802 u16 burnlo;
1803 u16 burnhi;
1804 int nwrites;
1805 u8 *writebuf;
1806 u16 writepage;
1807 u16 writeoffset;
1808 u32 writelen;
1809 int i;
1810 int j;
1811
1812 pr_debug("daddr=0x%08x len=%d\n", daddr, len);
1813
1814
1815 if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
1816 return -EINVAL;
1817
1818 netdev_info(hw->wlandev->netdev,
1819 "Download %d bytes to flash @0x%06x\n", len, daddr);
1820
1821
1822
1823 dlbufaddr =
1824 HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset);
1825 pr_debug("dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
1826 hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
1827
1828
1829
1830
1831
1832
1833
1834
1835 nburns = len / hw->bufinfo.len;
1836 nburns += (len % hw->bufinfo.len) ? 1 : 0;
1837
1838
1839 nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN;
1840 nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
1841
1842
1843 for (i = 0; i < nburns; i++) {
1844
1845 burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
1846 hw->bufinfo.len : (len - (hw->bufinfo.len * i));
1847 burndaddr = daddr + (hw->bufinfo.len * i);
1848 burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
1849 burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
1850
1851 netdev_info(hw->wlandev->netdev, "Writing %d bytes to flash @0x%06x\n",
1852 burnlen, burndaddr);
1853
1854
1855 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
1856 burnlo, burnhi, burnlen);
1857 if (result) {
1858 netdev_err(hw->wlandev->netdev,
1859 "download(NV,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n",
1860 burnlo, burnhi, burnlen, result);
1861 goto exit_proc;
1862 }
1863
1864
1865 for (j = 0; j < nwrites; j++) {
1866 writebuf = buf +
1867 (i * hw->bufinfo.len) +
1868 (j * HFA384x_USB_RWMEM_MAXLEN);
1869
1870 writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr +
1871 (j * HFA384x_USB_RWMEM_MAXLEN));
1872 writeoffset = HFA384x_ADDR_CMD_MKOFF(dlbufaddr +
1873 (j * HFA384x_USB_RWMEM_MAXLEN));
1874
1875 writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN);
1876 writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
1877 HFA384x_USB_RWMEM_MAXLEN : writelen;
1878
1879 result = hfa384x_dowmem(hw,
1880 writepage,
1881 writeoffset,
1882 writebuf, writelen);
1883 }
1884
1885
1886 result = hfa384x_cmd_download(hw,
1887 HFA384x_PROGMODE_NVWRITE,
1888 0, 0, 0);
1889 if (result) {
1890 netdev_err(hw->wlandev->netdev,
1891 "download(NVWRITE,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n",
1892 burnlo, burnhi, burnlen, result);
1893 goto exit_proc;
1894 }
1895
1896
1897 }
1898
1899exit_proc:
1900
1901
1902
1903
1904
1905 return result;
1906}
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len)
1935{
1936 return hfa384x_dorrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL);
1937}
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963int
1964hfa384x_drvr_setconfig_async(struct hfa384x *hw,
1965 u16 rid,
1966 void *buf,
1967 u16 len, ctlx_usercb_t usercb, void *usercb_data)
1968{
1969 return hfa384x_dowrid(hw, DOASYNC, rid, buf, len, hfa384x_cb_status,
1970 usercb, usercb_data);
1971}
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992int hfa384x_drvr_ramdl_disable(struct hfa384x *hw)
1993{
1994
1995 if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
1996 return -EINVAL;
1997
1998 pr_debug("ramdl_disable()\n");
1999
2000
2001
2002 hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
2003 hw->dlstate = HFA384x_DLSTATE_DISABLED;
2004
2005 return 0;
2006}
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033int hfa384x_drvr_ramdl_enable(struct hfa384x *hw, u32 exeaddr)
2034{
2035 int result = 0;
2036 u16 lowaddr;
2037 u16 hiaddr;
2038 int i;
2039
2040
2041 for (i = 0; i < HFA384x_PORTID_MAX; i++) {
2042 if (hw->port_enabled[i]) {
2043 netdev_err(hw->wlandev->netdev,
2044 "Can't download with a macport enabled.\n");
2045 return -EINVAL;
2046 }
2047 }
2048
2049
2050 if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
2051 netdev_err(hw->wlandev->netdev,
2052 "Download state not disabled.\n");
2053 return -EINVAL;
2054 }
2055
2056 pr_debug("ramdl_enable, exeaddr=0x%08x\n", exeaddr);
2057
2058
2059 lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
2060 hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
2061
2062 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
2063 lowaddr, hiaddr, 0);
2064
2065 if (result == 0) {
2066
2067 hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
2068 } else {
2069 pr_debug("cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
2070 lowaddr, hiaddr, result);
2071 }
2072
2073 return result;
2074}
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len)
2104{
2105 int result = 0;
2106 int nwrites;
2107 u8 *data = buf;
2108 int i;
2109 u32 curraddr;
2110 u16 currpage;
2111 u16 curroffset;
2112 u16 currlen;
2113
2114
2115 if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
2116 return -EINVAL;
2117
2118 netdev_info(hw->wlandev->netdev, "Writing %d bytes to ram @0x%06x\n",
2119 len, daddr);
2120
2121
2122 nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
2123 nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
2124
2125
2126 for (i = 0; i < nwrites; i++) {
2127
2128 curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
2129 currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
2130 curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
2131 currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
2132 if (currlen > HFA384x_USB_RWMEM_MAXLEN)
2133 currlen = HFA384x_USB_RWMEM_MAXLEN;
2134
2135
2136 result = hfa384x_dowmem(hw,
2137 currpage,
2138 curroffset,
2139 data + (i * HFA384x_USB_RWMEM_MAXLEN),
2140 currlen);
2141
2142 if (result)
2143 break;
2144
2145
2146 }
2147
2148 return result;
2149}
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len)
2184{
2185 int result = 0;
2186 __le16 *pda = buf;
2187 int pdaok = 0;
2188 int morepdrs = 1;
2189 int currpdr = 0;
2190 size_t i;
2191 u16 pdrlen;
2192 u16 pdrcode;
2193 u16 currpage;
2194 u16 curroffset;
2195 struct pdaloc {
2196 u32 cardaddr;
2197 u16 auxctl;
2198 } pdaloc[] = {
2199 {
2200 HFA3842_PDA_BASE, 0}, {
2201 HFA3841_PDA_BASE, 0}, {
2202 HFA3841_PDA_BOGUS_BASE, 0}
2203 };
2204
2205
2206 for (i = 0; i < ARRAY_SIZE(pdaloc); i++) {
2207
2208 currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
2209 curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
2210
2211
2212 result = hfa384x_dormem(hw, currpage, curroffset, buf,
2213 len);
2214
2215 if (result) {
2216 netdev_warn(hw->wlandev->netdev,
2217 "Read from index %zd failed, continuing\n",
2218 i);
2219 continue;
2220 }
2221
2222
2223 pdaok = 1;
2224 morepdrs = 1;
2225 while (pdaok && morepdrs) {
2226 pdrlen = le16_to_cpu(pda[currpdr]) * 2;
2227 pdrcode = le16_to_cpu(pda[currpdr + 1]);
2228
2229 if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
2230 netdev_err(hw->wlandev->netdev,
2231 "pdrlen invalid=%d\n", pdrlen);
2232 pdaok = 0;
2233 break;
2234 }
2235
2236 if (!hfa384x_isgood_pdrcode(pdrcode)) {
2237 netdev_err(hw->wlandev->netdev, "pdrcode invalid=%d\n",
2238 pdrcode);
2239 pdaok = 0;
2240 break;
2241 }
2242
2243 if (pdrcode == HFA384x_PDR_END_OF_PDA)
2244 morepdrs = 0;
2245
2246
2247 if (morepdrs) {
2248
2249 currpdr += le16_to_cpu(pda[currpdr]) + 1;
2250 }
2251 }
2252 if (pdaok) {
2253 netdev_info(hw->wlandev->netdev,
2254 "PDA Read from 0x%08x in %s space.\n",
2255 pdaloc[i].cardaddr,
2256 pdaloc[i].auxctl == 0 ? "EXTDS" :
2257 pdaloc[i].auxctl == 1 ? "NV" :
2258 pdaloc[i].auxctl == 2 ? "PHY" :
2259 pdaloc[i].auxctl == 3 ? "ICSRAM" :
2260 "<bogus auxctl>");
2261 break;
2262 }
2263 }
2264 result = pdaok ? 0 : -ENODATA;
2265
2266 if (result)
2267 pr_debug("Failure: pda is not okay\n");
2268
2269 return result;
2270}
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len)
2295{
2296 return hfa384x_dowrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL);
2297}
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319int hfa384x_drvr_start(struct hfa384x *hw)
2320{
2321 int result, result1, result2;
2322 u16 status;
2323
2324 might_sleep();
2325
2326
2327
2328
2329
2330
2331 result =
2332 usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in,
2333 &status);
2334 if (result < 0) {
2335 netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n");
2336 goto done;
2337 }
2338 if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
2339 netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n");
2340
2341 result =
2342 usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out,
2343 &status);
2344 if (result < 0) {
2345 netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n");
2346 goto done;
2347 }
2348 if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
2349 netdev_err(hw->wlandev->netdev, "Failed to reset bulk out endpoint.\n");
2350
2351
2352 usb_kill_urb(&hw->rx_urb);
2353
2354
2355 result = submit_rx_urb(hw, GFP_KERNEL);
2356 if (result != 0) {
2357 netdev_err(hw->wlandev->netdev,
2358 "Fatal, failed to submit RX URB, result=%d\n",
2359 result);
2360 goto done;
2361 }
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373 result1 = hfa384x_cmd_initialize(hw);
2374 msleep(1000);
2375 result = hfa384x_cmd_initialize(hw);
2376 result2 = result;
2377 if (result1 != 0) {
2378 if (result2 != 0) {
2379 netdev_err(hw->wlandev->netdev,
2380 "cmd_initialize() failed on two attempts, results %d and %d\n",
2381 result1, result2);
2382 usb_kill_urb(&hw->rx_urb);
2383 goto done;
2384 } else {
2385 pr_debug("First cmd_initialize() failed (result %d),\n",
2386 result1);
2387 pr_debug("but second attempt succeeded. All should be ok\n");
2388 }
2389 } else if (result2 != 0) {
2390 netdev_warn(hw->wlandev->netdev, "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
2391 result2);
2392 netdev_warn(hw->wlandev->netdev,
2393 "Most likely the card will be functional\n");
2394 goto done;
2395 }
2396
2397 hw->state = HFA384x_STATE_RUNNING;
2398
2399done:
2400 return result;
2401}
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423int hfa384x_drvr_stop(struct hfa384x *hw)
2424{
2425 int i;
2426
2427 might_sleep();
2428
2429
2430
2431
2432 if (!hw->wlandev->hwremoved) {
2433
2434 hfa384x_cmd_initialize(hw);
2435
2436
2437 usb_kill_urb(&hw->rx_urb);
2438 }
2439
2440 hw->link_status = HFA384x_LINK_NOTCONNECTED;
2441 hw->state = HFA384x_STATE_INIT;
2442
2443 del_timer_sync(&hw->commsqual_timer);
2444
2445
2446 for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
2447 hw->port_enabled[i] = 0;
2448
2449 return 0;
2450}
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474int hfa384x_drvr_txframe(struct hfa384x *hw, struct sk_buff *skb,
2475 union p80211_hdr *p80211_hdr,
2476 struct p80211_metawep *p80211_wep)
2477{
2478 int usbpktlen = sizeof(struct hfa384x_tx_frame);
2479 int result;
2480 int ret;
2481 char *ptr;
2482
2483 if (hw->tx_urb.status == -EINPROGRESS) {
2484 netdev_warn(hw->wlandev->netdev, "TX URB already in use\n");
2485 result = 3;
2486 goto exit;
2487 }
2488
2489
2490
2491 memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
2492
2493
2494 hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM);
2495
2496
2497 hw->txbuff.txfrm.desc.sw_support = 0x0123;
2498
2499
2500
2501
2502
2503#if defined(DOBOTH)
2504 hw->txbuff.txfrm.desc.tx_control =
2505 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2506 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
2507#elif defined(DOEXC)
2508 hw->txbuff.txfrm.desc.tx_control =
2509 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2510 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
2511#else
2512 hw->txbuff.txfrm.desc.tx_control =
2513 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2514 HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
2515#endif
2516 cpu_to_le16s(&hw->txbuff.txfrm.desc.tx_control);
2517
2518
2519 memcpy(&hw->txbuff.txfrm.desc.frame_control, p80211_hdr,
2520 sizeof(union p80211_hdr));
2521
2522
2523 if (p80211_wep->data) {
2524 hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8);
2525 usbpktlen += 8;
2526 } else {
2527 hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len);
2528 }
2529
2530 usbpktlen += skb->len;
2531
2532
2533 ptr = hw->txbuff.txfrm.data;
2534 if (p80211_wep->data) {
2535 memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
2536 ptr += sizeof(p80211_wep->iv);
2537 memcpy(ptr, p80211_wep->data, skb->len);
2538 } else {
2539 memcpy(ptr, skb->data, skb->len);
2540 }
2541
2542 ptr += skb->len;
2543
2544
2545 if (p80211_wep->data)
2546 memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
2547
2548
2549 usb_fill_bulk_urb(&hw->tx_urb, hw->usb,
2550 hw->endp_out,
2551 &hw->txbuff, ROUNDUP64(usbpktlen),
2552 hfa384x_usbout_callback, hw->wlandev);
2553 hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
2554
2555 result = 1;
2556 ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
2557 if (ret != 0) {
2558 netdev_err(hw->wlandev->netdev,
2559 "submit_tx_urb() failed, error=%d\n", ret);
2560 result = 3;
2561 }
2562
2563exit:
2564 return result;
2565}
2566
2567void hfa384x_tx_timeout(struct wlandevice *wlandev)
2568{
2569 struct hfa384x *hw = wlandev->priv;
2570 unsigned long flags;
2571
2572 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2573
2574 if (!hw->wlandev->hwremoved) {
2575 int sched;
2576
2577 sched = !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags);
2578 sched |= !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags);
2579 if (sched)
2580 schedule_work(&hw->usb_work);
2581 }
2582
2583 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2584}
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600static void hfa384x_usbctlx_reaper_task(struct tasklet_struct *t)
2601{
2602 struct hfa384x *hw = from_tasklet(hw, t, reaper_bh);
2603 struct hfa384x_usbctlx *ctlx, *temp;
2604 unsigned long flags;
2605
2606 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2607
2608
2609
2610
2611 list_for_each_entry_safe(ctlx, temp, &hw->ctlxq.reapable, list) {
2612 list_del(&ctlx->list);
2613 kfree(ctlx);
2614 }
2615
2616 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2617}
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634static void hfa384x_usbctlx_completion_task(struct tasklet_struct *t)
2635{
2636 struct hfa384x *hw = from_tasklet(hw, t, completion_bh);
2637 struct hfa384x_usbctlx *ctlx, *temp;
2638 unsigned long flags;
2639
2640 int reap = 0;
2641
2642 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2643
2644
2645
2646
2647 list_for_each_entry_safe(ctlx, temp, &hw->ctlxq.completing, list) {
2648
2649
2650
2651 if (ctlx->cmdcb) {
2652 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2653 ctlx->cmdcb(hw, ctlx);
2654 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2655
2656
2657
2658
2659 ctlx->cmdcb = NULL;
2660
2661
2662
2663
2664 if (hw->wlandev->hwremoved) {
2665 reap = 0;
2666 break;
2667 }
2668 }
2669
2670
2671
2672
2673
2674
2675 if (ctlx->reapable) {
2676
2677
2678
2679
2680
2681 list_move_tail(&ctlx->list, &hw->ctlxq.reapable);
2682 reap = 1;
2683 }
2684
2685 complete(&ctlx->done);
2686 }
2687 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2688
2689 if (reap)
2690 tasklet_schedule(&hw->reaper_bh);
2691}
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711static int unlocked_usbctlx_cancel_async(struct hfa384x *hw,
2712 struct hfa384x_usbctlx *ctlx)
2713{
2714 int ret;
2715
2716
2717
2718
2719
2720
2721 hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
2722 ret = usb_unlink_urb(&hw->ctlx_urb);
2723
2724 if (ret != -EINPROGRESS) {
2725
2726
2727
2728
2729
2730
2731 ctlx->state = CTLX_REQ_FAILED;
2732 unlocked_usbctlx_complete(hw, ctlx);
2733 ret = 0;
2734 }
2735
2736 return ret;
2737}
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762static void unlocked_usbctlx_complete(struct hfa384x *hw,
2763 struct hfa384x_usbctlx *ctlx)
2764{
2765
2766
2767
2768
2769 list_move_tail(&ctlx->list, &hw->ctlxq.completing);
2770 tasklet_schedule(&hw->completion_bh);
2771
2772 switch (ctlx->state) {
2773 case CTLX_COMPLETE:
2774 case CTLX_REQ_FAILED:
2775
2776 break;
2777
2778 default:
2779 netdev_err(hw->wlandev->netdev, "CTLX[%d] not in a terminating state(%s)\n",
2780 le16_to_cpu(ctlx->outbuf.type),
2781 ctlxstr(ctlx->state));
2782 break;
2783 }
2784}
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803static void hfa384x_usbctlxq_run(struct hfa384x *hw)
2804{
2805 unsigned long flags;
2806
2807
2808 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2809
2810
2811
2812
2813
2814
2815
2816
2817 if (!list_empty(&hw->ctlxq.active) ||
2818 test_bit(WORK_TX_HALT, &hw->usb_flags) || hw->wlandev->hwremoved)
2819 goto unlock;
2820
2821 while (!list_empty(&hw->ctlxq.pending)) {
2822 struct hfa384x_usbctlx *head;
2823 int result;
2824
2825
2826 head = list_entry(hw->ctlxq.pending.next,
2827 struct hfa384x_usbctlx, list);
2828
2829
2830 list_move_tail(&head->list, &hw->ctlxq.active);
2831
2832
2833 usb_fill_bulk_urb(&hw->ctlx_urb, hw->usb,
2834 hw->endp_out,
2835 &head->outbuf, ROUNDUP64(head->outbufsize),
2836 hfa384x_ctlxout_callback, hw);
2837 hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
2838
2839
2840 result = usb_submit_urb(&hw->ctlx_urb, GFP_ATOMIC);
2841 if (result == 0) {
2842
2843 head->state = CTLX_REQ_SUBMITTED;
2844
2845
2846 hw->req_timer_done = 0;
2847 hw->reqtimer.expires = jiffies + HZ;
2848 add_timer(&hw->reqtimer);
2849
2850
2851 hw->resp_timer_done = 0;
2852 hw->resptimer.expires = jiffies + 2 * HZ;
2853 add_timer(&hw->resptimer);
2854
2855 break;
2856 }
2857
2858 if (result == -EPIPE) {
2859
2860
2861
2862
2863 netdev_warn(hw->wlandev->netdev,
2864 "%s tx pipe stalled: requesting reset\n",
2865 hw->wlandev->netdev->name);
2866 list_move(&head->list, &hw->ctlxq.pending);
2867 set_bit(WORK_TX_HALT, &hw->usb_flags);
2868 schedule_work(&hw->usb_work);
2869 break;
2870 }
2871
2872 if (result == -ESHUTDOWN) {
2873 netdev_warn(hw->wlandev->netdev, "%s urb shutdown!\n",
2874 hw->wlandev->netdev->name);
2875 break;
2876 }
2877
2878 netdev_err(hw->wlandev->netdev, "Failed to submit CTLX[%d]: error=%d\n",
2879 le16_to_cpu(head->outbuf.type), result);
2880 unlocked_usbctlx_complete(hw, head);
2881 }
2882
2883unlock:
2884 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2885}
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904static void hfa384x_usbin_callback(struct urb *urb)
2905{
2906 struct wlandevice *wlandev = urb->context;
2907 struct hfa384x *hw;
2908 union hfa384x_usbin *usbin;
2909 struct sk_buff *skb = NULL;
2910 int result;
2911 int urb_status;
2912 u16 type;
2913
2914 enum USBIN_ACTION {
2915 HANDLE,
2916 RESUBMIT,
2917 ABORT
2918 } action;
2919
2920 if (!wlandev || !wlandev->netdev || wlandev->hwremoved)
2921 goto exit;
2922
2923 hw = wlandev->priv;
2924 if (!hw)
2925 goto exit;
2926
2927 skb = hw->rx_urb_skb;
2928 if (!skb || (skb->data != urb->transfer_buffer)) {
2929 WARN_ON(1);
2930 return;
2931 }
2932
2933 hw->rx_urb_skb = NULL;
2934
2935
2936 switch (urb->status) {
2937 case 0:
2938 action = HANDLE;
2939
2940
2941 if (urb->actual_length == 0) {
2942 wlandev->netdev->stats.rx_errors++;
2943 wlandev->netdev->stats.rx_length_errors++;
2944 action = RESUBMIT;
2945 }
2946 break;
2947
2948 case -EPIPE:
2949 netdev_warn(hw->wlandev->netdev, "%s rx pipe stalled: requesting reset\n",
2950 wlandev->netdev->name);
2951 if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
2952 schedule_work(&hw->usb_work);
2953 wlandev->netdev->stats.rx_errors++;
2954 action = ABORT;
2955 break;
2956
2957 case -EILSEQ:
2958 case -ETIMEDOUT:
2959 case -EPROTO:
2960 if (!test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
2961 !timer_pending(&hw->throttle)) {
2962 mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
2963 }
2964 wlandev->netdev->stats.rx_errors++;
2965 action = ABORT;
2966 break;
2967
2968 case -EOVERFLOW:
2969 wlandev->netdev->stats.rx_over_errors++;
2970 action = RESUBMIT;
2971 break;
2972
2973 case -ENODEV:
2974 case -ESHUTDOWN:
2975 pr_debug("status=%d, device removed.\n", urb->status);
2976 action = ABORT;
2977 break;
2978
2979 case -ENOENT:
2980 case -ECONNRESET:
2981 pr_debug("status=%d, urb explicitly unlinked.\n", urb->status);
2982 action = ABORT;
2983 break;
2984
2985 default:
2986 pr_debug("urb status=%d, transfer flags=0x%x\n",
2987 urb->status, urb->transfer_flags);
2988 wlandev->netdev->stats.rx_errors++;
2989 action = RESUBMIT;
2990 break;
2991 }
2992
2993
2994 urb_status = urb->status;
2995 usbin = (union hfa384x_usbin *)urb->transfer_buffer;
2996
2997 if (action != ABORT) {
2998
2999 result = submit_rx_urb(hw, GFP_ATOMIC);
3000
3001 if (result != 0) {
3002 netdev_err(hw->wlandev->netdev,
3003 "Fatal, failed to resubmit rx_urb. error=%d\n",
3004 result);
3005 }
3006 }
3007
3008
3009
3010
3011
3012 type = le16_to_cpu(usbin->type);
3013 if (HFA384x_USB_ISRXFRM(type)) {
3014 if (action == HANDLE) {
3015 if (usbin->txfrm.desc.sw_support == 0x0123) {
3016 hfa384x_usbin_txcompl(wlandev, usbin);
3017 } else {
3018 skb_put(skb, sizeof(*usbin));
3019 hfa384x_usbin_rx(wlandev, skb);
3020 skb = NULL;
3021 }
3022 }
3023 goto exit;
3024 }
3025 if (HFA384x_USB_ISTXFRM(type)) {
3026 if (action == HANDLE)
3027 hfa384x_usbin_txcompl(wlandev, usbin);
3028 goto exit;
3029 }
3030 switch (type) {
3031 case HFA384x_USB_INFOFRM:
3032 if (action == ABORT)
3033 goto exit;
3034 if (action == HANDLE)
3035 hfa384x_usbin_info(wlandev, usbin);
3036 break;
3037
3038 case HFA384x_USB_CMDRESP:
3039 case HFA384x_USB_WRIDRESP:
3040 case HFA384x_USB_RRIDRESP:
3041 case HFA384x_USB_WMEMRESP:
3042 case HFA384x_USB_RMEMRESP:
3043
3044 hfa384x_usbin_ctlx(hw, usbin, urb_status);
3045 break;
3046
3047 case HFA384x_USB_BUFAVAIL:
3048 pr_debug("Received BUFAVAIL packet, frmlen=%d\n",
3049 usbin->bufavail.frmlen);
3050 break;
3051
3052 case HFA384x_USB_ERROR:
3053 pr_debug("Received USB_ERROR packet, errortype=%d\n",
3054 usbin->usberror.errortype);
3055 break;
3056
3057 default:
3058 pr_debug("Unrecognized USBIN packet, type=%x, status=%d\n",
3059 usbin->type, urb_status);
3060 break;
3061 }
3062
3063exit:
3064
3065 if (skb)
3066 dev_kfree_skb(skb);
3067}
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin,
3091 int urb_status)
3092{
3093 struct hfa384x_usbctlx *ctlx;
3094 int run_queue = 0;
3095 unsigned long flags;
3096
3097retry:
3098 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3099
3100
3101
3102
3103
3104 if (list_empty(&hw->ctlxq.active))
3105 goto unlock;
3106
3107
3108
3109
3110
3111
3112
3113 if (del_timer(&hw->resptimer) == 0) {
3114 if (hw->resp_timer_done == 0) {
3115 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3116 goto retry;
3117 }
3118 } else {
3119 hw->resp_timer_done = 1;
3120 }
3121
3122 ctlx = get_active_ctlx(hw);
3123
3124 if (urb_status != 0) {
3125
3126
3127
3128
3129
3130 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
3131 run_queue = 1;
3132 } else {
3133 const __le16 intype = (usbin->type & ~cpu_to_le16(0x8000));
3134
3135
3136
3137
3138 if (ctlx->outbuf.type != intype) {
3139 netdev_warn(hw->wlandev->netdev,
3140 "Expected IN[%d], received IN[%d] - ignored.\n",
3141 le16_to_cpu(ctlx->outbuf.type),
3142 le16_to_cpu(intype));
3143 goto unlock;
3144 }
3145
3146
3147 memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf));
3148
3149 switch (ctlx->state) {
3150 case CTLX_REQ_SUBMITTED:
3151
3152
3153
3154
3155
3156 pr_debug("Causality violation: please reboot Universe\n");
3157 ctlx->state = CTLX_RESP_COMPLETE;
3158 break;
3159
3160 case CTLX_REQ_COMPLETE:
3161
3162
3163
3164
3165
3166 ctlx->state = CTLX_COMPLETE;
3167 unlocked_usbctlx_complete(hw, ctlx);
3168 run_queue = 1;
3169 break;
3170
3171 default:
3172
3173
3174
3175 netdev_err(hw->wlandev->netdev,
3176 "Matched IN URB, CTLX[%d] in invalid state(%s). Discarded.\n",
3177 le16_to_cpu(ctlx->outbuf.type),
3178 ctlxstr(ctlx->state));
3179 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
3180 run_queue = 1;
3181 break;
3182 }
3183 }
3184
3185unlock:
3186 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3187
3188 if (run_queue)
3189 hfa384x_usbctlxq_run(hw);
3190}
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210static void hfa384x_usbin_txcompl(struct wlandevice *wlandev,
3211 union hfa384x_usbin *usbin)
3212{
3213 u16 status;
3214
3215 status = le16_to_cpu(usbin->type);
3216
3217
3218 if (HFA384x_TXSTATUS_ISERROR(status))
3219 prism2sta_ev_txexc(wlandev, status);
3220 else
3221 prism2sta_ev_tx(wlandev, status);
3222}
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb)
3243{
3244 union hfa384x_usbin *usbin = (union hfa384x_usbin *)skb->data;
3245 struct hfa384x *hw = wlandev->priv;
3246 int hdrlen;
3247 struct p80211_rxmeta *rxmeta;
3248 u16 data_len;
3249 u16 fc;
3250 u16 status;
3251
3252
3253 le16_to_cpus(&usbin->rxfrm.desc.status);
3254 le32_to_cpus(&usbin->rxfrm.desc.time);
3255
3256
3257 status = HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status);
3258
3259 switch (status) {
3260 case 0:
3261 fc = le16_to_cpu(usbin->rxfrm.desc.frame_control);
3262
3263
3264 if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
3265 !WLAN_GET_FC_ISWEP(fc)) {
3266 break;
3267 }
3268
3269 data_len = le16_to_cpu(usbin->rxfrm.desc.data_len);
3270
3271
3272 hdrlen = p80211_headerlen(fc);
3273
3274
3275 skb_pull(skb, sizeof(struct hfa384x_rx_frame));
3276
3277
3278
3279
3280 memmove(skb_push(skb, hdrlen),
3281 &usbin->rxfrm.desc.frame_control, hdrlen);
3282
3283 skb->dev = wlandev->netdev;
3284
3285
3286 skb_trim(skb, data_len + hdrlen);
3287
3288
3289 memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN);
3290
3291 skb_reset_mac_header(skb);
3292
3293
3294 p80211skb_rxmeta_attach(wlandev, skb);
3295 rxmeta = p80211skb_rxmeta(skb);
3296 rxmeta->mactime = usbin->rxfrm.desc.time;
3297 rxmeta->rxrate = usbin->rxfrm.desc.rate;
3298 rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust;
3299 rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust;
3300
3301 p80211netdev_rx(wlandev, skb);
3302
3303 break;
3304
3305 case 7:
3306 if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) {
3307
3308 hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm);
3309 dev_kfree_skb(skb);
3310 } else {
3311 pr_debug("Received monitor frame: FCSerr set\n");
3312 }
3313 break;
3314
3315 default:
3316 netdev_warn(hw->wlandev->netdev,
3317 "Received frame on unsupported port=%d\n",
3318 status);
3319 break;
3320 }
3321}
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345static void hfa384x_int_rxmonitor(struct wlandevice *wlandev,
3346 struct hfa384x_usb_rxfrm *rxfrm)
3347{
3348 struct hfa384x_rx_frame *rxdesc = &rxfrm->desc;
3349 unsigned int hdrlen = 0;
3350 unsigned int datalen = 0;
3351 unsigned int skblen = 0;
3352 u8 *datap;
3353 u16 fc;
3354 struct sk_buff *skb;
3355 struct hfa384x *hw = wlandev->priv;
3356
3357
3358
3359 fc = le16_to_cpu(rxdesc->frame_control);
3360 hdrlen = p80211_headerlen(fc);
3361 datalen = le16_to_cpu(rxdesc->data_len);
3362
3363
3364 skblen = sizeof(struct p80211_caphdr) + hdrlen + datalen + WLAN_CRC_LEN;
3365
3366
3367 if (skblen >
3368 (sizeof(struct p80211_caphdr) +
3369 WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
3370 pr_debug("overlen frm: len=%zd\n",
3371 skblen - sizeof(struct p80211_caphdr));
3372
3373 return;
3374 }
3375
3376 skb = dev_alloc_skb(skblen);
3377 if (!skb)
3378 return;
3379
3380
3381 if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
3382 (hw->sniffhdr != 0)) {
3383 struct p80211_caphdr *caphdr;
3384
3385 datap = skb_put(skb, sizeof(struct p80211_caphdr));
3386 caphdr = (struct p80211_caphdr *)datap;
3387
3388 caphdr->version = htonl(P80211CAPTURE_VERSION);
3389 caphdr->length = htonl(sizeof(struct p80211_caphdr));
3390 caphdr->mactime = __cpu_to_be64(rxdesc->time * 1000);
3391 caphdr->hosttime = __cpu_to_be64(jiffies);
3392 caphdr->phytype = htonl(4);
3393 caphdr->channel = htonl(hw->sniff_channel);
3394 caphdr->datarate = htonl(rxdesc->rate);
3395 caphdr->antenna = htonl(0);
3396 caphdr->priority = htonl(0);
3397 caphdr->ssi_type = htonl(3);
3398 caphdr->ssi_signal = htonl(rxdesc->signal);
3399 caphdr->ssi_noise = htonl(rxdesc->silence);
3400 caphdr->preamble = htonl(0);
3401 caphdr->encoding = htonl(1);
3402 }
3403
3404
3405
3406
3407 skb_put_data(skb, &rxdesc->frame_control, hdrlen);
3408
3409
3410 if (datalen > 0) {
3411 datap = skb_put_data(skb, rxfrm->data, datalen);
3412
3413
3414 if (*(datap - hdrlen + 1) & 0x40)
3415 if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
3416
3417 *(datap - hdrlen + 1) &= 0xbf;
3418 }
3419
3420 if (hw->sniff_fcs) {
3421
3422 datap = skb_put(skb, WLAN_CRC_LEN);
3423 memset(datap, 0xff, WLAN_CRC_LEN);
3424 }
3425
3426
3427 p80211netdev_rx(wlandev, skb);
3428}
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448static void hfa384x_usbin_info(struct wlandevice *wlandev,
3449 union hfa384x_usbin *usbin)
3450{
3451 le16_to_cpus(&usbin->infofrm.info.framelen);
3452 prism2sta_ev_info(wlandev, &usbin->infofrm.info);
3453}
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472static void hfa384x_usbout_callback(struct urb *urb)
3473{
3474 struct wlandevice *wlandev = urb->context;
3475
3476#ifdef DEBUG_USB
3477 dbprint_urb(urb);
3478#endif
3479
3480 if (wlandev && wlandev->netdev) {
3481 switch (urb->status) {
3482 case 0:
3483 prism2sta_ev_alloc(wlandev);
3484 break;
3485
3486 case -EPIPE: {
3487 struct hfa384x *hw = wlandev->priv;
3488
3489 netdev_warn(hw->wlandev->netdev,
3490 "%s tx pipe stalled: requesting reset\n",
3491 wlandev->netdev->name);
3492 if (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags))
3493 schedule_work(&hw->usb_work);
3494 wlandev->netdev->stats.tx_errors++;
3495 break;
3496 }
3497
3498 case -EPROTO:
3499 case -ETIMEDOUT:
3500 case -EILSEQ: {
3501 struct hfa384x *hw = wlandev->priv;
3502
3503 if (!test_and_set_bit(THROTTLE_TX, &hw->usb_flags) &&
3504 !timer_pending(&hw->throttle)) {
3505 mod_timer(&hw->throttle,
3506 jiffies + THROTTLE_JIFFIES);
3507 }
3508 wlandev->netdev->stats.tx_errors++;
3509 netif_stop_queue(wlandev->netdev);
3510 break;
3511 }
3512
3513 case -ENOENT:
3514 case -ESHUTDOWN:
3515
3516 break;
3517
3518 default:
3519 netdev_info(wlandev->netdev, "unknown urb->status=%d\n",
3520 urb->status);
3521 wlandev->netdev->stats.tx_errors++;
3522 break;
3523 }
3524 }
3525}
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544static void hfa384x_ctlxout_callback(struct urb *urb)
3545{
3546 struct hfa384x *hw = urb->context;
3547 int delete_resptimer = 0;
3548 int timer_ok = 1;
3549 int run_queue = 0;
3550 struct hfa384x_usbctlx *ctlx;
3551 unsigned long flags;
3552
3553 pr_debug("urb->status=%d\n", urb->status);
3554#ifdef DEBUG_USB
3555 dbprint_urb(urb);
3556#endif
3557 if ((urb->status == -ESHUTDOWN) ||
3558 (urb->status == -ENODEV) || !hw)
3559 return;
3560
3561retry:
3562 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3563
3564
3565
3566
3567
3568
3569
3570 if (list_empty(&hw->ctlxq.active)) {
3571 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3572 return;
3573 }
3574
3575
3576
3577
3578
3579 if (del_timer(&hw->reqtimer) == 0) {
3580 if (hw->req_timer_done == 0) {
3581
3582
3583
3584
3585
3586 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3587 goto retry;
3588 }
3589 } else {
3590 hw->req_timer_done = 1;
3591 }
3592
3593 ctlx = get_active_ctlx(hw);
3594
3595 if (urb->status == 0) {
3596
3597 switch (ctlx->state) {
3598 case CTLX_REQ_SUBMITTED:
3599
3600 ctlx->state = CTLX_REQ_COMPLETE;
3601 break;
3602
3603 case CTLX_RESP_COMPLETE:
3604
3605
3606
3607 ctlx->state = CTLX_COMPLETE;
3608 unlocked_usbctlx_complete(hw, ctlx);
3609 run_queue = 1;
3610 break;
3611
3612 default:
3613
3614 netdev_err(hw->wlandev->netdev,
3615 "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
3616 le16_to_cpu(ctlx->outbuf.type),
3617 ctlxstr(ctlx->state), urb->status);
3618 break;
3619 }
3620 } else {
3621
3622 if ((urb->status == -EPIPE) &&
3623 !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
3624 netdev_warn(hw->wlandev->netdev,
3625 "%s tx pipe stalled: requesting reset\n",
3626 hw->wlandev->netdev->name);
3627 schedule_work(&hw->usb_work);
3628 }
3629
3630
3631
3632
3633 ctlx->state = CTLX_REQ_FAILED;
3634 unlocked_usbctlx_complete(hw, ctlx);
3635 delete_resptimer = 1;
3636 run_queue = 1;
3637 }
3638
3639delresp:
3640 if (delete_resptimer) {
3641 timer_ok = del_timer(&hw->resptimer);
3642 if (timer_ok != 0)
3643 hw->resp_timer_done = 1;
3644 }
3645
3646 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3647
3648 if (!timer_ok && (hw->resp_timer_done == 0)) {
3649 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3650 goto delresp;
3651 }
3652
3653 if (run_queue)
3654 hfa384x_usbctlxq_run(hw);
3655}
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676static void hfa384x_usbctlx_reqtimerfn(struct timer_list *t)
3677{
3678 struct hfa384x *hw = from_timer(hw, t, reqtimer);
3679 unsigned long flags;
3680
3681 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3682
3683 hw->req_timer_done = 1;
3684
3685
3686
3687
3688 if (!list_empty(&hw->ctlxq.active)) {
3689
3690
3691
3692
3693 hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
3694 if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
3695 struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw);
3696
3697 ctlx->state = CTLX_REQ_FAILED;
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708 if (del_timer(&hw->resptimer) != 0)
3709 hw->resp_timer_done = 1;
3710 }
3711 }
3712
3713 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3714}
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735static void hfa384x_usbctlx_resptimerfn(struct timer_list *t)
3736{
3737 struct hfa384x *hw = from_timer(hw, t, resptimer);
3738 unsigned long flags;
3739
3740 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3741
3742 hw->resp_timer_done = 1;
3743
3744
3745
3746
3747 if (!list_empty(&hw->ctlxq.active)) {
3748 struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw);
3749
3750 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
3751 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3752 hfa384x_usbctlxq_run(hw);
3753 return;
3754 }
3755 }
3756 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3757}
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775static void hfa384x_usb_throttlefn(struct timer_list *t)
3776{
3777 struct hfa384x *hw = from_timer(hw, t, throttle);
3778 unsigned long flags;
3779
3780 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3781
3782
3783
3784
3785
3786 pr_debug("flags=0x%lx\n", hw->usb_flags);
3787 if (!hw->wlandev->hwremoved &&
3788 ((test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
3789 !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags)) |
3790 (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
3791 !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
3792 )) {
3793 schedule_work(&hw->usb_work);
3794 }
3795
3796 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3797}
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818static int hfa384x_usbctlx_submit(struct hfa384x *hw,
3819 struct hfa384x_usbctlx *ctlx)
3820{
3821 unsigned long flags;
3822
3823 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3824
3825 if (hw->wlandev->hwremoved) {
3826 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3827 return -ENODEV;
3828 }
3829
3830 ctlx->state = CTLX_PENDING;
3831 list_add_tail(&ctlx->list, &hw->ctlxq.pending);
3832 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3833 hfa384x_usbctlxq_run(hw);
3834
3835 return 0;
3836}
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855static int hfa384x_isgood_pdrcode(u16 pdrcode)
3856{
3857 switch (pdrcode) {
3858 case HFA384x_PDR_END_OF_PDA:
3859 case HFA384x_PDR_PCB_PARTNUM:
3860 case HFA384x_PDR_PDAVER:
3861 case HFA384x_PDR_NIC_SERIAL:
3862 case HFA384x_PDR_MKK_MEASUREMENTS:
3863 case HFA384x_PDR_NIC_RAMSIZE:
3864 case HFA384x_PDR_MFISUPRANGE:
3865 case HFA384x_PDR_CFISUPRANGE:
3866 case HFA384x_PDR_NICID:
3867 case HFA384x_PDR_MAC_ADDRESS:
3868 case HFA384x_PDR_REGDOMAIN:
3869 case HFA384x_PDR_ALLOWED_CHANNEL:
3870 case HFA384x_PDR_DEFAULT_CHANNEL:
3871 case HFA384x_PDR_TEMPTYPE:
3872 case HFA384x_PDR_IFR_SETTING:
3873 case HFA384x_PDR_RFR_SETTING:
3874 case HFA384x_PDR_HFA3861_BASELINE:
3875 case HFA384x_PDR_HFA3861_SHADOW:
3876 case HFA384x_PDR_HFA3861_IFRF:
3877 case HFA384x_PDR_HFA3861_CHCALSP:
3878 case HFA384x_PDR_HFA3861_CHCALI:
3879 case HFA384x_PDR_3842_NIC_CONFIG:
3880 case HFA384x_PDR_USB_ID:
3881 case HFA384x_PDR_PCI_ID:
3882 case HFA384x_PDR_PCI_IFCONF:
3883 case HFA384x_PDR_PCI_PMCONF:
3884 case HFA384x_PDR_RFENRGY:
3885 case HFA384x_PDR_HFA3861_MANF_TESTSP:
3886 case HFA384x_PDR_HFA3861_MANF_TESTI:
3887
3888 return 1;
3889 default:
3890 if (pdrcode < 0x1000) {
3891
3892 pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n",
3893 pdrcode);
3894 return 1;
3895 }
3896 break;
3897 }
3898
3899 pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
3900 pdrcode);
3901 return 0;
3902}
3903