Skip to content

Commit 3deff76

Browse files
Sujith Manoharanlinvjw
authored andcommitted
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 <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent 16c56ae commit 3deff76

File tree

2 files changed

+61
-42
lines changed

2 files changed

+61
-42
lines changed

drivers/net/wireless/ath/ath9k/hif_usb.c

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
566566
case -ESHUTDOWN:
567567
goto free;
568568
default:
569+
skb_reset_tail_pointer(skb);
570+
skb_trim(skb, 0);
571+
569572
goto resubmit;
570573
}
571574

@@ -590,23 +593,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
590593
USB_REG_IN_PIPE),
591594
nskb->data, MAX_REG_IN_BUF_SIZE,
592595
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;
601596
}
602597

603598
resubmit:
604-
skb_reset_tail_pointer(skb);
605-
skb_trim(skb, 0);
606-
599+
usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
607600
ret = usb_submit_urb(urb, GFP_ATOMIC);
608-
if (ret)
601+
if (ret) {
602+
usb_unanchor_urb(urb);
609603
goto free;
604+
}
610605

611606
return;
612607
free:
@@ -747,43 +742,67 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
747742
return ret;
748743
}
749744

750-
static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
745+
static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
751746
{
752-
if (hif_dev->reg_in_urb) {
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-
}
747+
usb_kill_anchored_urbs(&hif_dev->reg_in_submitted);
759748
}
760749

761-
static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
750+
static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
762751
{
763-
struct sk_buff *skb;
752+
struct urb *urb = NULL;
753+
struct sk_buff *skb = NULL;
754+
int i, ret;
764755

765-
hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
766-
if (hif_dev->reg_in_urb == NULL)
767-
return -ENOMEM;
756+
init_usb_anchor(&hif_dev->reg_in_submitted);
768757

769-
skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
770-
if (!skb)
771-
goto err;
758+
for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
772759

773-
usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev,
774-
usb_rcvbulkpipe(hif_dev->udev,
775-
USB_REG_IN_PIPE),
776-
skb->data, MAX_REG_IN_BUF_SIZE,
777-
ath9k_hif_usb_reg_in_cb, skb);
760+
/* Allocate URB */
761+
urb = usb_alloc_urb(0, GFP_KERNEL);
762+
if (urb == NULL) {
763+
ret = -ENOMEM;
764+
goto err_urb;
765+
}
778766

779-
if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
780-
goto err;
767+
/* Allocate buffer */
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+
}
781796

782797
return 0;
783798

784-
err:
785-
ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
786-
return -ENOMEM;
799+
err_submit:
800+
kfree_skb(skb);
801+
err_skb:
802+
usb_free_urb(urb);
803+
err_urb:
804+
ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
805+
return ret;
787806
}
788807

789808
static 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)
800819
goto err_rx;
801820

802821
/* 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)
804823
goto err_reg;
805824

806825
return 0;
@@ -815,7 +834,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
815834
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
816835
{
817836
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);
819838
ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
820839
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
821840
}

drivers/net/wireless/ath/ath9k/hif_usb.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#define MAX_PKT_NUM_IN_TRANSFER 10
4141

4242
#define MAX_REG_OUT_URB_NUM 1
43-
#define MAX_REG_OUT_BUF_NUM 8
43+
#define MAX_REG_IN_URB_NUM 64
4444

4545
#define MAX_REG_IN_BUF_SIZE 64
4646

@@ -90,9 +90,9 @@ struct hif_device_usb {
9090
const struct firmware *firmware;
9191
struct htc_target *htc_handle;
9292
struct hif_usb_tx tx;
93-
struct urb *reg_in_urb;
9493
struct usb_anchor regout_submitted;
9594
struct usb_anchor rx_submitted;
95+
struct usb_anchor reg_in_submitted;
9696
struct sk_buff *remain_skb;
9797
const char *fw_name;
9898
int rx_remain_len;

0 commit comments

Comments
 (0)