aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-05-24 16:47:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-24 16:47:54 -0400
commit31ec97d9cebac804814de298592648f7c18d8281 (patch)
treef725fcce0d5a9d6d7bd64b777de0a44e71773d0e /drivers/net/wireless/mwifiex
parent557eed603159b4e007c57d97fad1333ecebd3c2e (diff)
parentdaf8cf608d57a0b9f22276036e420cc82cf6ab4f (diff)
Merge ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c4
-rw-r--r--drivers/net/wireless/mwifiex/main.h9
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c4
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c59
4 files changed, 60 insertions, 16 deletions
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index d3d5e0853c4..f807447e4d9 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -196,6 +196,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
196 if (skb_src) 196 if (skb_src)
197 pra_list->total_pkts_size -= skb_src->len; 197 pra_list->total_pkts_size -= skb_src->len;
198 198
199 atomic_dec(&priv->wmm.tx_pkts_queued);
200
199 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 201 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
200 ra_list_flags); 202 ra_list_flags);
201 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); 203 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
@@ -257,6 +259,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
257 259
258 pra_list->total_pkts_size += skb_aggr->len; 260 pra_list->total_pkts_size += skb_aggr->len;
259 261
262 atomic_inc(&priv->wmm.tx_pkts_queued);
263
260 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; 264 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
261 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 265 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
262 ra_list_flags); 266 ra_list_flags);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 672701dc272..8316b3cd92c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -69,7 +69,8 @@ struct mwifiex_drv_mode {
69#define MWIFIEX_TIMER_10S 10000 69#define MWIFIEX_TIMER_10S 10000
70#define MWIFIEX_TIMER_1S 1000 70#define MWIFIEX_TIMER_1S 1000
71 71
72#define MAX_TX_PENDING 60 72#define MAX_TX_PENDING 100
73#define LOW_TX_PENDING 80
73 74
74#define MWIFIEX_UPLD_SIZE (2312) 75#define MWIFIEX_UPLD_SIZE (2312)
75 76
@@ -202,6 +203,7 @@ struct mwifiex_tid_tbl {
202#define WMM_HIGHEST_PRIORITY 7 203#define WMM_HIGHEST_PRIORITY 7
203#define HIGH_PRIO_TID 7 204#define HIGH_PRIO_TID 7
204#define LOW_PRIO_TID 0 205#define LOW_PRIO_TID 0
206#define NO_PKT_PRIO_TID (-1)
205 207
206struct mwifiex_wmm_desc { 208struct mwifiex_wmm_desc {
207 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; 209 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
@@ -213,7 +215,10 @@ struct mwifiex_wmm_desc {
213 u32 drv_pkt_delay_max; 215 u32 drv_pkt_delay_max;
214 u8 queue_priority[IEEE80211_MAX_QUEUES]; 216 u8 queue_priority[IEEE80211_MAX_QUEUES];
215 u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ 217 u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */
216 218 /* Number of transmit packets queued */
219 atomic_t tx_pkts_queued;
220 /* Tracks highest priority with a packet queued */
221 atomic_t highest_queued_prio;
217}; 222};
218 223
219struct mwifiex_802_11_security { 224struct mwifiex_802_11_security {
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 210120889df..aaa50c07419 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -140,7 +140,9 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
140 } else { 140 } else {
141 priv->stats.tx_errors++; 141 priv->stats.tx_errors++;
142 } 142 }
143 atomic_dec(&adapter->tx_pending); 143
144 if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING)
145 goto done;
144 146
145 for (i = 0; i < adapter->priv_num; i++) { 147 for (i = 0; i < adapter->priv_num; i++) {
146 148
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index faa09e32902..91634daec30 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -177,14 +177,20 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
177 * This function map ACs to TIDs. 177 * This function map ACs to TIDs.
178 */ 178 */
179static void 179static void
180mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) 180mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm)
181{ 181{
182 u8 *queue_priority = wmm->queue_priority;
182 int i; 183 int i;
183 184
184 for (i = 0; i < 4; ++i) { 185 for (i = 0; i < 4; ++i) {
185 tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; 186 tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
186 tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; 187 tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
187 } 188 }
189
190 for (i = 0; i < MAX_NUM_TID; ++i)
191 tos_to_tid_inv[tos_to_tid[i]] = (u8)i;
192
193 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID);
188} 194}
189 195
190/* 196/*
@@ -246,7 +252,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
246 } 252 }
247 } 253 }
248 254
249 mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); 255 mwifiex_wmm_queue_priorities_tid(&priv->wmm);
250} 256}
251 257
252/* 258/*
@@ -399,6 +405,9 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
399 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; 405 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
400 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; 406 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
401 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; 407 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
408
409 atomic_set(&priv->wmm.tx_pkts_queued, 0);
410 atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
402 } 411 }
403} 412}
404 413
@@ -408,17 +417,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
408int 417int
409mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) 418mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
410{ 419{
411 int i, j; 420 int i;
412 struct mwifiex_private *priv; 421 struct mwifiex_private *priv;
413 422
414 for (j = 0; j < adapter->priv_num; ++j) { 423 for (i = 0; i < adapter->priv_num; ++i) {
415 priv = adapter->priv[j]; 424 priv = adapter->priv[i];
416 if (priv) { 425 if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
417 for (i = 0; i < MAX_NUM_TID; i++) 426 return false;
418 if (!mwifiex_wmm_is_ra_list_empty(
419 &priv->wmm.tid_tbl_ptr[i].ra_list))
420 return false;
421 }
422 } 427 }
423 428
424 return true; 429 return true;
@@ -468,6 +473,9 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
468 for (i = 0; i < MAX_NUM_TID; i++) 473 for (i = 0; i < MAX_NUM_TID; i++)
469 mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. 474 mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
470 ra_list); 475 ra_list);
476
477 atomic_set(&priv->wmm.tx_pkts_queued, 0);
478 atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
471} 479}
472 480
473/* 481/*
@@ -638,6 +646,13 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
638 646
639 ra_list->total_pkts_size += skb->len; 647 ra_list->total_pkts_size += skb->len;
640 648
649 atomic_inc(&priv->wmm.tx_pkts_queued);
650
651 if (atomic_read(&priv->wmm.highest_queued_prio) <
652 tos_to_tid_inv[tid_down])
653 atomic_set(&priv->wmm.highest_queued_prio,
654 tos_to_tid_inv[tid_down]);
655
641 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 656 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
642} 657}
643 658
@@ -863,9 +878,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
863 } 878 }
864 879
865 do { 880 do {
881 atomic_t *hqp;
882 spinlock_t *lock;
883
866 priv_tmp = bssprio_node->priv; 884 priv_tmp = bssprio_node->priv;
885 hqp = &priv_tmp->wmm.highest_queued_prio;
886 lock = &priv_tmp->wmm.ra_list_spinlock;
867 887
868 for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { 888 for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
869 889
870 tid_ptr = &(priv_tmp)->wmm. 890 tid_ptr = &(priv_tmp)->wmm.
871 tid_tbl_ptr[tos_to_tid[i]]; 891 tid_tbl_ptr[tos_to_tid[i]];
@@ -903,6 +923,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
903 is_list_empty = 923 is_list_empty =
904 skb_queue_empty(&ptr->skb_head); 924 skb_queue_empty(&ptr->skb_head);
905 if (!is_list_empty) { 925 if (!is_list_empty) {
926 spin_lock_irqsave(lock, flags);
927 if (atomic_read(hqp) > i)
928 atomic_set(hqp, i);
929 spin_unlock_irqrestore(lock,
930 flags);
906 *priv = priv_tmp; 931 *priv = priv_tmp;
907 *tid = tos_to_tid[i]; 932 *tid = tos_to_tid[i];
908 return ptr; 933 return ptr;
@@ -921,6 +946,12 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
921 } while (ptr != head); 946 } while (ptr != head);
922 } 947 }
923 948
949 /* No packet at any TID for this priv. Mark as such
950 * to skip checking TIDs for this priv (until pkt is
951 * added).
952 */
953 atomic_set(hqp, NO_PKT_PRIO_TID);
954
924 /* Get next bss priority node */ 955 /* Get next bss priority node */
925 bssprio_node = list_first_entry(&bssprio_node->list, 956 bssprio_node = list_first_entry(&bssprio_node->list,
926 struct mwifiex_bss_prio_node, 957 struct mwifiex_bss_prio_node,
@@ -1028,6 +1059,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1028 .bss_prio_cur->list, 1059 .bss_prio_cur->list,
1029 struct mwifiex_bss_prio_node, 1060 struct mwifiex_bss_prio_node,
1030 list); 1061 list);
1062 atomic_dec(&priv->wmm.tx_pkts_queued);
1031 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1063 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1032 ra_list_flags); 1064 ra_list_flags);
1033 } 1065 }
@@ -1134,6 +1166,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1134 .bss_prio_cur->list, 1166 .bss_prio_cur->list,
1135 struct mwifiex_bss_prio_node, 1167 struct mwifiex_bss_prio_node,
1136 list); 1168 list);
1169 atomic_dec(&priv->wmm.tx_pkts_queued);
1137 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1170 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1138 ra_list_flags); 1171 ra_list_flags);
1139 } 1172 }
@@ -1227,5 +1260,5 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1227 1260
1228 if (mwifiex_dequeue_tx_packet(adapter)) 1261 if (mwifiex_dequeue_tx_packet(adapter))
1229 break; 1262 break;
1230 } while (true); 1263 } while (!mwifiex_wmm_lists_empty(adapter));
1231} 1264}