aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-04-13 01:55:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-13 15:23:35 -0400
commit3deff76095c4ac4252e27c537db3041f619c23a2 (patch)
tree50bf835382741f7f456c6132dfa87340237471cb /drivers/net/wireless/ath
parent16c56ae87509d9bbcd8c711dc4f99b38c234d6c5 (diff)
ath9k_htc: Increase URB count for REG_IN pipe
Using a single URB for receiving WMI events is insufficient, increase it to 64 to not lose WMI events in high throughput situations. Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c99
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h4
2 files changed, 61 insertions, 42 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index e252576760d1..0b63a48462c7 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -566,6 +566,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
566 case -ESHUTDOWN: 566 case -ESHUTDOWN:
567 goto free; 567 goto free;
568 default: 568 default:
569 skb_reset_tail_pointer(skb);
570 skb_trim(skb, 0);
571
569 goto resubmit; 572 goto resubmit;
570 } 573 }
571 574
@@ -590,23 +593,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
590 USB_REG_IN_PIPE), 593 USB_REG_IN_PIPE),
591 nskb->data, MAX_REG_IN_BUF_SIZE, 594 nskb->data, MAX_REG_IN_BUF_SIZE,
592 ath9k_hif_usb_reg_in_cb, nskb); 595 ath9k_hif_usb_reg_in_cb, nskb);
593
594 ret = usb_submit_urb(urb, GFP_ATOMIC);
595 if (ret) {
596 kfree_skb(nskb);
597 urb->context = NULL;
598 }
599
600 return;
601 } 596 }
602 597
603resubmit: 598resubmit:
604 skb_reset_tail_pointer(skb); 599 usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
605 skb_trim(skb, 0);
606
607 ret = usb_submit_urb(urb, GFP_ATOMIC); 600 ret = usb_submit_urb(urb, GFP_ATOMIC);
608 if (ret) 601 if (ret) {
602 usb_unanchor_urb(urb);
609 goto free; 603 goto free;
604 }
610 605
611 return; 606 return;
612free: 607free:
@@ -747,43 +742,67 @@ err_urb:
747 return ret; 742 return ret;
748} 743}
749 744
750static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) 745static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
751{ 746{
752 if (hif_dev->reg_in_urb) { 747 usb_kill_anchored_urbs(&hif_dev->reg_in_submitted);
753 usb_kill_urb(hif_dev->reg_in_urb);
754 if (hif_dev->reg_in_urb->context)
755 kfree_skb((void *)hif_dev->reg_in_urb->context);
756 usb_free_urb(hif_dev->reg_in_urb);
757 hif_dev->reg_in_urb = NULL;
758 }
759} 748}
760 749
761static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) 750static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
762{ 751{
763 struct sk_buff *skb; 752 struct urb *urb = NULL;
753 struct sk_buff *skb = NULL;
754 int i, ret;
764 755
765 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); 756 init_usb_anchor(&hif_dev->reg_in_submitted);
766 if (hif_dev->reg_in_urb == NULL)
767 return -ENOMEM;
768 757
769 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); 758 for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
770 if (!skb)
771 goto err;
772 759
773 usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, 760 /* Allocate URB */
774 usb_rcvbulkpipe(hif_dev->udev, 761 urb = usb_alloc_urb(0, GFP_KERNEL);
775 USB_REG_IN_PIPE), 762 if (urb == NULL) {
776 skb->data, MAX_REG_IN_BUF_SIZE, 763 ret = -ENOMEM;
777 ath9k_hif_usb_reg_in_cb, skb); 764 goto err_urb;
765 }
778 766
779 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) 767 /* Allocate buffer */
780 goto err; 768 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
769 if (!skb) {
770 ret = -ENOMEM;
771 goto err_skb;
772 }
773
774 usb_fill_bulk_urb(urb, hif_dev->udev,
775 usb_rcvbulkpipe(hif_dev->udev,
776 USB_REG_IN_PIPE),
777 skb->data, MAX_REG_IN_BUF_SIZE,
778 ath9k_hif_usb_reg_in_cb, skb);
779
780 /* Anchor URB */
781 usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
782
783 /* Submit URB */
784 ret = usb_submit_urb(urb, GFP_KERNEL);
785 if (ret) {
786 usb_unanchor_urb(urb);
787 goto err_submit;
788 }
789
790 /*
791 * Drop reference count.
792 * This ensures that the URB is freed when killing them.
793 */
794 usb_free_urb(urb);
795 }
781 796
782 return 0; 797 return 0;
783 798
784err: 799err_submit:
785 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); 800 kfree_skb(skb);
786 return -ENOMEM; 801err_skb:
802 usb_free_urb(urb);
803err_urb:
804 ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
805 return ret;
787} 806}
788 807
789static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) 808static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
@@ -800,7 +819,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
800 goto err_rx; 819 goto err_rx;
801 820
802 /* Register Read */ 821 /* Register Read */
803 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) 822 if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0)
804 goto err_reg; 823 goto err_reg;
805 824
806 return 0; 825 return 0;
@@ -815,7 +834,7 @@ err:
815static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) 834static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
816{ 835{
817 usb_kill_anchored_urbs(&hif_dev->regout_submitted); 836 usb_kill_anchored_urbs(&hif_dev->regout_submitted);
818 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); 837 ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
819 ath9k_hif_usb_dealloc_tx_urbs(hif_dev); 838 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
820 ath9k_hif_usb_dealloc_rx_urbs(hif_dev); 839 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
821} 840}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index f82b32bbf4e2..8b98d646e91a 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -40,7 +40,7 @@
40#define MAX_PKT_NUM_IN_TRANSFER 10 40#define MAX_PKT_NUM_IN_TRANSFER 10
41 41
42#define MAX_REG_OUT_URB_NUM 1 42#define MAX_REG_OUT_URB_NUM 1
43#define MAX_REG_OUT_BUF_NUM 8 43#define MAX_REG_IN_URB_NUM 64
44 44
45#define MAX_REG_IN_BUF_SIZE 64 45#define MAX_REG_IN_BUF_SIZE 64
46 46
@@ -90,9 +90,9 @@ struct hif_device_usb {
90 const struct firmware *firmware; 90 const struct firmware *firmware;
91 struct htc_target *htc_handle; 91 struct htc_target *htc_handle;
92 struct hif_usb_tx tx; 92 struct hif_usb_tx tx;
93 struct urb *reg_in_urb;
94 struct usb_anchor regout_submitted; 93 struct usb_anchor regout_submitted;
95 struct usb_anchor rx_submitted; 94 struct usb_anchor rx_submitted;
95 struct usb_anchor reg_in_submitted;
96 struct sk_buff *remain_skb; 96 struct sk_buff *remain_skb;
97 const char *fw_name; 97 const char *fw_name;
98 int rx_remain_len; 98 int rx_remain_len;