diff options
author | Avinash Patil <patila@marvell.com> | 2013-07-22 22:17:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-07-24 11:02:05 -0400 |
commit | 61c873045f74b16317c88e2931637329a6844564 (patch) | |
tree | 958660932b119dbb9ad5142d169f35e717243149 | |
parent | c7d9ed9ec9b2947a9c5dc5e2c7afce1fd3ad82cc (diff) |
mwifiex: delete AP TX queues when bridged packets reach threshold
Delete packets from TX queues for this mwifiex_private structure
when bridged packet count reaches maximum threshold. Bridged packets
from each RA List are deleted till they fall to low threshold of 128.
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/mwifiex/decl.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/init.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/uap_txrx.c | 66 |
4 files changed, 69 insertions, 2 deletions
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 94cc09d48444..a5993475daef 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -75,7 +75,8 @@ | |||
75 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) | 75 | #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) |
76 | #define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) | 76 | #define MWIFIEX_BUF_FLAG_BRIDGED_PKT BIT(1) |
77 | 77 | ||
78 | #define MWIFIEX_BRIDGED_PKTS_THRESHOLD 1024 | 78 | #define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 |
79 | #define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 | ||
79 | 80 | ||
80 | enum mwifiex_bss_type { | 81 | enum mwifiex_bss_type { |
81 | MWIFIEX_BSS_TYPE_STA = 0, | 82 | MWIFIEX_BSS_TYPE_STA = 0, |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index caaf4bd56b30..fb86cec1b5cd 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -135,6 +135,7 @@ int mwifiex_init_priv(struct mwifiex_private *priv) | |||
135 | 135 | ||
136 | priv->csa_chan = 0; | 136 | priv->csa_chan = 0; |
137 | priv->csa_expire_time = 0; | 137 | priv->csa_expire_time = 0; |
138 | priv->del_list_idx = 0; | ||
138 | 139 | ||
139 | return mwifiex_add_bss_prio_tbl(priv); | 140 | return mwifiex_add_bss_prio_tbl(priv); |
140 | } | 141 | } |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 761e5927eee3..5db05435d412 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -515,6 +515,7 @@ struct mwifiex_private { | |||
515 | bool scan_aborting; | 515 | bool scan_aborting; |
516 | u8 csa_chan; | 516 | u8 csa_chan; |
517 | unsigned long csa_expire_time; | 517 | unsigned long csa_expire_time; |
518 | u8 del_list_idx; | ||
518 | }; | 519 | }; |
519 | 520 | ||
520 | enum mwifiex_ba_status { | 521 | enum mwifiex_ba_status { |
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 11df2b2f8923..1cfe5a738c47 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c | |||
@@ -24,6 +24,69 @@ | |||
24 | #include "11n_aggr.h" | 24 | #include "11n_aggr.h" |
25 | #include "11n_rxreorder.h" | 25 | #include "11n_rxreorder.h" |
26 | 26 | ||
27 | /* This function checks if particular RA list has packets more than low bridge | ||
28 | * packet threshold and then deletes packet from this RA list. | ||
29 | * Function deletes packets from such RA list and returns true. If no such list | ||
30 | * is found, false is returned. | ||
31 | */ | ||
32 | static bool | ||
33 | mwifiex_uap_del_tx_pkts_in_ralist(struct mwifiex_private *priv, | ||
34 | struct list_head *ra_list_head) | ||
35 | { | ||
36 | struct mwifiex_ra_list_tbl *ra_list; | ||
37 | struct sk_buff *skb, *tmp; | ||
38 | bool pkt_deleted = false; | ||
39 | struct mwifiex_txinfo *tx_info; | ||
40 | struct mwifiex_adapter *adapter = priv->adapter; | ||
41 | |||
42 | list_for_each_entry(ra_list, ra_list_head, list) { | ||
43 | if (skb_queue_empty(&ra_list->skb_head)) | ||
44 | continue; | ||
45 | |||
46 | skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) { | ||
47 | tx_info = MWIFIEX_SKB_TXCB(skb); | ||
48 | if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) { | ||
49 | __skb_unlink(skb, &ra_list->skb_head); | ||
50 | mwifiex_write_data_complete(adapter, skb, 0, | ||
51 | -1); | ||
52 | atomic_dec(&priv->wmm.tx_pkts_queued); | ||
53 | pkt_deleted = true; | ||
54 | } | ||
55 | if ((atomic_read(&adapter->pending_bridged_pkts) <= | ||
56 | MWIFIEX_BRIDGED_PKTS_THR_LOW)) | ||
57 | break; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | return pkt_deleted; | ||
62 | } | ||
63 | |||
64 | /* This function deletes packets from particular RA List. RA list index | ||
65 | * from which packets are deleted is preserved so that packets from next RA | ||
66 | * list are deleted upon subsequent call thus maintaining fairness. | ||
67 | */ | ||
68 | static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | struct list_head *ra_list; | ||
72 | int i; | ||
73 | |||
74 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); | ||
75 | |||
76 | for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) { | ||
77 | if (priv->del_list_idx == MAX_NUM_TID) | ||
78 | priv->del_list_idx = 0; | ||
79 | ra_list = &priv->wmm.tid_tbl_ptr[priv->del_list_idx].ra_list; | ||
80 | if (mwifiex_uap_del_tx_pkts_in_ralist(priv, ra_list)) { | ||
81 | priv->del_list_idx++; | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | ||
87 | } | ||
88 | |||
89 | |||
27 | static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, | 90 | static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, |
28 | struct sk_buff *skb) | 91 | struct sk_buff *skb) |
29 | { | 92 | { |
@@ -40,10 +103,11 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, | |||
40 | rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); | 103 | rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); |
41 | 104 | ||
42 | if ((atomic_read(&adapter->pending_bridged_pkts) >= | 105 | if ((atomic_read(&adapter->pending_bridged_pkts) >= |
43 | MWIFIEX_BRIDGED_PKTS_THRESHOLD)) { | 106 | MWIFIEX_BRIDGED_PKTS_THR_HIGH)) { |
44 | dev_err(priv->adapter->dev, | 107 | dev_err(priv->adapter->dev, |
45 | "Tx: Bridge packet limit reached. Drop packet!\n"); | 108 | "Tx: Bridge packet limit reached. Drop packet!\n"); |
46 | kfree_skb(skb); | 109 | kfree_skb(skb); |
110 | mwifiex_uap_cleanup_tx_queues(priv); | ||
47 | return; | 111 | return; |
48 | } | 112 | } |
49 | 113 | ||