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) {
|
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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 = {
|
|||||||
.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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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;
|
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;
|
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))
|
(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,
|
|||||||
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)
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user