aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/wmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/wmm.c')
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c131
1 files changed, 87 insertions, 44 deletions
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 981cf6e7c73b..0a7cc742aed7 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -37,8 +37,8 @@
37/* Offset for TOS field in the IP header */ 37/* Offset for TOS field in the IP header */
38#define IPTOS_OFFSET 5 38#define IPTOS_OFFSET 5
39 39
40static bool enable_tx_amsdu; 40static bool disable_tx_amsdu;
41module_param(enable_tx_amsdu, bool, 0644); 41module_param(disable_tx_amsdu, bool, 0644);
42 42
43/* WMM information IE */ 43/* WMM information IE */
44static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07, 44static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
@@ -64,21 +64,6 @@ static u8 tos_to_tid[] = {
64 0x07 /* 1 1 1 AC_VO */ 64 0x07 /* 1 1 1 AC_VO */
65}; 65};
66 66
67/*
68 * This table inverses the tos_to_tid operation to get a priority
69 * which is in sequential order, and can be compared.
70 * Use this to compare the priority of two different TIDs.
71 */
72static u8 tos_to_tid_inv[] = {
73 0x02, /* from tos_to_tid[2] = 0 */
74 0x00, /* from tos_to_tid[0] = 1 */
75 0x01, /* from tos_to_tid[1] = 2 */
76 0x03,
77 0x04,
78 0x05,
79 0x06,
80 0x07};
81
82static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} }; 67static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
83 68
84/* 69/*
@@ -175,8 +160,15 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
175 break; 160 break;
176 161
177 ra_list->is_11n_enabled = 0; 162 ra_list->is_11n_enabled = 0;
163 ra_list->tdls_link = false;
178 if (!mwifiex_queuing_ra_based(priv)) { 164 if (!mwifiex_queuing_ra_based(priv)) {
179 ra_list->is_11n_enabled = IS_11N_ENABLED(priv); 165 if (mwifiex_get_tdls_link_status(priv, ra) ==
166 TDLS_SETUP_COMPLETE) {
167 ra_list->is_11n_enabled =
168 mwifiex_tdls_peer_11n_enabled(priv, ra);
169 } else {
170 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
171 }
180 } else { 172 } else {
181 ra_list->is_11n_enabled = 173 ra_list->is_11n_enabled =
182 mwifiex_is_sta_11n_enabled(priv, node); 174 mwifiex_is_sta_11n_enabled(priv, node);
@@ -213,8 +205,9 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
213 * This function map ACs to TIDs. 205 * This function map ACs to TIDs.
214 */ 206 */
215static void 207static void
216mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm) 208mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv)
217{ 209{
210 struct mwifiex_wmm_desc *wmm = &priv->wmm;
218 u8 *queue_priority = wmm->queue_priority; 211 u8 *queue_priority = wmm->queue_priority;
219 int i; 212 int i;
220 213
@@ -224,7 +217,7 @@ mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm)
224 } 217 }
225 218
226 for (i = 0; i < MAX_NUM_TID; ++i) 219 for (i = 0; i < MAX_NUM_TID; ++i)
227 tos_to_tid_inv[tos_to_tid[i]] = (u8)i; 220 priv->tos_to_tid_inv[tos_to_tid[i]] = (u8)i;
228 221
229 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID); 222 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID);
230} 223}
@@ -285,7 +278,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
285 } 278 }
286 } 279 }
287 280
288 mwifiex_wmm_queue_priorities_tid(&priv->wmm); 281 mwifiex_wmm_queue_priorities_tid(priv);
289} 282}
290 283
291/* 284/*
@@ -388,8 +381,7 @@ mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
388 * AP is disabled (due to call admission control (ACM bit). Mapping 381 * AP is disabled (due to call admission control (ACM bit). Mapping
389 * of TID to AC is taken care of internally. 382 * of TID to AC is taken care of internally.
390 */ 383 */
391static u8 384u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
392mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
393{ 385{
394 enum mwifiex_wmm_ac_e ac, ac_down; 386 enum mwifiex_wmm_ac_e ac, ac_down;
395 u8 new_tid; 387 u8 new_tid;
@@ -421,9 +413,17 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
421 continue; 413 continue;
422 414
423 for (i = 0; i < MAX_NUM_TID; ++i) { 415 for (i = 0; i < MAX_NUM_TID; ++i) {
424 priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; 416 if (!disable_tx_amsdu &&
425 priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; 417 adapter->tx_buf_size > MWIFIEX_TX_DATA_BUF_SIZE_2K)
426 priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; 418 priv->aggr_prio_tbl[i].amsdu =
419 priv->tos_to_tid_inv[i];
420 else
421 priv->aggr_prio_tbl[i].amsdu =
422 BA_STREAM_NOT_ALLOWED;
423 priv->aggr_prio_tbl[i].ampdu_ap =
424 priv->tos_to_tid_inv[i];
425 priv->aggr_prio_tbl[i].ampdu_user =
426 priv->tos_to_tid_inv[i];
427 } 427 }
428 428
429 priv->aggr_prio_tbl[6].amsdu 429 priv->aggr_prio_tbl[6].amsdu
@@ -546,6 +546,7 @@ void
546mwifiex_clean_txrx(struct mwifiex_private *priv) 546mwifiex_clean_txrx(struct mwifiex_private *priv)
547{ 547{
548 unsigned long flags; 548 unsigned long flags;
549 struct sk_buff *skb, *tmp;
549 550
550 mwifiex_11n_cleanup_reorder_tbl(priv); 551 mwifiex_11n_cleanup_reorder_tbl(priv);
551 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); 552 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
@@ -563,6 +564,9 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
563 !priv->adapter->surprise_removed) 564 !priv->adapter->surprise_removed)
564 priv->adapter->if_ops.clean_pcie_ring(priv->adapter); 565 priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
565 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 566 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
567
568 skb_queue_walk_safe(&priv->tdls_txq, skb, tmp)
569 mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
566} 570}
567 571
568/* 572/*
@@ -591,7 +595,7 @@ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
591 * If no such node is found, a new node is added first and then 595 * If no such node is found, a new node is added first and then
592 * retrieved. 596 * retrieved.
593 */ 597 */
594static struct mwifiex_ra_list_tbl * 598struct mwifiex_ra_list_tbl *
595mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) 599mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr)
596{ 600{
597 struct mwifiex_ra_list_tbl *ra_list; 601 struct mwifiex_ra_list_tbl *ra_list;
@@ -641,6 +645,21 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
641 struct mwifiex_ra_list_tbl *ra_list; 645 struct mwifiex_ra_list_tbl *ra_list;
642 u8 ra[ETH_ALEN], tid_down; 646 u8 ra[ETH_ALEN], tid_down;
643 unsigned long flags; 647 unsigned long flags;
648 struct list_head list_head;
649 int tdls_status = TDLS_NOT_SETUP;
650 struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;
651 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
652
653 memcpy(ra, eth_hdr->h_dest, ETH_ALEN);
654
655 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
656 ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) {
657 if (ntohs(eth_hdr->h_proto) == ETH_P_TDLS)
658 dev_dbg(adapter->dev,
659 "TDLS setup packet for %pM. Don't block\n", ra);
660 else
661 tdls_status = mwifiex_get_tdls_link_status(priv, ra);
662 }
644 663
645 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { 664 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
646 dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); 665 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
@@ -659,12 +678,27 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
659 have only 1 raptr for a tid in case of infra */ 678 have only 1 raptr for a tid in case of infra */
660 if (!mwifiex_queuing_ra_based(priv) && 679 if (!mwifiex_queuing_ra_based(priv) &&
661 !mwifiex_is_skb_mgmt_frame(skb)) { 680 !mwifiex_is_skb_mgmt_frame(skb)) {
662 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) 681 switch (tdls_status) {
663 ra_list = list_first_entry( 682 case TDLS_SETUP_COMPLETE:
664 &priv->wmm.tid_tbl_ptr[tid_down].ra_list, 683 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down,
665 struct mwifiex_ra_list_tbl, list); 684 ra);
666 else 685 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
667 ra_list = NULL; 686 break;
687 case TDLS_SETUP_INPROGRESS:
688 skb_queue_tail(&priv->tdls_txq, skb);
689 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
690 flags);
691 return;
692 default:
693 list_head = priv->wmm.tid_tbl_ptr[tid_down].ra_list;
694 if (!list_empty(&list_head))
695 ra_list = list_first_entry(
696 &list_head, struct mwifiex_ra_list_tbl,
697 list);
698 else
699 ra_list = NULL;
700 break;
701 }
668 } else { 702 } else {
669 memcpy(ra, skb->data, ETH_ALEN); 703 memcpy(ra, skb->data, ETH_ALEN);
670 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb)) 704 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb))
@@ -684,9 +718,9 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
684 ra_list->total_pkt_count++; 718 ra_list->total_pkt_count++;
685 719
686 if (atomic_read(&priv->wmm.highest_queued_prio) < 720 if (atomic_read(&priv->wmm.highest_queued_prio) <
687 tos_to_tid_inv[tid_down]) 721 priv->tos_to_tid_inv[tid_down])
688 atomic_set(&priv->wmm.highest_queued_prio, 722 atomic_set(&priv->wmm.highest_queued_prio,
689 tos_to_tid_inv[tid_down]); 723 priv->tos_to_tid_inv[tid_down]);
690 724
691 atomic_inc(&priv->wmm.tx_pkts_queued); 725 atomic_inc(&priv->wmm.tx_pkts_queued);
692 726
@@ -1219,15 +1253,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1219 1253
1220 if (!ptr->is_11n_enabled || 1254 if (!ptr->is_11n_enabled ||
1221 mwifiex_is_ba_stream_setup(priv, ptr, tid) || 1255 mwifiex_is_ba_stream_setup(priv, ptr, tid) ||
1222 priv->wps.session_enable || 1256 priv->wps.session_enable) {
1223 ((priv->sec_info.wpa_enabled || 1257 if (ptr->is_11n_enabled &&
1224 priv->sec_info.wpa2_enabled) && 1258 mwifiex_is_ba_stream_setup(priv, ptr, tid) &&
1225 !priv->wpa_is_gtk_set)) { 1259 mwifiex_is_amsdu_in_ampdu_allowed(priv, ptr, tid) &&
1226 mwifiex_send_single_packet(priv, ptr, ptr_index, flags); 1260 mwifiex_is_amsdu_allowed(priv, tid) &&
1227 /* ra_list_spinlock has been freed in 1261 mwifiex_is_11n_aggragation_possible(priv, ptr,
1228 mwifiex_send_single_packet() */ 1262 adapter->tx_buf_size))
1263 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
1264 /* ra_list_spinlock has been freed in
1265 * mwifiex_11n_aggregate_pkt()
1266 */
1267 else
1268 mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
1269 /* ra_list_spinlock has been freed in
1270 * mwifiex_send_single_packet()
1271 */
1229 } else { 1272 } else {
1230 if (mwifiex_is_ampdu_allowed(priv, tid) && 1273 if (mwifiex_is_ampdu_allowed(priv, ptr, tid) &&
1231 ptr->ba_pkt_count > ptr->ba_packet_thr) { 1274 ptr->ba_pkt_count > ptr->ba_packet_thr) {
1232 if (mwifiex_space_avail_for_new_ba_stream(adapter)) { 1275 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1233 mwifiex_create_ba_tbl(priv, ptr->ra, tid, 1276 mwifiex_create_ba_tbl(priv, ptr->ra, tid,
@@ -1240,7 +1283,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1240 mwifiex_send_delba(priv, tid_del, ra, 1); 1283 mwifiex_send_delba(priv, tid_del, ra, 1);
1241 } 1284 }
1242 } 1285 }
1243 if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && 1286 if (mwifiex_is_amsdu_allowed(priv, tid) &&
1244 mwifiex_is_11n_aggragation_possible(priv, ptr, 1287 mwifiex_is_11n_aggragation_possible(priv, ptr,
1245 adapter->tx_buf_size)) 1288 adapter->tx_buf_size))
1246 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); 1289 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);