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,
}
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->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;
......
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