Commit 735ab6bf authored by Zhaoyang Liu's avatar Zhaoyang Liu Committed by Kalle Valo

mwifiex: complete usb tx data with multi endpoints

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: default avatarZhaoyang Liu <liuzy@marvell.com>
Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 7e4e5d2c
...@@ -259,7 +259,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ...@@ -259,7 +259,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
} }
if (adapter->iface_type == MWIFIEX_USB) { 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); skb_aggr, NULL);
} else { } else {
if (skb_src) if (skb_src)
......
...@@ -817,6 +817,7 @@ struct mwifiex_if_ops { ...@@ -817,6 +817,7 @@ struct mwifiex_if_ops {
void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *); void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
void (*multi_port_resync)(struct mwifiex_adapter *); void (*multi_port_resync)(struct mwifiex_adapter *);
bool (*is_port_ready)(struct mwifiex_private *);
}; };
struct mwifiex_adapter { struct mwifiex_adapter {
......
...@@ -616,7 +616,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) ...@@ -616,7 +616,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
adapter->tx_lock_flag = false; adapter->tx_lock_flag = false;
if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
if (mwifiex_check_last_packet_indication(priv)) { 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->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false; adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false; adapter->pm_wakeup_fw_try = false;
......
...@@ -153,6 +153,10 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) ...@@ -153,6 +153,10 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
if (adapter->data_sent) if (adapter->data_sent)
return -1; return -1;
if (adapter->if_ops.is_port_ready &&
!adapter->if_ops.is_port_ready(priv))
return -1;
skb = dev_alloc_skb(data_len); skb = dev_alloc_skb(data_len);
if (!skb) if (!skb)
return -1; return -1;
...@@ -174,7 +178,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) ...@@ -174,7 +178,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
local_tx_pd->bss_type = priv->bss_type; local_tx_pd->bss_type = priv->bss_type;
if (adapter->iface_type == MWIFIEX_USB) { 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); skb, NULL);
} else { } else {
skb_push(skb, INTF_HEADER_LEN); skb_push(skb, INTF_HEADER_LEN);
......
...@@ -116,7 +116,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, ...@@ -116,7 +116,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
local_tx_pd = (struct txpd *)(head_ptr + hroom); local_tx_pd = (struct txpd *)(head_ptr + hroom);
if (adapter->iface_type == MWIFIEX_USB) { if (adapter->iface_type == MWIFIEX_USB) {
ret = adapter->if_ops.host_to_card(adapter, ret = adapter->if_ops.host_to_card(adapter,
MWIFIEX_USB_EP_DATA, priv->usb_port,
skb, NULL); skb, NULL);
} else { } else {
ret = adapter->if_ops.host_to_card(adapter, ret = adapter->if_ops.host_to_card(adapter,
...@@ -189,7 +189,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter, ...@@ -189,7 +189,7 @@ static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
if (adapter->iface_type == MWIFIEX_USB) { if (adapter->iface_type == MWIFIEX_USB) {
ret = adapter->if_ops.host_to_card(adapter, ret = adapter->if_ops.host_to_card(adapter,
MWIFIEX_USB_EP_DATA, priv->usb_port,
skb, NULL); skb, NULL);
} else { } else {
ret = adapter->if_ops.host_to_card(adapter, ret = adapter->if_ops.host_to_card(adapter,
......
...@@ -269,7 +269,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) ...@@ -269,7 +269,9 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
adapter->tx_lock_flag = false; adapter->tx_lock_flag = false;
if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
if (mwifiex_check_last_packet_indication(priv)) { 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->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false; adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false; adapter->pm_wakeup_fw_try = false;
......
...@@ -282,6 +282,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb) ...@@ -282,6 +282,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
port = &card->port[i]; port = &card->port[i];
if (context->ep == port->tx_data_ep) { if (context->ep == port->tx_data_ep) {
atomic_dec(&port->tx_data_urb_pending); atomic_dec(&port->tx_data_urb_pending);
port->block_status = false;
break; break;
} }
} }
...@@ -823,6 +824,31 @@ static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter) ...@@ -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. */ /* This function write a command/data packet to card. */
static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct sk_buff *skb, struct sk_buff *skb,
...@@ -833,7 +859,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, ...@@ -833,7 +859,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
struct usb_tx_data_port *port = NULL; struct usb_tx_data_port *port = NULL;
u8 *data = (u8 *)skb->data; u8 *data = (u8 *)skb->data;
struct urb *tx_urb; struct urb *tx_urb;
int idx; int idx, ret;
if (adapter->is_suspended) { if (adapter->is_suspended) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
...@@ -856,8 +882,9 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, ...@@ -856,8 +882,9 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
port = &card->port[idx]; port = &card->port[idx];
if (atomic_read(&port->tx_data_urb_pending) if (atomic_read(&port->tx_data_urb_pending)
>= MWIFIEX_TX_DATA_URB) { >= MWIFIEX_TX_DATA_URB) {
adapter->data_sent = true; port->block_status = true;
return -EBUSY; ret = -EBUSY;
goto done;
} }
if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB) if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
port->tx_data_ix = 0; port->tx_data_ix = 0;
...@@ -895,7 +922,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, ...@@ -895,7 +922,7 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
atomic_dec(&card->tx_cmd_urb_pending); atomic_dec(&card->tx_cmd_urb_pending);
} else { } else {
atomic_dec(&port->tx_data_urb_pending); atomic_dec(&port->tx_data_urb_pending);
adapter->data_sent = false; port->block_status = false;
if (port->tx_data_ix) if (port->tx_data_ix)
port->tx_data_ix--; port->tx_data_ix--;
else else
...@@ -907,12 +934,19 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep, ...@@ -907,12 +934,19 @@ static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
if (ep != card->tx_cmd_ep && if (ep != card->tx_cmd_ep &&
atomic_read(&port->tx_data_urb_pending) == atomic_read(&port->tx_data_urb_pending) ==
MWIFIEX_TX_DATA_URB) { MWIFIEX_TX_DATA_URB) {
adapter->data_sent = true; port->block_status = true;
return -ENOSR; ret = -ENOSR;
goto done;
} }
} }
return -EINPROGRESS; 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. */ /* This function register usb device and initialize parameter. */
...@@ -1189,6 +1223,7 @@ static struct mwifiex_if_ops usb_ops = { ...@@ -1189,6 +1223,7 @@ static struct mwifiex_if_ops usb_ops = {
.host_to_card = mwifiex_usb_host_to_card, .host_to_card = mwifiex_usb_host_to_card,
.submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs, .submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs,
.multi_port_resync = mwifiex_usb_port_resync, .multi_port_resync = mwifiex_usb_port_resync,
.is_port_ready = mwifiex_usb_is_port_ready,
}; };
/* This function initializes the USB driver module. /* This function initializes the USB driver module.
......
...@@ -452,7 +452,21 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) ...@@ -452,7 +452,21 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
int mwifiex_bypass_txlist_empty(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) ...@@ -466,9 +480,14 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; ++i) { for (i = 0; i < adapter->priv_num; ++i) {
priv = adapter->priv[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; continue;
if (priv && atomic_read(&priv->wmm.tx_pkts_queued)) if (atomic_read(&priv->wmm.tx_pkts_queued))
return false; return false;
} }
...@@ -1091,6 +1110,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, ...@@ -1091,6 +1110,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
(atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0)) (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0))
continue; 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 */ /* iterate over the WMM queues of the BSS */
hqp = &priv_tmp->wmm.highest_queued_prio; hqp = &priv_tmp->wmm.highest_queued_prio;
for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
...@@ -1326,7 +1349,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, ...@@ -1326,7 +1349,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (adapter->iface_type == MWIFIEX_USB) { 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); skb, NULL);
} else { } else {
tx_param.next_pkt_len = tx_param.next_pkt_len =
...@@ -1467,6 +1490,13 @@ void mwifiex_process_bypass_tx(struct mwifiex_adapter *adapter) ...@@ -1467,6 +1490,13 @@ void mwifiex_process_bypass_tx(struct mwifiex_adapter *adapter)
for (i = 0; i < adapter->priv_num; ++i) { for (i = 0; i < adapter->priv_num; ++i) {
priv = adapter->priv[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)) if (skb_queue_empty(&priv->bypass_txq))
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment