aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorAndreas Fenkart <[andreas.fenkart@streamunlimited.com]>2013-04-18 19:34:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-23 15:18:40 -0400
commitb006ed545cbadf1ebd4683719554742d20dbcede (patch)
tree4469dfebe8b2ed700175ecba692a03ab581cf548 /drivers/net/wireless
parent2e23731954d3641a418455e8e0c37c9b8aa7f567 (diff)
mwifiex: rework round robin scheduling of bss nodes.
Rotate bss prio list, so the bss next to the one served, will come first in the list of bss' with equal priority. This way we pick bss nodes in a round robin fashion. Using list rotation instead of a cur ptr simplifies iteration to calling list_for_each_entry. List rotation is done via list_move, where the head itself is temporarily removed and then re-inserted after the bss just served. 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')
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c6
-rw-r--r--drivers/net/wireless/mwifiex/init.c21
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c79
3 files changed, 29 insertions, 77 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index c6d74518aaab..a78e0651409c 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -297,12 +297,6 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
297 } 297 }
298 if (ret != -EBUSY) { 298 if (ret != -EBUSY) {
299 mwifiex_rotate_priolists(priv, pra_list, ptrindex); 299 mwifiex_rotate_priolists(priv, pra_list, ptrindex);
300 /* Now bss_prio_cur pointer points to next node */
301 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
302 list_first_entry(
303 &adapter->bss_prio_tbl[priv->bss_priority]
304 .bss_prio_cur->list,
305 struct mwifiex_bss_prio_node, list);
306 } 300 }
307 301
308 return 0; 302 return 0;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 42d7f0adf9bd..9f44fda19db9 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -44,8 +44,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
44 44
45 bss_prio->priv = priv; 45 bss_prio->priv = priv;
46 INIT_LIST_HEAD(&bss_prio->list); 46 INIT_LIST_HEAD(&bss_prio->list);
47 if (!tbl[priv->bss_priority].bss_prio_cur)
48 tbl[priv->bss_priority].bss_prio_cur = bss_prio;
49 47
50 spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); 48 spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags);
51 list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); 49 list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head);
@@ -525,7 +523,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
525 523
526 for (i = 0; i < adapter->priv_num; ++i) { 524 for (i = 0; i < adapter->priv_num; ++i) {
527 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); 525 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
528 adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
529 spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); 526 spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
530 } 527 }
531 528
@@ -625,42 +622,36 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
625{ 622{
626 int i; 623 int i;
627 struct mwifiex_adapter *adapter = priv->adapter; 624 struct mwifiex_adapter *adapter = priv->adapter;
628 struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; 625 struct mwifiex_bss_prio_node *bssprio_node, *tmp_node;
629 struct list_head *head; 626 struct list_head *head;
630 spinlock_t *lock; /* bss priority lock */ 627 spinlock_t *lock; /* bss priority lock */
631 unsigned long flags; 628 unsigned long flags;
632 629
633 for (i = 0; i < adapter->priv_num; ++i) { 630 for (i = 0; i < adapter->priv_num; ++i) {
634 head = &adapter->bss_prio_tbl[i].bss_prio_head; 631 head = &adapter->bss_prio_tbl[i].bss_prio_head;
635 cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
636 lock = &adapter->bss_prio_tbl[i].bss_prio_lock; 632 lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
637 dev_dbg(adapter->dev, "info: delete BSS priority table," 633 dev_dbg(adapter->dev, "info: delete BSS priority table,"
638 " bss_type = %d, bss_num = %d, i = %d," 634 " bss_type = %d, bss_num = %d, i = %d,"
639 " head = %p, cur = %p\n", 635 " head = %p\n",
640 priv->bss_type, priv->bss_num, i, head, *cur); 636 priv->bss_type, priv->bss_num, i, head);
641 if (*cur) { 637
638 {
642 spin_lock_irqsave(lock, flags); 639 spin_lock_irqsave(lock, flags);
643 if (list_empty(head)) { 640 if (list_empty(head)) {
644 spin_unlock_irqrestore(lock, flags); 641 spin_unlock_irqrestore(lock, flags);
645 continue; 642 continue;
646 } 643 }
647 bssprio_node = list_first_entry(head,
648 struct mwifiex_bss_prio_node, list);
649 spin_unlock_irqrestore(lock, flags);
650
651 list_for_each_entry_safe(bssprio_node, tmp_node, head, 644 list_for_each_entry_safe(bssprio_node, tmp_node, head,
652 list) { 645 list) {
653 if (bssprio_node->priv == priv) { 646 if (bssprio_node->priv == priv) {
654 dev_dbg(adapter->dev, "info: Delete " 647 dev_dbg(adapter->dev, "info: Delete "
655 "node %p, next = %p\n", 648 "node %p, next = %p\n",
656 bssprio_node, tmp_node); 649 bssprio_node, tmp_node);
657 spin_lock_irqsave(lock, flags);
658 list_del(&bssprio_node->list); 650 list_del(&bssprio_node->list);
659 spin_unlock_irqrestore(lock, flags);
660 kfree(bssprio_node); 651 kfree(bssprio_node);
661 } 652 }
662 } 653 }
663 *cur = (struct mwifiex_bss_prio_node *)head; 654 spin_unlock_irqrestore(lock, flags);
664 } 655 }
665 } 656 }
666} 657}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index b48e03cde23f..4be3d33ceae8 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -878,37 +878,25 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
878{ 878{
879 struct mwifiex_private *priv_tmp; 879 struct mwifiex_private *priv_tmp;
880 struct mwifiex_ra_list_tbl *ptr; 880 struct mwifiex_ra_list_tbl *ptr;
881 struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
882 struct mwifiex_tid_tbl *tid_ptr; 881 struct mwifiex_tid_tbl *tid_ptr;
883 atomic_t *hqp; 882 atomic_t *hqp;
884 unsigned long flags_bss, flags_ra; 883 unsigned long flags_bss, flags_ra;
885 int i, j; 884 int i, j;
886 885
886 /* check the BSS with highest priority first */
887 for (j = adapter->priv_num - 1; j >= 0; --j) { 887 for (j = adapter->priv_num - 1; j >= 0; --j) {
888 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, 888 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
889 flags_bss); 889 flags_bss);
890 890
891 if (list_empty(&adapter->bss_prio_tbl[j].bss_prio_head)) 891 /* iterate over BSS with the equal priority */
892 goto skip_prio_tbl; 892 list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur,
893 893 &adapter->bss_prio_tbl[j].bss_prio_head,
894 if (adapter->bss_prio_tbl[j].bss_prio_cur == 894 list) {
895 (struct mwifiex_bss_prio_node *)
896 &adapter->bss_prio_tbl[j].bss_prio_head) {
897 adapter->bss_prio_tbl[j].bss_prio_cur =
898 list_first_entry(&adapter->bss_prio_tbl[j]
899 .bss_prio_head,
900 struct mwifiex_bss_prio_node,
901 list);
902 }
903
904 bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
905 bssprio_head = bssprio_node;
906 895
907 do { 896 priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv;
908 priv_tmp = bssprio_node->priv;
909 897
910 if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0) 898 if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0)
911 goto skip_bss; 899 continue;
912 900
913 /* iterate over the WMM queues of the BSS */ 901 /* iterate over the WMM queues of the BSS */
914 hqp = &priv_tmp->wmm.highest_queued_prio; 902 hqp = &priv_tmp->wmm.highest_queued_prio;
@@ -933,24 +921,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
933 ra_list_spinlock, 921 ra_list_spinlock,
934 flags_ra); 922 flags_ra);
935 } 923 }
924 }
936 925
937skip_bss:
938 /* Get next bss priority node */
939 bssprio_node = list_first_entry(&bssprio_node->list,
940 struct mwifiex_bss_prio_node,
941 list);
942
943 if (bssprio_node ==
944 (struct mwifiex_bss_prio_node *)
945 &adapter->bss_prio_tbl[j].bss_prio_head)
946 /* Get next bss priority node */
947 bssprio_node = list_first_entry(
948 &bssprio_node->list,
949 struct mwifiex_bss_prio_node,
950 list);
951 } while (bssprio_node != bssprio_head);
952
953skip_prio_tbl:
954 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, 926 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
955 flags_bss); 927 flags_bss);
956 } 928 }
@@ -971,12 +943,12 @@ found:
971 return ptr; 943 return ptr;
972} 944}
973 945
974/* This functions rotates ra lists so packets are picked in round robin 946/* This functions rotates ra and bss lists so packets are picked round robin.
975 * fashion.
976 * 947 *
977 * After a packet is successfully transmitted, rotate the ra list, so the ra 948 * 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 949 * next to the one transmitted, will come first in the list. This way we pick
979 * the ra in a round robin fashion. 950 * the ra' in a round robin fashion. Same applies to bss nodes of equal
951 * priority.
980 * 952 *
981 * Function also increments wmm.packets_out counter. 953 * Function also increments wmm.packets_out counter.
982 */ 954 */
@@ -984,17 +956,24 @@ void mwifiex_rotate_priolists(struct mwifiex_private *priv,
984 struct mwifiex_ra_list_tbl *ra, 956 struct mwifiex_ra_list_tbl *ra,
985 int tid) 957 int tid)
986{ 958{
959 struct mwifiex_adapter *adapter = priv->adapter;
960 struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl;
987 struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid]; 961 struct mwifiex_tid_tbl *tid_ptr = &priv->wmm.tid_tbl_ptr[tid];
988 unsigned long flags; 962 unsigned long flags;
989 963
964 spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags);
965 /*
966 * dirty trick: we remove 'head' temporarily and reinsert it after
967 * curr bss node. imagine list to stay fixed while head is moved
968 */
969 list_move(&tbl[priv->bss_priority].bss_prio_head,
970 &tbl[priv->bss_priority].bss_prio_cur->list);
971 spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags);
972
990 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); 973 spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
991 if (mwifiex_is_ralist_valid(priv, ra, tid)) { 974 if (mwifiex_is_ralist_valid(priv, ra, tid)) {
992 priv->wmm.packets_out[tid]++; 975 priv->wmm.packets_out[tid]++;
993 /* 976 /* same as above */
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); 977 list_move(&tid_ptr->ra_list, &ra->list);
999 } 978 }
1000 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 979 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
@@ -1087,12 +1066,6 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1087 ra_list_flags); 1066 ra_list_flags);
1088 } else { 1067 } else {
1089 mwifiex_rotate_priolists(priv, ptr, ptr_index); 1068 mwifiex_rotate_priolists(priv, ptr, ptr_index);
1090 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1091 list_first_entry(
1092 &adapter->bss_prio_tbl[priv->bss_priority]
1093 .bss_prio_cur->list,
1094 struct mwifiex_bss_prio_node,
1095 list);
1096 atomic_dec(&priv->wmm.tx_pkts_queued); 1069 atomic_dec(&priv->wmm.tx_pkts_queued);
1097 } 1070 }
1098} 1071}
@@ -1198,12 +1171,6 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1198 } 1171 }
1199 if (ret != -EBUSY) { 1172 if (ret != -EBUSY) {
1200 mwifiex_rotate_priolists(priv, ptr, ptr_index); 1173 mwifiex_rotate_priolists(priv, ptr, ptr_index);
1201 adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
1202 list_first_entry(
1203 &adapter->bss_prio_tbl[priv->bss_priority]
1204 .bss_prio_cur->list,
1205 struct mwifiex_bss_prio_node,
1206 list);
1207 atomic_dec(&priv->wmm.tx_pkts_queued); 1174 atomic_dec(&priv->wmm.tx_pkts_queued);
1208 } 1175 }
1209} 1176}