summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rsi/rsi_91x_usb.c
diff options
context:
space:
mode:
authorPrameela Rani Garnepudi <prameela.j04cs@gmail.com>2018-02-28 10:38:28 +0300
committerKalle Valo <kvalo@codeaurora.org>2018-03-13 19:42:26 +0300
commita1854fae1414dd8edfff4857fd26c3e355d43e19 (patch)
tree627c05f97886ff697a894cf08a3b55f1ce57028d /drivers/net/wireless/rsi/rsi_91x_usb.c
parent8809f08cdc0b57765c190abe0853a394513f6d2f (diff)
downloadlinux-a1854fae1414dd8edfff4857fd26c3e355d43e19.tar.xz
rsi: improve RX packet handling in USB interface
Curretly, RX packet processing is done sequencially. To improve the efficiency, RX skb queue is introduced. Here, while preparing RX URB skb is allocated and used for RX buffer. When rx done handler is called, enqueue the skb to rx_q and set the thread event. RX thread is modified to dequeue packets from skb queue and process further. Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/rsi/rsi_91x_usb.c')
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c110
1 files changed, 62 insertions, 48 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 64781a3629f0..be8236f404b5 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -29,6 +29,8 @@ MODULE_PARM_DESC(dev_oper_mode,
"9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
"6[AP + BT classic], 14[AP + BT classic + BT LE]");
+static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num);
+
/**
* rsi_usb_card_write() - This function writes to the USB Card.
* @adapter: Pointer to the adapter structure.
@@ -260,12 +262,31 @@ static void rsi_rx_done_handler(struct urb *urb)
{
struct rx_usb_ctrl_block *rx_cb = urb->context;
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data;
+ int status = -EINVAL;
if (urb->status)
- return;
+ goto out;
+
+ if (urb->actual_length <= 0) {
+ rsi_dbg(INFO_ZONE, "%s: Zero length packet\n", __func__);
+ goto out;
+ }
+ if (skb_queue_len(&dev->rx_q) >= RSI_MAX_RX_PKTS) {
+ rsi_dbg(INFO_ZONE, "Max RX packets reached\n");
+ goto out;
+ }
+ skb_put(rx_cb->rx_skb, urb->actual_length);
+ skb_queue_tail(&dev->rx_q, rx_cb->rx_skb);
- rx_cb->pend = 1;
rsi_set_event(&dev->rx_thread.event);
+ status = 0;
+
+out:
+ if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num))
+ rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__);
+
+ if (status)
+ dev_kfree_skb(rx_cb->rx_skb);
}
/**
@@ -280,13 +301,26 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1];
struct urb *urb = rx_cb->rx_urb;
int status;
+ struct sk_buff *skb;
+ u8 dword_align_bytes = 0;
+
+#define RSI_MAX_RX_USB_PKT_SIZE 3000
+ skb = dev_alloc_skb(RSI_MAX_RX_USB_PKT_SIZE);
+ if (!skb)
+ return -ENOMEM;
+ skb_reserve(skb, MAX_DWORD_ALIGN_BYTES);
+ dword_align_bytes = (unsigned long)skb->data & 0x3f;
+ if (dword_align_bytes > 0)
+ skb_push(skb, dword_align_bytes);
+ urb->transfer_buffer = skb->data;
+ rx_cb->rx_skb = skb;
usb_fill_bulk_urb(urb,
dev->usbdev,
usb_rcvbulkpipe(dev->usbdev,
dev->bulkin_endpoint_addr[ep_num - 1]),
urb->transfer_buffer,
- 3000,
+ RSI_MAX_RX_USB_PKT_SIZE,
rsi_rx_done_handler,
rx_cb);
@@ -502,13 +536,9 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
rsi_kill_thread(&dev->rx_thread);
usb_free_urb(dev->rx_cb[0].rx_urb);
- kfree(dev->rx_cb[0].rx_buffer);
- if (adapter->priv->coex_mode > 1) {
+ if (adapter->priv->coex_mode > 1)
usb_free_urb(dev->rx_cb[1].rx_urb);
- kfree(dev->rx_cb[1].rx_buffer);
- }
- kfree(adapter->priv->rx_data_pkt);
kfree(dev->tx_buffer);
}
@@ -523,29 +553,29 @@ static int rsi_usb_init_rx(struct rsi_hw *adapter)
for (idx = 0; idx < num_rx_cb; idx++) {
rx_cb = &dev->rx_cb[idx];
- rx_cb->rx_buffer = kzalloc(RSI_USB_BUF_SIZE * 2,
- GFP_KERNEL);
- if (!rx_cb->rx_buffer)
- goto err;
-
rx_cb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!rx_cb->rx_urb) {
rsi_dbg(ERR_ZONE, "Failed alloc rx urb[%d]\n", idx);
goto err;
}
- rx_cb->rx_urb->transfer_buffer = rx_cb->rx_buffer;
rx_cb->ep_num = idx + 1;
rx_cb->data = (void *)dev;
}
+ skb_queue_head_init(&dev->rx_q);
+ rsi_init_event(&dev->rx_thread.event);
+ if (rsi_create_kthread(adapter->priv, &dev->rx_thread,
+ rsi_usb_rx_thread, "RX-Thread")) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
+ goto err;
+ }
+
return 0;
err:
- kfree(dev->rx_cb[0].rx_buffer);
usb_free_urb(dev->rx_cb[0].rx_urb);
- if (adapter->priv->coex_mode > 1) {
- kfree(dev->rx_cb[1].rx_buffer);
+ if (adapter->priv->coex_mode > 1)
usb_free_urb(dev->rx_cb[1].rx_urb);
- }
+
return -1;
}
@@ -560,7 +590,6 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
struct usb_interface *pfunction)
{
struct rsi_91x_usbdev *rsi_dev;
- struct rsi_common *common = adapter->priv;
int status;
rsi_dev = kzalloc(sizeof(*rsi_dev), GFP_KERNEL);
@@ -569,49 +598,37 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
adapter->rsi_dev = rsi_dev;
rsi_dev->usbdev = interface_to_usbdev(pfunction);
+ rsi_dev->priv = (void *)adapter;
- if (rsi_find_bulk_in_and_out_endpoints(pfunction, adapter))
- return -EINVAL;
+ if (rsi_find_bulk_in_and_out_endpoints(pfunction, adapter)) {
+ status = -EINVAL;
+ goto fail_eps;
+ }
adapter->device = &pfunction->dev;
usb_set_intfdata(pfunction, adapter);
- common->rx_data_pkt = kmalloc(2048, GFP_KERNEL);
- if (!common->rx_data_pkt) {
- rsi_dbg(ERR_ZONE, "%s: Failed to allocate memory\n",
- __func__);
- return -ENOMEM;
- }
-
rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL);
if (!rsi_dev->tx_buffer) {
status = -ENOMEM;
- goto fail_tx;
+ goto fail_eps;
}
if (rsi_usb_init_rx(adapter)) {
rsi_dbg(ERR_ZONE, "Failed to init RX handle\n");
- return -ENOMEM;
+ status = -ENOMEM;
+ goto fail_rx;
}
rsi_dev->tx_blk_size = 252;
adapter->block_size = rsi_dev->tx_blk_size;
/* Initializing function callbacks */
- adapter->rx_urb_submit = rsi_rx_urb_submit;
adapter->check_hw_queue_status = rsi_usb_check_queue_status;
adapter->determine_event_timeout = rsi_usb_event_timeout;
adapter->rsi_host_intf = RSI_HOST_INTF_USB;
adapter->host_intf_ops = &usb_host_intf_ops;
- rsi_init_event(&rsi_dev->rx_thread.event);
- status = rsi_create_kthread(common, &rsi_dev->rx_thread,
- rsi_usb_rx_thread, "RX-Thread");
- if (status) {
- rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
- goto fail_thread;
- }
-
#ifdef CONFIG_RSI_DEBUGFS
/* In USB, one less than the MAX_DEBUGFS_ENTRIES entries is required */
adapter->num_debugfs_entries = (MAX_DEBUGFS_ENTRIES - 1);
@@ -620,15 +637,12 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
return 0;
-fail_thread:
- kfree(rsi_dev->rx_cb[0].rx_buffer);
- usb_free_urb(rsi_dev->rx_cb[0].rx_urb);
- if (common->coex_mode > 1) {
- kfree(rsi_dev->rx_cb[1].rx_buffer);
- usb_free_urb(rsi_dev->rx_cb[1].rx_urb);
- }
-fail_tx:
- kfree(common->rx_data_pkt);
+fail_rx:
+ kfree(rsi_dev->tx_buffer);
+
+fail_eps:
+ kfree(rsi_dev);
+
return status;
}