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.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 3fa4d4176993..600d8194610e 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -127,6 +127,29 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
127 return ra_list; 127 return ra_list;
128} 128}
129 129
130/* This function returns random no between 16 and 32 to be used as threshold
131 * for no of packets after which BA setup is initiated.
132 */
133static u8 mwifiex_get_random_ba_threshold(void)
134{
135 u32 sec, usec;
136 struct timeval ba_tstamp;
137 u8 ba_threshold;
138
139 /* setup ba_packet_threshold here random number between
140 * [BA_SETUP_PACKET_OFFSET,
141 * BA_SETUP_PACKET_OFFSET+BA_SETUP_MAX_PACKET_THRESHOLD-1]
142 */
143
144 do_gettimeofday(&ba_tstamp);
145 sec = (ba_tstamp.tv_sec & 0xFFFF) + (ba_tstamp.tv_sec >> 16);
146 usec = (ba_tstamp.tv_usec & 0xFFFF) + (ba_tstamp.tv_usec >> 16);
147 ba_threshold = (((sec << 16) + usec) % BA_SETUP_MAX_PACKET_THRESHOLD)
148 + BA_SETUP_PACKET_OFFSET;
149
150 return ba_threshold;
151}
152
130/* 153/*
131 * This function allocates and adds a RA list for all TIDs 154 * This function allocates and adds a RA list for all TIDs
132 * with the given RA. 155 * with the given RA.
@@ -137,6 +160,12 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
137 int i; 160 int i;
138 struct mwifiex_ra_list_tbl *ra_list; 161 struct mwifiex_ra_list_tbl *ra_list;
139 struct mwifiex_adapter *adapter = priv->adapter; 162 struct mwifiex_adapter *adapter = priv->adapter;
163 struct mwifiex_sta_node *node;
164 unsigned long flags;
165
166 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
167 node = mwifiex_get_sta_entry(priv, ra);
168 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
140 169
141 for (i = 0; i < MAX_NUM_TID; ++i) { 170 for (i = 0; i < MAX_NUM_TID; ++i) {
142 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra); 171 ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
@@ -145,14 +174,24 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
145 if (!ra_list) 174 if (!ra_list)
146 break; 175 break;
147 176
148 if (!mwifiex_queuing_ra_based(priv)) 177 ra_list->is_11n_enabled = 0;
178 if (!mwifiex_queuing_ra_based(priv)) {
149 ra_list->is_11n_enabled = IS_11N_ENABLED(priv); 179 ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
150 else 180 } else {
151 ra_list->is_11n_enabled = false; 181 ra_list->is_11n_enabled =
182 mwifiex_is_sta_11n_enabled(priv, node);
183 if (ra_list->is_11n_enabled)
184 ra_list->max_amsdu = node->max_amsdu;
185 }
152 186
153 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n", 187 dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",
154 ra_list, ra_list->is_11n_enabled); 188 ra_list, ra_list->is_11n_enabled);
155 189
190 if (ra_list->is_11n_enabled) {
191 ra_list->pkt_count = 0;
192 ra_list->ba_packet_thr =
193 mwifiex_get_random_ba_threshold();
194 }
156 list_add_tail(&ra_list->list, 195 list_add_tail(&ra_list->list,
157 &priv->wmm.tid_tbl_ptr[i].ra_list); 196 &priv->wmm.tid_tbl_ptr[i].ra_list);
158 197
@@ -423,7 +462,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
423 for (i = 0; i < adapter->priv_num; ++i) { 462 for (i = 0; i < adapter->priv_num; ++i) {
424 priv = adapter->priv[i]; 463 priv = adapter->priv[i];
425 if (priv && atomic_read(&priv->wmm.tx_pkts_queued)) 464 if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
426 return false; 465 return false;
427 } 466 }
428 467
429 return true; 468 return true;
@@ -609,7 +648,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
609 u8 ra[ETH_ALEN], tid_down; 648 u8 ra[ETH_ALEN], tid_down;
610 unsigned long flags; 649 unsigned long flags;
611 650
612 if (!priv->media_connected) { 651 if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
613 dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); 652 dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
614 mwifiex_write_data_complete(adapter, skb, -1); 653 mwifiex_write_data_complete(adapter, skb, -1);
615 return; 654 return;
@@ -624,7 +663,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
624 /* In case of infra as we have already created the list during 663 /* In case of infra as we have already created the list during
625 association we just don't have to call get_queue_raptr, we will 664 association we just don't have to call get_queue_raptr, we will
626 have only 1 raptr for a tid in case of infra */ 665 have only 1 raptr for a tid in case of infra */
627 if (!mwifiex_queuing_ra_based(priv)) { 666 if (!mwifiex_queuing_ra_based(priv) &&
667 !mwifiex_is_skb_mgmt_frame(skb)) {
628 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) 668 if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
629 ra_list = list_first_entry( 669 ra_list = list_first_entry(
630 &priv->wmm.tid_tbl_ptr[tid_down].ra_list, 670 &priv->wmm.tid_tbl_ptr[tid_down].ra_list,
@@ -633,7 +673,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
633 ra_list = NULL; 673 ra_list = NULL;
634 } else { 674 } else {
635 memcpy(ra, skb->data, ETH_ALEN); 675 memcpy(ra, skb->data, ETH_ALEN);
636 if (ra[0] & 0x01) 676 if (ra[0] & 0x01 || mwifiex_is_skb_mgmt_frame(skb))
637 memset(ra, 0xff, ETH_ALEN); 677 memset(ra, 0xff, ETH_ALEN);
638 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra); 678 ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
639 } 679 }
@@ -647,6 +687,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
647 skb_queue_tail(&ra_list->skb_head, skb); 687 skb_queue_tail(&ra_list->skb_head, skb);
648 688
649 ra_list->total_pkts_size += skb->len; 689 ra_list->total_pkts_size += skb->len;
690 ra_list->pkt_count++;
650 691
651 atomic_inc(&priv->wmm.tx_pkts_queued); 692 atomic_inc(&priv->wmm.tx_pkts_queued);
652 693
@@ -867,17 +908,16 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
867 if (adapter->bss_prio_tbl[j].bss_prio_cur == 908 if (adapter->bss_prio_tbl[j].bss_prio_cur ==
868 (struct mwifiex_bss_prio_node *) 909 (struct mwifiex_bss_prio_node *)
869 &adapter->bss_prio_tbl[j].bss_prio_head) { 910 &adapter->bss_prio_tbl[j].bss_prio_head) {
870 bssprio_node = 911 adapter->bss_prio_tbl[j].bss_prio_cur =
871 list_first_entry(&adapter->bss_prio_tbl[j] 912 list_first_entry(&adapter->bss_prio_tbl[j]
872 .bss_prio_head, 913 .bss_prio_head,
873 struct mwifiex_bss_prio_node, 914 struct mwifiex_bss_prio_node,
874 list); 915 list);
875 bssprio_head = bssprio_node;
876 } else {
877 bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
878 bssprio_head = bssprio_node;
879 } 916 }
880 917
918 bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
919 bssprio_head = bssprio_node;
920
881 do { 921 do {
882 priv_tmp = bssprio_node->priv; 922 priv_tmp = bssprio_node->priv;
883 hqp = &priv_tmp->wmm.highest_queued_prio; 923 hqp = &priv_tmp->wmm.highest_queued_prio;
@@ -986,10 +1026,17 @@ mwifiex_is_11n_aggragation_possible(struct mwifiex_private *priv,
986{ 1026{
987 int count = 0, total_size = 0; 1027 int count = 0, total_size = 0;
988 struct sk_buff *skb, *tmp; 1028 struct sk_buff *skb, *tmp;
1029 int max_amsdu_size;
1030
1031 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP && priv->ap_11n_enabled &&
1032 ptr->is_11n_enabled)
1033 max_amsdu_size = min_t(int, ptr->max_amsdu, max_buf_size);
1034 else
1035 max_amsdu_size = max_buf_size;
989 1036
990 skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { 1037 skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
991 total_size += skb->len; 1038 total_size += skb->len;
992 if (total_size >= max_buf_size) 1039 if (total_size >= max_amsdu_size)
993 break; 1040 break;
994 if (++count >= MIN_NUM_AMSDU) 1041 if (++count >= MIN_NUM_AMSDU)
995 return true; 1042 return true;
@@ -1050,6 +1097,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1050 skb_queue_tail(&ptr->skb_head, skb); 1097 skb_queue_tail(&ptr->skb_head, skb);
1051 1098
1052 ptr->total_pkts_size += skb->len; 1099 ptr->total_pkts_size += skb->len;
1100 ptr->pkt_count++;
1053 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; 1101 tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
1054 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1102 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1055 ra_list_flags); 1103 ra_list_flags);
@@ -1231,7 +1279,8 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1231 /* ra_list_spinlock has been freed in 1279 /* ra_list_spinlock has been freed in
1232 mwifiex_send_single_packet() */ 1280 mwifiex_send_single_packet() */
1233 } else { 1281 } else {
1234 if (mwifiex_is_ampdu_allowed(priv, tid)) { 1282 if (mwifiex_is_ampdu_allowed(priv, tid) &&
1283 ptr->pkt_count > ptr->ba_packet_thr) {
1235 if (mwifiex_space_avail_for_new_ba_stream(adapter)) { 1284 if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
1236 mwifiex_create_ba_tbl(priv, ptr->ra, tid, 1285 mwifiex_create_ba_tbl(priv, ptr->ra, tid,
1237 BA_SETUP_INPROGRESS); 1286 BA_SETUP_INPROGRESS);