From patchwork Tue Feb 27 14:26:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitkumar Karwar X-Patchwork-Id: 10245547 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D978760384 for ; Tue, 27 Feb 2018 14:38:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8F7C2891E for ; Tue, 27 Feb 2018 14:38:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BDBB928925; Tue, 27 Feb 2018 14:38:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2EE9428923 for ; Tue, 27 Feb 2018 14:38:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753585AbeB0OiA (ORCPT ); Tue, 27 Feb 2018 09:38:00 -0500 Received: from mail-pl0-f66.google.com ([209.85.160.66]:46254 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753172AbeB0Ohu (ORCPT ); Tue, 27 Feb 2018 09:37:50 -0500 Received: by mail-pl0-f66.google.com with SMTP id y8-v6so1008944pll.13; Tue, 27 Feb 2018 06:37:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wLcDVecaySi3xzpXs9UrY+ykefegxhPjD1whOf46f/8=; b=X5yWq4hNJx68bxi9G30/uw2Vk6CaUoFFK4VyMXn3g6FZGc2MKq5OOZrifwd2JTjir7 UWJAMuLHFgCDKD92MB7774mZ+B0to3qruwM91N2eC62vcuBlON76FJeaSFM1UpMIIxr9 wbkrTnhCZGMQzpdiKJ+DqwJLb5lrolnyIl/eee2L7WmDE6pQTP4Vn/cCTNoeNrK6u1vS egTXx9TRTKGcsSGPqWUCfk07F+ACDgfFWYe9Tj+CkmiPGnkHWQplxfRyN4oGdnRleY5I z8tGEPlWzHh8kq+gRT5F9tW+1Q+2KzMptTh8Ldffywc9GpfPgDfqzzulbCo74yHkZ0u4 Vs3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wLcDVecaySi3xzpXs9UrY+ykefegxhPjD1whOf46f/8=; b=FOKXwVqQHJ6vdnby583LqoizC8k+w5sb7vawyLKnCNaNBOFn97+8gyiTtn80WH4Ksl owZ171FIRJiJk0E8xJ2AnjDf2lszQiJ/LDcBdCEJJ86jyabXSWKQKp2RvJWcb2LLx4Uv i6pYzFomEGoxH9Rnem3uUKYszecDBzv30AKh5qxnDW+iQU3FQ1JlvdHHaXDO7A82hej+ S1L2l5AHUJ2EaWKnf5oS142uGBoBsIrn6z4HLF5zgqZ7KP13XIQFIZUFgNXuGn8olBfS SmzQrDhPxiz5t62GtexjA9Px9O8k6b5eMLf/gNTpjOee9J6yMw383vN6+34OCBIYJWfA obgw== X-Gm-Message-State: APf1xPCVdVzxt5NzCd8rS/D5Gef+WZQHB2BCVLs2XYjxmPd8zJieGPfA b0qn93FbCgWvVeMW6di48kU= X-Google-Smtp-Source: AH8x226sYtGTjzyZbTG1apKdK9/V2VDhpekVo2vFrFtw6mJddhUCOBD+wBVLQRzxXOScdjuzKMjPag== X-Received: by 2002:a17:902:9898:: with SMTP id s24-v6mr14106918plp.382.1519742270066; Tue, 27 Feb 2018 06:37:50 -0800 (PST) Received: from cpu185.redpinesignals.com ([203.196.161.90]) by smtp.gmail.com with ESMTPSA id g186sm23637490pfb.168.2018.02.27.06.37.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 27 Feb 2018 06:37:49 -0800 (PST) From: Amitkumar Karwar To: Kalle Valo , marcel@holtmann.org Cc: linux-wireless@vger.kernel.org, Amitkumar Karwar , Siva Rebbagondla , linux-bluetooth@vger.kernel.org, Prameela Rani Garnepudi Subject: [v9 1/8] rsi: add rx control block to handle rx packets in USB Date: Tue, 27 Feb 2018 19:56:11 +0530 Message-Id: <1519741578-12640-2-git-send-email-amitkarwar@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519741578-12640-1-git-send-email-amitkarwar@gmail.com> References: <1519741578-12640-1-git-send-email-amitkarwar@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Prameela Rani Garnepudi Rx bluetooth endpoint shall be added in further patches. Rx control block is introduced here to handle Rx packets properly. Separate function is written to initialize the RX control blocks. Signed-off-by: Prameela Rani Garnepudi Signed-off-by: Siva Rebbagondla Signed-off-by: Amitkumar Karwar --- v9: No change since v6 v6: Removed unnecessary GFP_DMA flag for kzalloc(Kalle) v5: Same as earlier version --- drivers/net/wireless/rsi/rsi_91x_main.c | 4 +- drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 2 +- drivers/net/wireless/rsi/rsi_91x_usb.c | 75 +++++++++++++++++++++++------ drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 35 +++++++++----- drivers/net/wireless/rsi/rsi_common.h | 2 +- drivers/net/wireless/rsi/rsi_main.h | 2 +- drivers/net/wireless/rsi/rsi_usb.h | 10 +++- 7 files changed, 96 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c index 0cb8e68..0413af8 100644 --- a/drivers/net/wireless/rsi/rsi_91x_main.c +++ b/drivers/net/wireless/rsi/rsi_91x_main.c @@ -137,7 +137,7 @@ static struct sk_buff *rsi_prepare_skb(struct rsi_common *common, * * Return: 0 on success, -1 on failure. */ -int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len) +int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len) { u8 *frame_desc = NULL, extended_desc = 0; u32 index, length = 0, queueno = 0; @@ -146,7 +146,7 @@ int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len) index = 0; do { - frame_desc = &common->rx_data_pkt[index]; + frame_desc = &rx_pkt[index]; actual_length = *(u16 *)&frame_desc[0]; offset = *(u16 *)&frame_desc[2]; diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index 8e2a95c..9fbc0ef 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -118,7 +118,7 @@ static int rsi_process_pkt(struct rsi_common *common) goto fail; } - status = rsi_read_pkt(common, rcv_pkt_len); + status = rsi_read_pkt(common, common->rx_data_pkt, rcv_pkt_len); fail: kfree(common->rx_data_pkt); diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 8f84438..bbce809 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -247,12 +247,13 @@ static int rsi_usb_reg_write(struct usb_device *usbdev, */ static void rsi_rx_done_handler(struct urb *urb) { - struct rsi_hw *adapter = urb->context; - struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; + struct rx_usb_ctrl_block *rx_cb = urb->context; + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data; if (urb->status) return; + rx_cb->pend = 1; rsi_set_event(&dev->rx_thread.event); } @@ -262,10 +263,11 @@ static void rsi_rx_done_handler(struct urb *urb) * * Return: 0 on success, a negative error code on failure. */ -static int rsi_rx_urb_submit(struct rsi_hw *adapter) +static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) { struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; - struct urb *urb = dev->rx_usb_urb[0]; + struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; + struct urb *urb = rx_cb->rx_urb; int status; usb_fill_bulk_urb(urb, @@ -275,7 +277,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter) urb->transfer_buffer, 3000, rsi_rx_done_handler, - adapter); + rx_cb); status = usb_submit_urb(urb, GFP_KERNEL); if (status) @@ -484,14 +486,54 @@ static struct rsi_host_intf_ops usb_host_intf_ops = { */ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) { + u8 idx; + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; rsi_kill_thread(&dev->rx_thread); - usb_free_urb(dev->rx_usb_urb[0]); + + for (idx = 0; idx < MAX_RX_URBS; idx++) { + usb_free_urb(dev->rx_cb[idx].rx_urb); + kfree(dev->rx_cb[idx].rx_buffer); + } + kfree(adapter->priv->rx_data_pkt); kfree(dev->tx_buffer); } +static int rsi_usb_init_rx(struct rsi_hw *adapter) +{ + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; + struct rx_usb_ctrl_block *rx_cb; + u8 idx; + + for (idx = 0; idx < MAX_RX_URBS; 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; + } + return 0; + +err: + for (idx = 0; idx < MAX_RX_URBS; idx++) { + kfree(dev->rx_cb[idx].rx_buffer); + kfree(dev->rx_cb[idx].rx_urb); + } + return -1; +} + /** * rsi_init_usb_interface() - This function initializes the usb interface. * @adapter: Pointer to the adapter structure. @@ -504,7 +546,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, { struct rsi_91x_usbdev *rsi_dev; struct rsi_common *common = adapter->priv; - int status; + int status, i; rsi_dev = kzalloc(sizeof(*rsi_dev), GFP_KERNEL); if (!rsi_dev) @@ -531,12 +573,12 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, status = -ENOMEM; goto fail_tx; } - rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL); - if (!rsi_dev->rx_usb_urb[0]) { - status = -ENOMEM; - goto fail_rx; + + if (rsi_usb_init_rx(adapter)) { + rsi_dbg(ERR_ZONE, "Failed to init RX handle\n"); + return -ENOMEM; } - rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; + rsi_dev->tx_blk_size = 252; adapter->block_size = rsi_dev->tx_blk_size; @@ -564,9 +606,10 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, return 0; fail_thread: - usb_free_urb(rsi_dev->rx_usb_urb[0]); -fail_rx: - kfree(rsi_dev->tx_buffer); + for (i = 0; i < MAX_RX_URBS; i++) { + kfree(rsi_dev->rx_cb[i].rx_buffer); + kfree(rsi_dev->rx_cb[i].rx_urb); + } fail_tx: kfree(common->rx_data_pkt); return status; @@ -698,7 +741,7 @@ static int rsi_probe(struct usb_interface *pfunction, rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__); } - status = rsi_rx_urb_submit(adapter); + status = rsi_rx_urb_submit(adapter, WLAN_EP); if (status) goto err1; diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c index 465692b..d0650ea 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c @@ -29,7 +29,8 @@ void rsi_usb_rx_thread(struct rsi_common *common) { struct rsi_hw *adapter = common->priv; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; - int status; + struct rx_usb_ctrl_block *rx_cb; + int status, idx; do { rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER); @@ -37,20 +38,30 @@ void rsi_usb_rx_thread(struct rsi_common *common) if (atomic_read(&dev->rx_thread.thread_done)) goto out; - mutex_lock(&common->rx_lock); - status = rsi_read_pkt(common, 0); - if (status) { - rsi_dbg(ERR_ZONE, "%s: Failed To read data", __func__); + for (idx = 0; idx < MAX_RX_URBS; idx++) { + rx_cb = &dev->rx_cb[idx]; + if (!rx_cb->pend) + continue; + + mutex_lock(&common->rx_lock); + status = rsi_read_pkt(common, rx_cb->rx_buffer, 0); + if (status) { + rsi_dbg(ERR_ZONE, "%s: Failed To read data", + __func__); + mutex_unlock(&common->rx_lock); + break; + } + rx_cb->pend = 0; mutex_unlock(&common->rx_lock); - return; + + if (adapter->rx_urb_submit(adapter, rx_cb->ep_num)) { + rsi_dbg(ERR_ZONE, + "%s: Failed in urb submission", + __func__); + return; + } } - mutex_unlock(&common->rx_lock); rsi_reset_event(&dev->rx_thread.event); - if (adapter->rx_urb_submit(adapter)) { - rsi_dbg(ERR_ZONE, - "%s: Failed in urb submission", __func__); - return; - } } while (1); out: diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h index d07dbba..1d8af41 100644 --- a/drivers/net/wireless/rsi/rsi_common.h +++ b/drivers/net/wireless/rsi/rsi_common.h @@ -82,7 +82,7 @@ void rsi_mac80211_detach(struct rsi_hw *hw); u16 rsi_get_connected_channel(struct ieee80211_vif *vif); struct rsi_hw *rsi_91x_init(void); void rsi_91x_deinit(struct rsi_hw *adapter); -int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len); +int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len); #ifdef CONFIG_PM int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan); #endif diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h index 8cab630..ee469dc 100644 --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -343,7 +343,7 @@ struct rsi_hw { void *rsi_dev; struct rsi_host_intf_ops *host_intf_ops; int (*check_hw_queue_status)(struct rsi_hw *adapter, u8 q_num); - int (*rx_urb_submit)(struct rsi_hw *adapter); + int (*rx_urb_submit)(struct rsi_hw *adapter, u8 ep_num); int (*determine_event_timeout)(struct rsi_hw *adapter); }; diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h index 891daea..7e781d5 100644 --- a/drivers/net/wireless/rsi/rsi_usb.h +++ b/drivers/net/wireless/rsi/rsi_usb.h @@ -39,12 +39,20 @@ #define RSI_USB_BUF_SIZE 4096 #define RSI_USB_CTRL_BUF_SIZE 0x04 +struct rx_usb_ctrl_block { + u8 *data; + struct urb *rx_urb; + u8 *rx_buffer; + u8 ep_num; + u8 pend; +}; + struct rsi_91x_usbdev { struct rsi_thread rx_thread; u8 endpoint; struct usb_device *usbdev; struct usb_interface *pfunction; - struct urb *rx_usb_urb[MAX_RX_URBS]; + struct rx_usb_ctrl_block rx_cb[MAX_RX_URBS]; u8 *tx_buffer; __le16 bulkin_size; u8 bulkin_endpoint_addr;