aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvinash Patil <patila@marvell.com>2013-07-22 22:17:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-07-24 11:02:05 -0400
commit61c873045f74b16317c88e2931637329a6844564 (patch)
tree958660932b119dbb9ad5142d169f35e717243149
parentc7d9ed9ec9b2947a9c5dc5e2c7afce1fd3ad82cc (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.h3
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.h1
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c66
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
80enum mwifiex_bss_type { 81enum 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
520enum mwifiex_ba_status { 521enum 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 */
32static bool
33mwifiex_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 */
68static 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
27static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, 90static 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