diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/wmm.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 77 |
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 | */ | ||
133 | static 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); |