mwifiex: complete usb tx data with multi endpoints
authorZhaoyang Liu <liuzy@marvell.com>
Fri, 18 Sep 2015 13:32:18 +0000 (06:32 -0700)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 29 Sep 2015 07:47:49 +0000 (10:47 +0300)
This patch do the work to TX data with specific USB
endpoint. At the same time, update data_sent flag
according to multi port status. And is_port_ready
API is added for BSS interface to check if current
used usb data endpoint is available or not.

Signed-off-by: Zhaoyang Liu <liuzy@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_tx.c
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/uap_event.c
drivers/net/wireless/mwifiex/usb.c
drivers/net/wireless/mwifiex/wmm.c

index 46221c2d0f90575ce897c9219666f36a92940cde..2c5ffa13f7b51aef636f735121008188bffc3002 100644 (file)
@@ -259,7 +259,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
        }
 
        if (adapter->iface_type == MWIFIEX_USB) {
-               ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+               ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
                                                   skb_aggr, NULL);
        } else {
                if (skb_src)
index 88130028cd890a011ee0815ff6a625f156eb5537..3959f1c97f4ea588dbc7f0b379659496a96fea4e 100644 (file)
@@ -817,6 +817,7 @@ struct mwifiex_if_ops {
        void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
        void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
        void (*multi_port_resync)(struct mwifiex_adapter *);
+       bool (*is_port_ready)(struct mwifiex_private *);
 };
 
 struct mwifiex_adapter {
index c333b249245197a8471efbd78af58d6741fcf000..ff3ee9dfbbd54f51dbd42f8ff5478d78bc63013b 100644 (file)
@@ -616,7 +616,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                adapter->tx_lock_flag = false;
                if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
                        if (mwifiex_check_last_packet_indication(priv)) {
-                               if (adapter->data_sent) {
+                               if (adapter->data_sent ||
+                                   (adapter->if_ops.is_port_ready &&
+                                    !adapter->if_ops.is_port_ready(priv))) {
                                        adapter->ps_state = PS_STATE_AWAKE;
                                        adapter->pm_wakeup_card_req = false;
                                        adapter->pm_wakeup_fw_try = false;
index 877ad06336a97951d2b5bf10ea8cdb474de30645..f6683ea6bd5ddfb64a64c0168ea26db346c45281 100644 (file)
@@ -153,6 +153,10 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
        if (adapter->data_sent)
                return -1;
 
+       if (adapter->if_ops.is_port_ready &&
+           !adapter->if_ops.is_port_ready(priv))
+               return -1;
+
        skb = dev_alloc_skb(data_len);
        if (!skb)
                return -1;
@@ -174,7 +178,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
        local_tx_pd->bss_type = priv->bss_type;
 
        if (adapter->iface_type == MWIFIEX_USB) {
-               ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+               ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
                                                   skb, NULL);
        } else {
                skb_push(skb, INTF_HEADER_LEN);
index 90f4915aea58b40c356fca01762f218ed3c5559e..bf6182b646a5436ad083623fa2c2980ce8019f28 100644 (file)
@@ -116,7 +116,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
                        local_tx_pd = (struct txpd *)(head_ptr + hroom);
                if (adapter->iface_type == MWIFIEX_USB) {
                        ret = adapter->if_ops.host_to_card(adapter,
-                                                          MWIFIEX_USB_EP_DATA,
+                                                          priv->usb_port,
                                                           skb, NULL);
                } else {
                        ret = adapter->if_ops.host_to_card(adapter,
@@ -189,7 +189,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
 
        if (adapter->iface_type == MWIFIEX_USB) {
                ret = adapter->if_ops.host_to_card(adapter,
-                                                  MWIFIEX_USB_EP_DATA,
+                                                  priv->usb_port,
                                                   skb, NULL);
        } else {
                ret = adapter->if_ops.host_to_card(adapter,
index 46c972a650a43c2918bb7703c98eeb877ccb79e6..078834cf125189d6c265fdc1c54476611324ed10 100644 (file)
@@ -269,7 +269,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
                adapter->tx_lock_flag = false;
                if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
                        if (mwifiex_check_last_packet_indication(priv)) {
-                               if (adapter->data_sent) {
+                               if (adapter->data_sent ||
+                                   (adapter->if_ops.is_port_ready &&
+                                    !adapter->if_ops.is_port_ready(priv))) {
                                        adapter->ps_state = PS_STATE_AWAKE;
                                        adapter->pm_wakeup_card_req = false;
                                        adapter->pm_wakeup_fw_try = false;
index 78ad857f20ea03f79e9e071685e8a8b6a4a6ae15..9f5356ef0531a9b7e22b3f9cdf19a9ac94fc537e 100644 (file)
@@ -282,6 +282,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
                        port = &card->port[i];
                        if (context->ep == port->tx_data_ep) {
                                atomic_dec(&port->tx_data_urb_pending);
+                               port->block_status = false;
                                break;
                        }
                }
@@ -823,6 +824,31 @@ static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)
        }
 }
 
+static bool mwifiex_usb_is_port_ready(struct mwifiex_private *priv)
+{
+       struct usb_card_rec *card = priv->adapter->card;
+       int idx;
+
+       for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
+               if (priv->usb_port == card->port[idx].tx_data_ep)
+                       return !card->port[idx].block_status;
+       }
+
+       return false;
+}
+
+static inline u8 mwifiex_usb_data_sent(struct mwifiex_adapter *adapter)
+{
+       struct usb_card_rec *card = adapter->card;
+       int i;
+
+       for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
+               if (!card->port[i].block_status)
+                       return false;
+
+       return true;
+}
+
 /* This function write a command/data packet to card. */
 static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                                    struct sk_buff *skb,
@@ -833,7 +859,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
        struct usb_tx_data_port *port = NULL;
        u8 *data = (u8 *)skb->data;
        struct urb *tx_urb;
-       int idx;
+       int idx, ret;
 
        if (adapter->is_suspended) {
                mwifiex_dbg(adapter, ERROR,
@@ -856,8 +882,9 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                                port = &card->port[idx];
                                if (atomic_read(&port->tx_data_urb_pending)
                                    >= MWIFIEX_TX_DATA_URB) {
-                                       adapter->data_sent = true;
-                                       return -EBUSY;
+                                       port->block_status = true;
+                                       ret = -EBUSY;
+                                       goto done;
                                }
                                if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
                                        port->tx_data_ix = 0;
@@ -895,7 +922,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                        atomic_dec(&card->tx_cmd_urb_pending);
                } else {
                        atomic_dec(&port->tx_data_urb_pending);
-                       adapter->data_sent = false;
+                       port->block_status = false;
                        if (port->tx_data_ix)
                                port->tx_data_ix--;
                        else
@@ -907,12 +934,19 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
                if (ep != card->tx_cmd_ep &&
                    atomic_read(&port->tx_data_urb_pending) ==
                                                        MWIFIEX_TX_DATA_URB) {
-                       adapter->data_sent = true;
-                       return -ENOSR;
+                       port->block_status = true;
+                       ret = -ENOSR;
+                       goto done;
                }
        }
 
        return -EINPROGRESS;
+
+done:
+       if (ep != card->tx_cmd_ep)
+               adapter->data_sent = mwifiex_usb_data_sent(adapter);
+
+       return ret;
 }
 
 /* This function register usb device and initialize parameter. */
@@ -1189,6 +1223,7 @@ static struct mwifiex_if_ops usb_ops = {
        .host_to_card =         mwifiex_usb_host_to_card,
        .submit_rem_rx_urbs =   mwifiex_usb_submit_rem_rx_urbs,
        .multi_port_resync =    mwifiex_usb_port_resync,
+       .is_port_ready =        mwifiex_usb_is_port_ready,
 };
 
 /* This function initializes the USB driver module.
index 4f303f38864761cad635342981683aded8d48e7a..7bbdfe4872e47c82200c0bf469f3c2f5e6ddc8e4 100644 (file)
@@ -452,7 +452,21 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
 
 int mwifiex_bypass_txlist_empty(struct mwifiex_adapter *adapter)
 {
-       return atomic_read(&adapter->bypass_tx_pending) ? false : true;
+       struct mwifiex_private *priv;
+       int i;
+
+       for (i = 0; i < adapter->priv_num; i++) {
+               priv = adapter->priv[i];
+               if (!priv)
+                       continue;
+               if (adapter->if_ops.is_port_ready &&
+                   !adapter->if_ops.is_port_ready(priv))
+                       continue;
+               if (!skb_queue_empty(&priv->bypass_txq))
+                       return false;
+       }
+
+       return true;
 }
 
 /*
@@ -466,9 +480,14 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
 
        for (i = 0; i < adapter->priv_num; ++i) {
                priv = adapter->priv[i];
-               if (priv && !priv->port_open)
+               if (!priv)
+                       continue;
+               if (!priv->port_open)
+                       continue;
+               if (adapter->if_ops.is_port_ready &&
+                   !adapter->if_ops.is_port_ready(priv))
                        continue;
-               if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
+               if (atomic_read(&priv->wmm.tx_pkts_queued))
                        return false;
        }
 
@@ -1091,6 +1110,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                            (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0))
                                continue;
 
+                       if (adapter->if_ops.is_port_ready &&
+                           !adapter->if_ops.is_port_ready(priv_tmp))
+                               continue;
+
                        /* iterate over the WMM queues of the BSS */
                        hqp = &priv_tmp->wmm.highest_queued_prio;
                        for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
@@ -1326,7 +1349,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
 
        if (adapter->iface_type == MWIFIEX_USB) {
-               ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
+               ret = adapter->if_ops.host_to_card(adapter, priv->usb_port,
                                                   skb, NULL);
        } else {
                tx_param.next_pkt_len =
@@ -1467,6 +1490,13 @@ void mwifiex_process_bypass_tx(struct mwifiex_adapter *adapter)
        for (i = 0; i < adapter->priv_num; ++i) {
                priv = adapter->priv[i];
 
+               if (!priv)
+                       continue;
+
+               if (adapter->if_ops.is_port_ready &&
+                   !adapter->if_ops.is_port_ready(priv))
+                       continue;
+
                if (skb_queue_empty(&priv->bypass_txq))
                        continue;