diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/wmm.c')
| -rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 396 |
1 files changed, 189 insertions, 207 deletions
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 818f871ae98..d3671d009f6 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -37,6 +37,9 @@ /* Offset for TOS field in the IP header */ #define IPTOS_OFFSET 5 +static bool disable_tx_amsdu; +module_param(disable_tx_amsdu, bool, 0644); + /* WMM information IE */ static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, @@ -61,21 +64,6 @@ static u8 tos_to_tid[] = { 0x07 /* 1 1 1 AC_VO */ }; -/* - * This table inverses the tos_to_tid operation to get a priority - * which is in sequential order, and can be compared. - * Use this to compare the priority of two different TIDs. - */ -static u8 tos_to_tid_inv[] = { - 0x02, /* from tos_to_tid[2] = 0 */ - 0x00, /* from tos_to_tid[0] = 1 */ - 0x01, /* from tos_to_tid[1] = 2 */ - 0x03, - 0x04, - 0x05, - 0x06, - 0x07}; - static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} }; /* @@ -104,23 +92,20 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) * The function also initializes the list with the provided RA. */ static struct mwifiex_ra_list_tbl * -mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) +mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, const u8 *ra) { struct mwifiex_ra_list_tbl *ra_list; ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC); - - if (!ra_list) { - dev_err(adapter->dev, "%s: failed to alloc ra_list\n", - __func__); + if (!ra_list) return NULL; - } + INIT_LIST_HEAD(&ra_list->list); skb_queue_head_init(&ra_list->skb_head); memcpy(ra_list->ra, ra, ETH_ALEN); - ra_list->total_pkts_size = 0; + ra_list->total_pkt_count = 0; dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); @@ -154,8 +139,7 @@ static u8 mwifiex_get_random_ba_threshold(void) * This function allocates and adds a RA list for all TIDs * with the given RA. */ -void -mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) +void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra) { int i; struct mwifiex_ra_list_tbl *ra_list; @@ -175,8 +159,16 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) break; ra_list->is_11n_enabled = 0; + ra_list->tdls_link = false; if (!mwifiex_queuing_ra_based(priv)) { - ra_list->is_11n_enabled = IS_11N_ENABLED(priv); + if (mwifiex_get_tdls_link_status(priv, ra) == + TDLS_SETUP_COMPLETE) { + ra_list->tdls_link = true; + ra_list->is_11n_enabled = + mwifiex_tdls_peer_11n_enabled(priv, ra); + } else { + ra_list->is_11n_enabled = IS_11N_ENABLED(priv); + } } else { ra_list->is_11n_enabled = mwifiex_is_sta_11n_enabled(priv, node); @@ -188,15 +180,12 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) ra_list, ra_list->is_11n_enabled); if (ra_list->is_11n_enabled) { - ra_list->pkt_count = 0; + ra_list->ba_pkt_count = 0; ra_list->ba_packet_thr = mwifiex_get_random_ba_threshold(); } list_add_tail(&ra_list->list, &priv->wmm.tid_tbl_ptr[i].ra_list); - - if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) - priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; } } @@ -216,8 +205,9 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) * This function map ACs to TIDs. */ static void -mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) +mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv) { + struct mwifiex_wmm_desc *wmm = &priv->wmm; u8 *queue_priority = wmm->queue_priority; int i; @@ -227,7 +217,7 @@ mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) } for (i = 0; i < MAX_NUM_TID; ++i) - tos_to_tid_inv[tos_to_tid[i]] = (u8)i; + priv->tos_to_tid_inv[tos_to_tid[i]] = (u8)i; atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); } @@ -288,7 +278,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, } } - mwifiex_wmm_queue_priorities_tid(&priv->wmm); + mwifiex_wmm_queue_priorities_tid(priv); } /* @@ -391,8 +381,7 @@ mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos) * AP is disabled (due to call admission control (ACM bit). Mapping * of TID to AC is taken care of internally. */ -static u8 -mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid) +u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid) { enum mwifiex_wmm_ac_e ac, ac_down; u8 new_tid; @@ -424,25 +413,20 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) continue; for (i = 0; i < MAX_NUM_TID; ++i) { - priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; - priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; - priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; - priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; + if (!disable_tx_amsdu && + adapter->tx_buf_size > MWIFIEX_TX_DATA_BUF_SIZE_2K) + priv->aggr_prio_tbl[i].amsdu = + priv->tos_to_tid_inv[i]; + else + priv->aggr_prio_tbl[i].amsdu = + BA_STREAM_NOT_ALLOWED; + priv->aggr_prio_tbl[i].ampdu_ap = + priv->tos_to_tid_inv[i]; + priv->aggr_prio_tbl[i].ampdu_user = + priv->tos_to_tid_inv[i]; } - priv->aggr_prio_tbl[6].amsdu - = priv->aggr_prio_tbl[6].ampdu_ap - = priv->aggr_prio_tbl[6].ampdu_user - = BA_STREAM_NOT_ALLOWED; - - priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap - = priv->aggr_prio_tbl[7].ampdu_user - = BA_STREAM_NOT_ALLOWED; - - priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; - priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; - priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; - + mwifiex_set_ba_params(priv); mwifiex_reset_11n_rx_seq_num(priv); atomic_set(&priv->wmm.tx_pkts_queued, 0); @@ -536,8 +520,6 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) } INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); - - priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; } } @@ -555,6 +537,7 @@ void mwifiex_clean_txrx(struct mwifiex_private *priv) { unsigned long flags; + struct sk_buff *skb, *tmp; mwifiex_11n_cleanup_reorder_tbl(priv); spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); @@ -568,7 +551,13 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) mwifiex_wmm_delete_all_ralist(priv); memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); + if (priv->adapter->if_ops.clean_pcie_ring && + !priv->adapter->surprise_removed) + priv->adapter->if_ops.clean_pcie_ring(priv->adapter); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); + + skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) + mwifiex_write_data_complete(priv->adapter, skb, 0, -1); } /* @@ -577,7 +566,7 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) */ static struct mwifiex_ra_list_tbl * mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, - u8 *ra_addr) + const u8 *ra_addr) { struct mwifiex_ra_list_tbl *ra_list; @@ -597,8 +586,9 @@ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, * If no such node is found, a new node is added first and then * retrieved. */ -static struct mwifiex_ra_list_tbl * -mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) +struct mwifiex_ra_list_tbl * +mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, + const u8 *ra_addr) { struct mwifiex_ra_list_tbl *ra_list; @@ -647,6 +637,21 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; unsigned long flags; + struct list_head list_head; + int tdls_status = TDLS_NOT_SETUP; + struct ethhdr *eth_hdr = (struct ethhdr *)skb->data; + struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); + + memcpy(ra, eth_hdr->h_dest, ETH_ALEN); + + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) { + if (ntohs(eth_hdr->h_proto) == ETH_P_TDLS) + dev_dbg(adapter->dev, + "TDLS setup packet for %pM. Don't block\n", ra); + else if (memcmp(priv->cfg_bssid, ra, ETH_ALEN)) + tdls_status = mwifiex_get_tdls_link_status(priv, ra); + } if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); @@ -665,12 +670,27 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, have only 1 raptr for a tid in case of infra */ if (!mwifiex_queuing_ra_based(priv) && !mwifiex_is_skb_mgmt_frame(skb)) { - if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) - ra_list = list_first_entry( - &priv->wmm.tid_tbl_ptr[tid_down].ra_list, - struct mwifiex_ra_list_tbl, list); - else - ra_list = NULL; + switch (tdls_status) { + case TDLS_SETUP_COMPLETE: + ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, + ra); + tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; + break; + case TDLS_SETUP_INPROGRESS: + skb_queue_tail(&priv->tdls_txq, skb); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + flags); + return; + default: + list_head = priv->wmm.tid_tbl_ptr[tid_down].ra_list; + if (!list_empty(&list_head)) + ra_list = list_first_entry( + &list_head, struct mwifiex_ra_list_tbl, + list); + else + ra_list = NULL; + break; + } } else { memcpy(ra, skb->data, ETH_ALEN); if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb)) @@ -686,15 +706,15 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, skb_queue_tail(&ra_list->skb_head, skb); - ra_list->total_pkts_size += skb->len; - ra_list->pkt_count++; - - atomic_inc(&priv->wmm.tx_pkts_queued); + ra_list->ba_pkt_count++; + ra_list->total_pkt_count++; if (atomic_read(&priv->wmm.highest_queued_prio) < - tos_to_tid_inv[tid_down]) + priv->tos_to_tid_inv[tid_down]) atomic_set(&priv->wmm.highest_queued_prio, - tos_to_tid_inv[tid_down]); + priv->tos_to_tid_inv[tid_down]); + + atomic_inc(&priv->wmm.tx_pkts_queued); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -715,7 +735,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, { u8 *curr = (u8 *) &resp->params.get_wmm_status; uint16_t resp_len = le16_to_cpu(resp->size), tlv_len; - int valid = true; + bool valid = true; struct mwifiex_ie_types_data *tlv_hdr; struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus; @@ -729,6 +749,9 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, tlv_hdr = (struct mwifiex_ie_types_data *) curr; tlv_len = le16_to_cpu(tlv_hdr->header.len); + if (resp_len < tlv_len + sizeof(tlv_hdr->header)) + break; + switch (le16_to_cpu(tlv_hdr->header.type)) { case TLV_TYPE_WMMQSTATUS: tlv_wmm_qstatus = @@ -887,128 +910,65 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_private **priv, int *tid) { struct mwifiex_private *priv_tmp; - struct mwifiex_ra_list_tbl *ptr, *head; - struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; + struct mwifiex_ra_list_tbl *ptr; struct mwifiex_tid_tbl *tid_ptr; atomic_t *hqp; - int is_list_empty; - unsigned long flags; + unsigned long flags_bss, flags_ra; int i, j; + /* check the BSS with highest priority first */ for (j = adapter->priv_num - 1; j >= 0; --j) { spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); - is_list_empty = list_empty(&adapter->bss_prio_tbl[j] - .bss_prio_head); - spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); - if (is_list_empty) - continue; + flags_bss); - if (adapter->bss_prio_tbl[j].bss_prio_cur == - (struct mwifiex_bss_prio_node *) - &adapter->bss_prio_tbl[j].bss_prio_head) { - adapter->bss_prio_tbl[j].bss_prio_cur = - list_first_entry(&adapter->bss_prio_tbl[j] - .bss_prio_head, - struct mwifiex_bss_prio_node, - list); - } + /* iterate over BSS with the equal priority */ + list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur, + &adapter->bss_prio_tbl[j].bss_prio_head, + list) { - bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur; - bssprio_head = bssprio_node; + priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv; - do { - priv_tmp = bssprio_node->priv; - hqp = &priv_tmp->wmm.highest_queued_prio; + if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0) + 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) { + spin_lock_irqsave(&priv_tmp->wmm. + ra_list_spinlock, flags_ra); + tid_ptr = &(priv_tmp)->wmm. tid_tbl_ptr[tos_to_tid[i]]; - /* For non-STA ra_list_curr may be NULL */ - if (!tid_ptr->ra_list_curr) - continue; - - spin_lock_irqsave(&tid_ptr->tid_tbl_lock, - flags); - is_list_empty = - list_empty(&adapter->bss_prio_tbl[j] - .bss_prio_head); - spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock, - flags); - if (is_list_empty) - continue; - - /* - * Always choose the next ra we transmitted - * last time, this way we pick the ra's in - * round robin fashion. - */ - ptr = list_first_entry( - &tid_ptr->ra_list_curr->list, - struct mwifiex_ra_list_tbl, - list); - - head = ptr; - if (ptr == (struct mwifiex_ra_list_tbl *) - &tid_ptr->ra_list) { - /* Get next ra */ - ptr = list_first_entry(&ptr->list, - struct mwifiex_ra_list_tbl, list); - head = ptr; - } - - do { - is_list_empty = - skb_queue_empty(&ptr->skb_head); + /* iterate over receiver addresses */ + list_for_each_entry(ptr, &tid_ptr->ra_list, + list) { - if (!is_list_empty) + if (!skb_queue_empty(&ptr->skb_head)) + /* holds both locks */ goto found; + } - /* Get next ra */ - ptr = list_first_entry(&ptr->list, - struct mwifiex_ra_list_tbl, - list); - if (ptr == - (struct mwifiex_ra_list_tbl *) - &tid_ptr->ra_list) - ptr = list_first_entry( - &ptr->list, - struct mwifiex_ra_list_tbl, - list); - } while (ptr != head); + spin_unlock_irqrestore(&priv_tmp->wmm. + ra_list_spinlock, + flags_ra); } + } - /* No packet at any TID for this priv. Mark as such - * to skip checking TIDs for this priv (until pkt is - * added). - */ - atomic_set(hqp, NO_PKT_PRIO_TID); - - /* Get next bss priority node */ - bssprio_node = list_first_entry(&bssprio_node->list, - struct mwifiex_bss_prio_node, - list); - - if (bssprio_node == - (struct mwifiex_bss_prio_node *) - &adapter->bss_prio_tbl[j].bss_prio_head) - /* Get next bss priority node */ - bssprio_node = list_first_entry( - &bssprio_node->list, - struct mwifiex_bss_prio_node, - list); - } while (bssprio_node != bssprio_head); + spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, + flags_bss); } + return NULL; found: - spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); + /* holds bss_prio_lock / ra_list_spinlock */ if (atomic_read(hqp) > i) atomic_set(hqp, i); - spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); + spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra); + spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, + flags_bss); *priv = priv_tmp; *tid = tos_to_tid[i]; @@ -1016,6 +976,42 @@ found: return ptr; } +/* This functions rotates ra and bss lists so packets are picked round robin. + * + * After a packet is successfully transmitted, rotate the ra list, so the ra + * next to the one transmitted, will come first in the list. This way we pick + * the ra' in a round robin fashion. Same applies to bss nodes of equal + * priority. + * + * Function also increments wmm.packets_out counter. + */ +void mwifiex_rotate_priolists(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra, + int tid) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; + struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid]; + unsigned long flags; + + spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); + /* + * dirty trick: we remove 'head' temporarily and reinsert it after + * curr bss node. imagine list to stay fixed while head is moved + */ + list_move(&tbl[priv->bss_priority].bss_prio_head, + &tbl[priv->bss_priority].bss_prio_cur->list); + spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); + + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); + if (mwifiex_is_ralist_valid(priv, ra, tid)) { + priv->wmm.packets_out[tid]++; + /* same as above */ + list_move(&tid_ptr->ra_list, &ra->list); + } + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); +} + /* * This function checks if 11n aggregation is possible. */ @@ -1071,7 +1067,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, tx_info = MWIFIEX_SKB_TXCB(skb); dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); - ptr->total_pkts_size -= skb->len; + ptr->total_pkt_count--; if (!skb_queue_empty(&ptr->skb_head)) skb_next = skb_peek(&ptr->skb_head); @@ -1096,26 +1092,14 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, skb_queue_tail(&ptr->skb_head, skb); - ptr->total_pkts_size += skb->len; - ptr->pkt_count++; + ptr->total_pkt_count++; + ptr->ba_pkt_count++; tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); } else { - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); - if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { - priv->wmm.packets_out[ptr_index]++; - priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; - } - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - list_first_entry( - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_cur->list, - struct mwifiex_bss_prio_node, - list); + mwifiex_rotate_priolists(priv, ptr, ptr_index); atomic_dec(&priv->wmm.tx_pkts_queued); - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, - ra_list_flags); } } @@ -1206,31 +1190,21 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, ra_list_flags); break; case -1: - adapter->data_sent = false; + if (adapter->iface_type != MWIFIEX_PCIE) + adapter->data_sent = false; dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, 0, ret); break; case -EINPROGRESS: - adapter->data_sent = false; + if (adapter->iface_type != MWIFIEX_PCIE) + adapter->data_sent = false; default: break; } if (ret != -EBUSY) { - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); - if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { - priv->wmm.packets_out[ptr_index]++; - priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; - } - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - list_first_entry( - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_cur->list, - struct mwifiex_bss_prio_node, - list); + mwifiex_rotate_priolists(priv, ptr, ptr_index); atomic_dec(&priv->wmm.tx_pkts_queued); - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, - ra_list_flags); } } @@ -1271,16 +1245,25 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || - priv->wps.session_enable || - ((priv->sec_info.wpa_enabled || - priv->sec_info.wpa2_enabled) && - !priv->wpa_is_gtk_set)) { - mwifiex_send_single_packet(priv, ptr, ptr_index, flags); - /* ra_list_spinlock has been freed in - mwifiex_send_single_packet() */ + priv->wps.session_enable) { + if (ptr->is_11n_enabled && + mwifiex_is_ba_stream_setup(priv, ptr, tid) && + mwifiex_is_amsdu_in_ampdu_allowed(priv, ptr, tid) && + mwifiex_is_amsdu_allowed(priv, tid) && + mwifiex_is_11n_aggragation_possible(priv, ptr, + adapter->tx_buf_size)) + mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + * mwifiex_11n_aggregate_pkt() + */ + else + mwifiex_send_single_packet(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + * mwifiex_send_single_packet() + */ } else { - if (mwifiex_is_ampdu_allowed(priv, tid) && - ptr->pkt_count > ptr->ba_packet_thr) { + if (mwifiex_is_ampdu_allowed(priv, ptr, tid) && + ptr->ba_pkt_count > ptr->ba_packet_thr) { if (mwifiex_space_avail_for_new_ba_stream(adapter)) { mwifiex_create_ba_tbl(priv, ptr->ra, tid, BA_SETUP_INPROGRESS); @@ -1295,8 +1278,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (mwifiex_is_amsdu_allowed(priv, tid) && mwifiex_is_11n_aggragation_possible(priv, ptr, adapter->tx_buf_size)) - mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, - ptr_index, flags); + mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); /* ra_list_spinlock has been freed in mwifiex_11n_aggregate_pkt() */ else |
