mirror of https://gitee.com/openkylin/linux.git
mwifiex: preprocess packets from TX queue
During profiling, we discovered that driver remains idle for time when pakcet is downloaded to FW but no TX_DONE has been received i.e. while data_sent is true. This patch adds enhancement to TX routine where we preprocess packets from TX queue, make them ready for TX and add them to separate TX queue. Signed-off-by: Zhaoyang Liu <liuzy@marvell.com> Signed-off-by: Marc Yang <yangyang@marvell.com> Signed-off-by: Chin-ran Lo <crlo@marvell.com> Reviewed-by: Cathy Luo <cluo@marvell.com> Reviewed-by: Amitkumar Karwar <akarwar@marvell.com> Reviewed-by: Avinash Patil <patila@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
690e792cb9
commit
e35000ead4
|
@ -170,7 +170,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||||
struct mwifiex_adapter *adapter = priv->adapter;
|
struct mwifiex_adapter *adapter = priv->adapter;
|
||||||
struct sk_buff *skb_aggr, *skb_src;
|
struct sk_buff *skb_aggr, *skb_src;
|
||||||
struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
|
struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
|
||||||
int pad = 0, ret;
|
int pad = 0, aggr_num = 0, ret;
|
||||||
struct mwifiex_tx_param tx_param;
|
struct mwifiex_tx_param tx_param;
|
||||||
struct txpd *ptx_pd = NULL;
|
struct txpd *ptx_pd = NULL;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -184,7 +184,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
|
tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
|
||||||
skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
|
skb_aggr = mwifiex_alloc_dma_align_buf(adapter->tx_buf_size,
|
||||||
|
GFP_ATOMIC | GFP_DMA);
|
||||||
if (!skb_aggr) {
|
if (!skb_aggr) {
|
||||||
dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
|
dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
|
||||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||||
|
@ -200,6 +201,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||||
|
|
||||||
if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
|
if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
|
||||||
tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
|
tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
|
||||||
|
tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;
|
||||||
skb_aggr->priority = skb_src->priority;
|
skb_aggr->priority = skb_src->priority;
|
||||||
|
|
||||||
do_gettimeofday(&tv);
|
do_gettimeofday(&tv);
|
||||||
|
@ -211,11 +213,9 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
skb_src = skb_dequeue(&pra_list->skb_head);
|
skb_src = skb_dequeue(&pra_list->skb_head);
|
||||||
|
|
||||||
pra_list->total_pkt_count--;
|
pra_list->total_pkt_count--;
|
||||||
|
|
||||||
atomic_dec(&priv->wmm.tx_pkts_queued);
|
atomic_dec(&priv->wmm.tx_pkts_queued);
|
||||||
|
aggr_num++;
|
||||||
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||||
ra_list_flags);
|
ra_list_flags);
|
||||||
mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
|
mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
|
||||||
|
@ -251,6 +251,12 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||||
ptx_pd = (struct txpd *)skb_aggr->data;
|
ptx_pd = (struct txpd *)skb_aggr->data;
|
||||||
|
|
||||||
skb_push(skb_aggr, headroom);
|
skb_push(skb_aggr, headroom);
|
||||||
|
tx_info_aggr->aggr_num = aggr_num * 2;
|
||||||
|
if (adapter->data_sent || adapter->tx_lock_flag) {
|
||||||
|
atomic_add(aggr_num * 2, &adapter->tx_queued);
|
||||||
|
skb_queue_tail(&adapter->tx_data_q, skb_aggr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (adapter->iface_type == MWIFIEX_USB) {
|
if (adapter->iface_type == MWIFIEX_USB) {
|
||||||
adapter->data_sent = true;
|
adapter->data_sent = true;
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
|
#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
|
||||||
#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
|
#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
|
||||||
#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
|
#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
|
||||||
|
#define MWIFIEX_BUF_FLAG_AGGR_PKT BIT(5)
|
||||||
|
|
||||||
#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
|
#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
|
||||||
#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
|
#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
|
||||||
|
@ -179,6 +180,7 @@ struct mwifiex_txinfo {
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u8 bss_num;
|
u8 bss_num;
|
||||||
u8 bss_type;
|
u8 bss_type;
|
||||||
|
u8 aggr_num;
|
||||||
u32 pkt_len;
|
u32 pkt_len;
|
||||||
u8 ack_frame_id;
|
u8 ack_frame_id;
|
||||||
u64 cookie;
|
u64 cookie;
|
||||||
|
|
|
@ -481,6 +481,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
|
||||||
spin_lock_init(&adapter->rx_proc_lock);
|
spin_lock_init(&adapter->rx_proc_lock);
|
||||||
|
|
||||||
skb_queue_head_init(&adapter->rx_data_q);
|
skb_queue_head_init(&adapter->rx_data_q);
|
||||||
|
skb_queue_head_init(&adapter->tx_data_q);
|
||||||
|
|
||||||
for (i = 0; i < adapter->priv_num; ++i) {
|
for (i = 0; i < adapter->priv_num; ++i) {
|
||||||
INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
|
INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
|
||||||
|
@ -688,6 +689,10 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atomic_set(&adapter->tx_queued, 0);
|
||||||
|
while ((skb = skb_dequeue(&adapter->tx_data_q)))
|
||||||
|
mwifiex_write_data_complete(adapter, skb, 0, 0);
|
||||||
|
|
||||||
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
|
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&adapter->rx_data_q))) {
|
while ((skb = skb_dequeue(&adapter->rx_data_q))) {
|
||||||
|
|
|
@ -262,6 +262,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
||||||
(adapter->pm_wakeup_card_req &&
|
(adapter->pm_wakeup_card_req &&
|
||||||
!adapter->pm_wakeup_fw_try) &&
|
!adapter->pm_wakeup_fw_try) &&
|
||||||
(is_command_pending(adapter) ||
|
(is_command_pending(adapter) ||
|
||||||
|
!skb_queue_empty(&adapter->tx_data_q) ||
|
||||||
!mwifiex_wmm_lists_empty(adapter))) {
|
!mwifiex_wmm_lists_empty(adapter))) {
|
||||||
adapter->pm_wakeup_fw_try = true;
|
adapter->pm_wakeup_fw_try = true;
|
||||||
mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
|
mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
|
||||||
|
@ -286,7 +287,8 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
||||||
|
|
||||||
if ((!adapter->scan_chan_gap_enabled &&
|
if ((!adapter->scan_chan_gap_enabled &&
|
||||||
adapter->scan_processing) || adapter->data_sent ||
|
adapter->scan_processing) || adapter->data_sent ||
|
||||||
mwifiex_wmm_lists_empty(adapter)) {
|
(mwifiex_wmm_lists_empty(adapter) &&
|
||||||
|
skb_queue_empty(&adapter->tx_data_q))) {
|
||||||
if (adapter->cmd_sent || adapter->curr_cmd ||
|
if (adapter->cmd_sent || adapter->curr_cmd ||
|
||||||
(!is_command_pending(adapter)))
|
(!is_command_pending(adapter)))
|
||||||
break;
|
break;
|
||||||
|
@ -336,6 +338,20 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((adapter->scan_chan_gap_enabled ||
|
||||||
|
!adapter->scan_processing) &&
|
||||||
|
!adapter->data_sent &&
|
||||||
|
!skb_queue_empty(&adapter->tx_data_q)) {
|
||||||
|
mwifiex_process_tx_queue(adapter);
|
||||||
|
if (adapter->hs_activated) {
|
||||||
|
adapter->is_hs_configured = false;
|
||||||
|
mwifiex_hs_activated_event
|
||||||
|
(mwifiex_get_priv
|
||||||
|
(adapter, MWIFIEX_BSS_ROLE_ANY),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((adapter->scan_chan_gap_enabled ||
|
if ((adapter->scan_chan_gap_enabled ||
|
||||||
!adapter->scan_processing) &&
|
!adapter->scan_processing) &&
|
||||||
!adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
|
!adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
|
||||||
|
@ -351,7 +367,8 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
||||||
|
|
||||||
if (adapter->delay_null_pkt && !adapter->cmd_sent &&
|
if (adapter->delay_null_pkt && !adapter->cmd_sent &&
|
||||||
!adapter->curr_cmd && !is_command_pending(adapter) &&
|
!adapter->curr_cmd && !is_command_pending(adapter) &&
|
||||||
mwifiex_wmm_lists_empty(adapter)) {
|
(mwifiex_wmm_lists_empty(adapter) &&
|
||||||
|
skb_queue_empty(&adapter->tx_data_q))) {
|
||||||
if (!mwifiex_send_null_packet
|
if (!mwifiex_send_null_packet
|
||||||
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
|
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
|
||||||
MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
|
MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
|
||||||
|
|
|
@ -59,6 +59,8 @@ enum {
|
||||||
|
|
||||||
#define MWIFIEX_MAX_AP 64
|
#define MWIFIEX_MAX_AP 64
|
||||||
|
|
||||||
|
#define MWIFIEX_MAX_PKTS_TXQ 16
|
||||||
|
|
||||||
#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
|
#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
|
||||||
|
|
||||||
#define MWIFIEX_TIMER_10S 10000
|
#define MWIFIEX_TIMER_10S 10000
|
||||||
|
@ -819,6 +821,8 @@ struct mwifiex_adapter {
|
||||||
spinlock_t scan_pending_q_lock;
|
spinlock_t scan_pending_q_lock;
|
||||||
/* spin lock for RX processing routine */
|
/* spin lock for RX processing routine */
|
||||||
spinlock_t rx_proc_lock;
|
spinlock_t rx_proc_lock;
|
||||||
|
struct sk_buff_head tx_data_q;
|
||||||
|
atomic_t tx_queued;
|
||||||
u32 scan_processing;
|
u32 scan_processing;
|
||||||
u16 region_code;
|
u16 region_code;
|
||||||
struct mwifiex_802_11d_domain_reg domain_reg;
|
struct mwifiex_802_11d_domain_reg domain_reg;
|
||||||
|
@ -905,6 +909,8 @@ struct mwifiex_adapter {
|
||||||
bool auto_tdls;
|
bool auto_tdls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
|
||||||
|
|
||||||
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
|
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
|
||||||
|
|
||||||
void mwifiex_set_trans_start(struct net_device *dev);
|
void mwifiex_set_trans_start(struct net_device *dev);
|
||||||
|
|
|
@ -92,6 +92,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
|
||||||
else
|
else
|
||||||
head_ptr = mwifiex_process_sta_txpd(priv, skb);
|
head_ptr = mwifiex_process_sta_txpd(priv, skb);
|
||||||
|
|
||||||
|
if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
|
||||||
|
skb_queue_tail(&adapter->tx_data_q, skb);
|
||||||
|
atomic_inc(&adapter->tx_queued);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (head_ptr) {
|
if (head_ptr) {
|
||||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
|
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
|
||||||
local_tx_pd = (struct txpd *)(head_ptr + hroom);
|
local_tx_pd = (struct txpd *)(head_ptr + hroom);
|
||||||
|
@ -142,6 +148,123 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct mwifiex_tx_param *tx_param)
|
||||||
|
{
|
||||||
|
struct txpd *local_tx_pd = NULL;
|
||||||
|
u8 *head_ptr = skb->data;
|
||||||
|
int ret = 0;
|
||||||
|
struct mwifiex_private *priv;
|
||||||
|
struct mwifiex_txinfo *tx_info;
|
||||||
|
|
||||||
|
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||||
|
priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
|
||||||
|
tx_info->bss_type);
|
||||||
|
if (!priv) {
|
||||||
|
dev_err(adapter->dev, "data: priv not found. Drop TX packet\n");
|
||||||
|
adapter->dbg.num_tx_host_to_card_failure++;
|
||||||
|
mwifiex_write_data_complete(adapter, skb, 0, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
|
||||||
|
if (adapter->iface_type == MWIFIEX_USB)
|
||||||
|
local_tx_pd = (struct txpd *)head_ptr;
|
||||||
|
else
|
||||||
|
local_tx_pd = (struct txpd *) (head_ptr +
|
||||||
|
INTF_HEADER_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adapter->iface_type == MWIFIEX_USB) {
|
||||||
|
adapter->data_sent = true;
|
||||||
|
ret = adapter->if_ops.host_to_card(adapter,
|
||||||
|
MWIFIEX_USB_EP_DATA,
|
||||||
|
skb, NULL);
|
||||||
|
} else {
|
||||||
|
ret = adapter->if_ops.host_to_card(adapter,
|
||||||
|
MWIFIEX_TYPE_DATA,
|
||||||
|
skb, tx_param);
|
||||||
|
}
|
||||||
|
switch (ret) {
|
||||||
|
case -ENOSR:
|
||||||
|
dev_err(adapter->dev, "data: -ENOSR is returned\n");
|
||||||
|
break;
|
||||||
|
case -EBUSY:
|
||||||
|
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
|
||||||
|
(adapter->pps_uapsd_mode) &&
|
||||||
|
(adapter->tx_lock_flag)) {
|
||||||
|
priv->adapter->tx_lock_flag = false;
|
||||||
|
if (local_tx_pd)
|
||||||
|
local_tx_pd->flags = 0;
|
||||||
|
}
|
||||||
|
skb_queue_head(&adapter->tx_data_q, skb);
|
||||||
|
if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
|
||||||
|
atomic_add(tx_info->aggr_num, &adapter->tx_queued);
|
||||||
|
else
|
||||||
|
atomic_inc(&adapter->tx_queued);
|
||||||
|
dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (adapter->iface_type != MWIFIEX_PCIE)
|
||||||
|
adapter->data_sent = false;
|
||||||
|
dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
|
||||||
|
ret);
|
||||||
|
adapter->dbg.num_tx_host_to_card_failure++;
|
||||||
|
mwifiex_write_data_complete(adapter, skb, 0, ret);
|
||||||
|
break;
|
||||||
|
case -EINPROGRESS:
|
||||||
|
if (adapter->iface_type != MWIFIEX_PCIE)
|
||||||
|
adapter->data_sent = false;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
mwifiex_write_data_complete(adapter, skb, 0, ret);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb, *skb_next;
|
||||||
|
struct mwifiex_txinfo *tx_info;
|
||||||
|
struct mwifiex_tx_param tx_param;
|
||||||
|
|
||||||
|
skb = skb_dequeue(&adapter->tx_data_q);
|
||||||
|
if (!skb)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||||
|
if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
|
||||||
|
atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
|
||||||
|
else
|
||||||
|
atomic_dec(&adapter->tx_queued);
|
||||||
|
|
||||||
|
if (!skb_queue_empty(&adapter->tx_data_q))
|
||||||
|
skb_next = skb_peek(&adapter->tx_data_q);
|
||||||
|
else
|
||||||
|
skb_next = NULL;
|
||||||
|
tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
|
||||||
|
if (!tx_param.next_pkt_len) {
|
||||||
|
if (!mwifiex_wmm_lists_empty(adapter))
|
||||||
|
tx_param.next_pkt_len = 1;
|
||||||
|
}
|
||||||
|
return mwifiex_host_to_card(adapter, skb, &tx_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (adapter->data_sent || adapter->tx_lock_flag)
|
||||||
|
break;
|
||||||
|
if (mwifiex_dequeue_tx_queue(adapter))
|
||||||
|
break;
|
||||||
|
} while (!skb_queue_empty(&adapter->tx_data_q));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packet send completion callback handler.
|
* Packet send completion callback handler.
|
||||||
*
|
*
|
||||||
|
@ -181,6 +304,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
|
||||||
|
|
||||||
if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
|
if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
|
||||||
atomic_dec_return(&adapter->pending_bridged_pkts);
|
atomic_dec_return(&adapter->pending_bridged_pkts);
|
||||||
|
if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (aggr)
|
if (aggr)
|
||||||
/* For skb_aggr, do not wake up tx queue */
|
/* For skb_aggr, do not wake up tx queue */
|
||||||
|
|
|
@ -1174,6 +1174,14 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
|
||||||
|
|
||||||
skb = skb_dequeue(&ptr->skb_head);
|
skb = skb_dequeue(&ptr->skb_head);
|
||||||
|
|
||||||
|
if (adapter->data_sent || adapter->tx_lock_flag) {
|
||||||
|
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
|
||||||
|
ra_list_flags);
|
||||||
|
skb_queue_tail(&adapter->tx_data_q, skb);
|
||||||
|
atomic_inc(&adapter->tx_queued);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!skb_queue_empty(&ptr->skb_head))
|
if (!skb_queue_empty(&ptr->skb_head))
|
||||||
skb_next = skb_peek(&ptr->skb_head);
|
skb_next = skb_peek(&ptr->skb_head);
|
||||||
else
|
else
|
||||||
|
@ -1324,11 +1332,16 @@ void
|
||||||
mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
|
mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
/* Check if busy */
|
|
||||||
if (adapter->data_sent || adapter->tx_lock_flag)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (mwifiex_dequeue_tx_packet(adapter))
|
if (mwifiex_dequeue_tx_packet(adapter))
|
||||||
break;
|
break;
|
||||||
|
if (adapter->iface_type != MWIFIEX_SDIO) {
|
||||||
|
if (adapter->data_sent ||
|
||||||
|
adapter->tx_lock_flag)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (atomic_read(&adapter->tx_queued) >=
|
||||||
|
MWIFIEX_MAX_PKTS_TXQ)
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (!mwifiex_wmm_lists_empty(adapter));
|
} while (!mwifiex_wmm_lists_empty(adapter));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue