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