diff options
author | Andreas Fenkart <[andreas.fenkart@streamunlimited.com]> | 2013-04-18 19:33:45 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-23 15:18:40 -0400 |
commit | 2e23731954d3641a418455e8e0c37c9b8aa7f567 (patch) | |
tree | 661b631bebb8b89c6d8d207e3d5f722fe31a4ce9 /drivers/net/wireless/mwifiex | |
parent | 1aac1e91171586e4d0981e40484a7c93d9b1f289 (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.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/wmm.c | 97 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/wmm.h | 3 |
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 | ||
214 | struct mwifiex_tid_tbl { | 214 | struct 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 | |||
973 | skip_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 | */ | ||
983 | void 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) | |||
85 | void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, | 85 | void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, |
86 | struct sk_buff *skb); | 86 | struct sk_buff *skb); |
87 | void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); | 87 | void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); |
88 | void mwifiex_rotate_priolists(struct mwifiex_private *priv, | ||
89 | struct mwifiex_ra_list_tbl *ra, | ||
90 | int tid); | ||
88 | 91 | ||
89 | int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); | 92 | int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); |
90 | void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); | 93 | void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); |