aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorAndreas Fenkart <[andreas.fenkart@streamunlimited.com]>2013-04-18 19:33:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-23 15:18:40 -0400
commit2e23731954d3641a418455e8e0c37c9b8aa7f567 (patch)
tree661b631bebb8b89c6d8d207e3d5f722fe31a4ce9 /drivers/net/wireless/mwifiex
parent1aac1e91171586e4d0981e40484a7c93d9b1f289 (diff)
mwifiex: replace ra_list_curr by list rotation.
After a packet is successfully transmitted, ra list is rotated, so the ra next to the one transmitted, will be the first in the list. This way we pick the ra' in a round robin fashion. This significantly simplifies iteration in mwifiex_wmm_get_highest_priolist_ptr to a call to list_for_each_entry. List rotation is done via list_move, where the head itself is temporarily removed and then re-inserted after the item just transferred. Signed-off-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com> Acked-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c8
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c97
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h3
4 files changed, 40 insertions, 69 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index af8fe6352eed..c6d74518aaab 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -296,19 +296,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
296 break; 296 break;
297 } 297 }
298 if (ret != -EBUSY) { 298 if (ret != -EBUSY) {
299 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); 299 mwifiex_rotate_priolists(priv, pra_list, ptrindex);
300 if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
301 priv->wmm.packets_out[ptrindex]++;
302 priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
303 }
304 /* Now bss_prio_cur pointer points to next node */ 300 /* Now bss_prio_cur pointer points to next node */
305 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = 301 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
306 list_first_entry( 302 list_first_entry(
307 &adapter->bss_prio_tbl[priv->bss_priority] 303 &adapter->bss_prio_tbl[priv->bss_priority]
308 .bss_prio_cur->list, 304 .bss_prio_cur->list,
309 struct mwifiex_bss_prio_node, list); 305 struct mwifiex_bss_prio_node, list);
310 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
311 ra_list_flags);
312 } 306 }
313 307
314 return 0; 308 return 0;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index b7484efc9443..4ef67fca06d3 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -213,7 +213,6 @@ struct mwifiex_ra_list_tbl {
213 213
214struct mwifiex_tid_tbl { 214struct mwifiex_tid_tbl {
215 struct list_head ra_list; 215 struct list_head ra_list;
216 struct mwifiex_ra_list_tbl *ra_list_curr;
217}; 216};
218 217
219#define WMM_HIGHEST_PRIORITY 7 218#define WMM_HIGHEST_PRIORITY 7
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 2cc81ba590e3..b48e03cde23f 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -191,9 +191,6 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
191 } 191 }
192 list_add_tail(&ra_list->list, 192 list_add_tail(&ra_list->list,
193 &priv->wmm.tid_tbl_ptr[i].ra_list); 193 &priv->wmm.tid_tbl_ptr[i].ra_list);
194
195 if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
196 priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
197 } 194 }
198} 195}
199 196
@@ -424,7 +421,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
424 priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; 421 priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i];
425 priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; 422 priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i];
426 priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; 423 priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
427 priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
428 } 424 }
429 425
430 priv->aggr_prio_tbl[6].amsdu 426 priv->aggr_prio_tbl[6].amsdu
@@ -530,8 +526,6 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
530 } 526 }
531 527
532 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); 528 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list);
533
534 priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
535 } 529 }
536} 530}
537 531
@@ -883,7 +877,7 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
883 struct mwifiex_private **priv, int *tid) 877 struct mwifiex_private **priv, int *tid)
884{ 878{
885 struct mwifiex_private *priv_tmp; 879 struct mwifiex_private *priv_tmp;
886 struct mwifiex_ra_list_tbl *ptr, *head; 880 struct mwifiex_ra_list_tbl *ptr;
887 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; 881 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
888 struct mwifiex_tid_tbl *tid_ptr; 882 struct mwifiex_tid_tbl *tid_ptr;
889 atomic_t *hqp; 883 atomic_t *hqp;
@@ -926,51 +920,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
926 tid_ptr = &(priv_tmp)->wmm. 920 tid_ptr = &(priv_tmp)->wmm.
927 tid_tbl_ptr[tos_to_tid[i]]; 921 tid_tbl_ptr[tos_to_tid[i]];
928 922
929 /* For non-STA ra_list_curr may be NULL */ 923 /* iterate over receiver addresses */
930 if (!tid_ptr->ra_list_curr) 924 list_for_each_entry(ptr, &tid_ptr->ra_list,
931 goto skip_wmm_queue; 925 list) {
932
933 if (list_empty(&tid_ptr->ra_list))
934 goto skip_wmm_queue;
935
936 /*
937 * Always choose the next ra we transmitted
938 * last time, this way we pick the ra's in
939 * round robin fashion.
940 */
941 ptr = list_first_entry(
942 &tid_ptr->ra_list_curr->list,
943 struct mwifiex_ra_list_tbl,
944 list);
945 926
946 head = ptr;
947 if (ptr == (struct mwifiex_ra_list_tbl *)
948 &tid_ptr->ra_list) {
949 /* Get next ra */
950 ptr = list_first_entry(&ptr->list,
951 struct mwifiex_ra_list_tbl, list);
952 head = ptr;
953 }
954
955 do {
956 if (!skb_queue_empty(&ptr->skb_head)) 927 if (!skb_queue_empty(&ptr->skb_head))
957 /* holds both locks */ 928 /* holds both locks */
958 goto found; 929 goto found;
930 }
959 931
960 /* Get next ra */
961 ptr = list_first_entry(&ptr->list,
962 struct mwifiex_ra_list_tbl,
963 list);
964 if (ptr ==
965 (struct mwifiex_ra_list_tbl *)
966 &tid_ptr->ra_list)
967 ptr = list_first_entry(
968 &ptr->list,
969 struct mwifiex_ra_list_tbl,
970 list);
971 } while (ptr != head);
972
973skip_wmm_queue:
974 spin_unlock_irqrestore(&priv_tmp->wmm. 932 spin_unlock_irqrestore(&priv_tmp->wmm.
975 ra_list_spinlock, 933 ra_list_spinlock,
976 flags_ra); 934 flags_ra);
@@ -1013,6 +971,35 @@ found:
1013 return ptr; 971 return ptr;
1014} 972}
1015 973
974/* This functions rotates ra lists so packets are picked in round robin
975 * fashion.
976 *
977 * After a packet is successfully transmitted, rotate the ra list, so the ra
978 * next to the one transmitted, will come first in the list. This way we pick
979 * the ra in a round robin fashion.
980 *
981 * Function also increments wmm.packets_out counter.
982 */
983void mwifiex_rotate_priolists(struct mwifiex_private *priv,
984 struct mwifiex_ra_list_tbl *ra,
985 int tid)
986{
987 struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid];
988 unsigned long flags;
989
990 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
991 if (mwifiex_is_ralist_valid(priv, ra, tid)) {
992 priv->wmm.packets_out[tid]++;
993 /*
994 * dirty trick: we remove 'head' temporarily and reinsert it
995 * after curr bss node. imagine list to stay fixed while only
996 * head is moved
997 */
998 list_move(&tid_ptr->ra_list, &ra->list);
999 }
1000 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
1001}
1002
1016/* 1003/*
1017 * This function checks if 11n aggregation is possible. 1004 * This function checks if 11n aggregation is possible.
1018 */ 1005 */
@@ -1099,11 +1086,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1099 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1086 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1100 ra_list_flags); 1087 ra_list_flags);
1101 } else { 1088 } else {
1102 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); 1089 mwifiex_rotate_priolists(priv, ptr, ptr_index);
1103 if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1104 priv->wmm.packets_out[ptr_index]++;
1105 priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
1106 }
1107 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = 1090 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1108 list_first_entry( 1091 list_first_entry(
1109 &adapter->bss_prio_tbl[priv->bss_priority] 1092 &adapter->bss_prio_tbl[priv->bss_priority]
@@ -1111,8 +1094,6 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1111 struct mwifiex_bss_prio_node, 1094 struct mwifiex_bss_prio_node,
1112 list); 1095 list);
1113 atomic_dec(&priv->wmm.tx_pkts_queued); 1096 atomic_dec(&priv->wmm.tx_pkts_queued);
1114 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1115 ra_list_flags);
1116 } 1097 }
1117} 1098}
1118 1099
@@ -1216,11 +1197,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1216 break; 1197 break;
1217 } 1198 }
1218 if (ret != -EBUSY) { 1199 if (ret != -EBUSY) {
1219 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); 1200 mwifiex_rotate_priolists(priv, ptr, ptr_index);
1220 if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
1221 priv->wmm.packets_out[ptr_index]++;
1222 priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
1223 }
1224 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = 1201 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1225 list_first_entry( 1202 list_first_entry(
1226 &adapter->bss_prio_tbl[priv->bss_priority] 1203 &adapter->bss_prio_tbl[priv->bss_priority]
@@ -1228,8 +1205,6 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1228 struct mwifiex_bss_prio_node, 1205 struct mwifiex_bss_prio_node,
1229 list); 1206 list);
1230 atomic_dec(&priv->wmm.tx_pkts_queued); 1207 atomic_dec(&priv->wmm.tx_pkts_queued);
1231 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1232 ra_list_flags);
1233 } 1208 }
1234} 1209}
1235 1210
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index b92f39d8963b..644d6e0c51cc 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -85,6 +85,9 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
85void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, 85void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
86 struct sk_buff *skb); 86 struct sk_buff *skb);
87void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); 87void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
88void mwifiex_rotate_priolists(struct mwifiex_private *priv,
89 struct mwifiex_ra_list_tbl *ra,
90 int tid);
88 91
89int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); 92int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
90void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); 93void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter);