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: 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>
This commit is contained in:
parent
7e4e5d2cd0
commit
735ab6bfc0
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 && atomic_read(&priv->wmm.tx_pkts_queued))
|
||||
if (!priv->port_open)
|
||||
continue;
|
||||
if (adapter->if_ops.is_port_ready &&
|
||||
!adapter->if_ops.is_port_ready(priv))
|
||||
continue;
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user