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