aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/carl9170/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/carl9170/tx.c')
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c157
1 files changed, 104 insertions, 53 deletions
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index cb70ed7ec5cc..bf2eff9dd582 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -104,6 +104,56 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
104 spin_unlock_bh(&ar->tx_stats_lock); 104 spin_unlock_bh(&ar->tx_stats_lock);
105} 105}
106 106
107/* needs rcu_read_lock */
108static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar,
109 struct sk_buff *skb)
110{
111 struct _carl9170_tx_superframe *super = (void *) skb->data;
112 struct ieee80211_hdr *hdr = (void *) super->frame_data;
113 struct ieee80211_vif *vif;
114 unsigned int vif_id;
115
116 vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
117 CARL9170_TX_SUPER_MISC_VIF_ID_S;
118
119 if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
120 return NULL;
121
122 vif = rcu_dereference(ar->vif_priv[vif_id].vif);
123 if (unlikely(!vif))
124 return NULL;
125
126 /*
127 * Normally we should use wrappers like ieee80211_get_DA to get
128 * the correct peer ieee80211_sta.
129 *
130 * But there is a problem with indirect traffic (broadcasts, or
131 * data which is designated for other stations) in station mode.
132 * The frame will be directed to the AP for distribution and not
133 * to the actual destination.
134 */
135
136 return ieee80211_find_sta(vif, hdr->addr1);
137}
138
139static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb)
140{
141 struct ieee80211_sta *sta;
142 struct carl9170_sta_info *sta_info;
143
144 rcu_read_lock();
145 sta = __carl9170_get_tx_sta(ar, skb);
146 if (unlikely(!sta))
147 goto out_rcu;
148
149 sta_info = (struct carl9170_sta_info *) sta->drv_priv;
150 if (atomic_dec_return(&sta_info->pending_frames) == 0)
151 ieee80211_sta_block_awake(ar->hw, sta, false);
152
153out_rcu:
154 rcu_read_unlock();
155}
156
107static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) 157static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
108{ 158{
109 struct ieee80211_tx_info *txinfo; 159 struct ieee80211_tx_info *txinfo;
@@ -135,6 +185,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
135 } 185 }
136 186
137 spin_unlock_bh(&ar->tx_stats_lock); 187 spin_unlock_bh(&ar->tx_stats_lock);
188
138 if (atomic_dec_and_test(&ar->tx_total_queued)) 189 if (atomic_dec_and_test(&ar->tx_total_queued))
139 complete(&ar->tx_flush); 190 complete(&ar->tx_flush);
140} 191}
@@ -329,13 +380,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
329{ 380{
330 struct _carl9170_tx_superframe *super = (void *) skb->data; 381 struct _carl9170_tx_superframe *super = (void *) skb->data;
331 struct ieee80211_hdr *hdr = (void *) super->frame_data; 382 struct ieee80211_hdr *hdr = (void *) super->frame_data;
332 struct ieee80211_tx_info *tx_info;
333 struct carl9170_tx_info *ar_info; 383 struct carl9170_tx_info *ar_info;
334 struct carl9170_sta_info *sta_info;
335 struct ieee80211_sta *sta; 384 struct ieee80211_sta *sta;
385 struct carl9170_sta_info *sta_info;
336 struct carl9170_sta_tid *tid_info; 386 struct carl9170_sta_tid *tid_info;
337 struct ieee80211_vif *vif;
338 unsigned int vif_id;
339 u8 tid; 387 u8 tid;
340 388
341 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || 389 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
@@ -343,30 +391,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
343 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) 391 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
344 return; 392 return;
345 393
346 tx_info = IEEE80211_SKB_CB(skb); 394 ar_info = (void *) txinfo->rate_driver_data;
347 ar_info = (void *) tx_info->rate_driver_data;
348
349 vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
350 CARL9170_TX_SUPER_MISC_VIF_ID_S;
351
352 if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
353 return;
354 395
355 rcu_read_lock(); 396 rcu_read_lock();
356 vif = rcu_dereference(ar->vif_priv[vif_id].vif); 397 sta = __carl9170_get_tx_sta(ar, skb);
357 if (unlikely(!vif))
358 goto out_rcu;
359
360 /*
361 * Normally we should use wrappers like ieee80211_get_DA to get
362 * the correct peer ieee80211_sta.
363 *
364 * But there is a problem with indirect traffic (broadcasts, or
365 * data which is designated for other stations) in station mode.
366 * The frame will be directed to the AP for distribution and not
367 * to the actual destination.
368 */
369 sta = ieee80211_find_sta(vif, hdr->addr1);
370 if (unlikely(!sta)) 398 if (unlikely(!sta))
371 goto out_rcu; 399 goto out_rcu;
372 400
@@ -427,6 +455,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
427 if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) 455 if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
428 carl9170_tx_status_process_ampdu(ar, skb, txinfo); 456 carl9170_tx_status_process_ampdu(ar, skb, txinfo);
429 457
458 carl9170_tx_ps_unblock(ar, skb);
430 carl9170_tx_put_skb(skb); 459 carl9170_tx_put_skb(skb);
431} 460}
432 461
@@ -540,11 +569,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
540 struct sk_buff *skb; 569 struct sk_buff *skb;
541 struct ieee80211_tx_info *txinfo; 570 struct ieee80211_tx_info *txinfo;
542 struct carl9170_tx_info *arinfo; 571 struct carl9170_tx_info *arinfo;
543 struct _carl9170_tx_superframe *super;
544 struct ieee80211_sta *sta; 572 struct ieee80211_sta *sta;
545 struct ieee80211_vif *vif;
546 struct ieee80211_hdr *hdr;
547 unsigned int vif_id;
548 573
549 rcu_read_lock(); 574 rcu_read_lock();
550 list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { 575 list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
@@ -562,20 +587,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
562 msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) 587 msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
563 goto unlock; 588 goto unlock;
564 589
565 super = (void *) skb->data; 590 sta = __carl9170_get_tx_sta(ar, skb);
566 hdr = (void *) super->frame_data;
567
568 vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
569 CARL9170_TX_SUPER_MISC_VIF_ID_S;
570
571 if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
572 goto unlock;
573
574 vif = rcu_dereference(ar->vif_priv[vif_id].vif);
575 if (WARN_ON(!vif))
576 goto unlock;
577
578 sta = ieee80211_find_sta(vif, hdr->addr1);
579 if (WARN_ON(!sta)) 591 if (WARN_ON(!sta))
580 goto unlock; 592 goto unlock;
581 593
@@ -1199,15 +1211,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
1199 arinfo = (void *) info->rate_driver_data; 1211 arinfo = (void *) info->rate_driver_data;
1200 1212
1201 arinfo->timeout = jiffies; 1213 arinfo->timeout = jiffies;
1202
1203 /*
1204 * increase ref count to "2".
1205 * Ref counting is the easiest way to solve the race between
1206 * the the urb's completion routine: carl9170_tx_callback and
1207 * wlan tx status functions: carl9170_tx_status/janitor.
1208 */
1209 carl9170_tx_get_skb(skb);
1210
1211 return skb; 1214 return skb;
1212 1215
1213err_unlock: 1216err_unlock:
@@ -1228,6 +1231,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
1228 __carl9170_tx_process_status(ar, super->s.cookie, q); 1231 __carl9170_tx_process_status(ar, super->s.cookie, q);
1229} 1232}
1230 1233
1234static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
1235{
1236 struct ieee80211_sta *sta;
1237 struct carl9170_sta_info *sta_info;
1238
1239 rcu_read_lock();
1240 sta = __carl9170_get_tx_sta(ar, skb);
1241 if (!sta)
1242 goto out_rcu;
1243
1244 sta_info = (void *) sta->drv_priv;
1245 if (unlikely(sta_info->sleeping)) {
1246 struct ieee80211_tx_info *tx_info;
1247
1248 rcu_read_unlock();
1249
1250 tx_info = IEEE80211_SKB_CB(skb);
1251 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
1252 atomic_dec(&ar->tx_ampdu_upload);
1253
1254 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1255 carl9170_tx_status(ar, skb, false);
1256 return true;
1257 }
1258
1259out_rcu:
1260 rcu_read_unlock();
1261 return false;
1262}
1263
1231static void carl9170_tx(struct ar9170 *ar) 1264static void carl9170_tx(struct ar9170 *ar)
1232{ 1265{
1233 struct sk_buff *skb; 1266 struct sk_buff *skb;
@@ -1247,6 +1280,9 @@ static void carl9170_tx(struct ar9170 *ar)
1247 if (unlikely(!skb)) 1280 if (unlikely(!skb))
1248 break; 1281 break;
1249 1282
1283 if (unlikely(carl9170_tx_ps_drop(ar, skb)))
1284 continue;
1285
1250 atomic_inc(&ar->tx_total_pending); 1286 atomic_inc(&ar->tx_total_pending);
1251 1287
1252 q = __carl9170_get_queue(ar, i); 1288 q = __carl9170_get_queue(ar, i);
@@ -1256,6 +1292,16 @@ static void carl9170_tx(struct ar9170 *ar)
1256 */ 1292 */
1257 skb_queue_tail(&ar->tx_status[q], skb); 1293 skb_queue_tail(&ar->tx_status[q], skb);
1258 1294
1295 /*
1296 * increase ref count to "2".
1297 * Ref counting is the easiest way to solve the
1298 * race between the urb's completion routine:
1299 * carl9170_tx_callback
1300 * and wlan tx status functions:
1301 * carl9170_tx_status/janitor.
1302 */
1303 carl9170_tx_get_skb(skb);
1304
1259 carl9170_usb_tx(ar, skb); 1305 carl9170_usb_tx(ar, skb);
1260 schedule_garbagecollector = true; 1306 schedule_garbagecollector = true;
1261 } 1307 }
@@ -1368,6 +1414,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1368 * all ressouces which are associated with the frame. 1414 * all ressouces which are associated with the frame.
1369 */ 1415 */
1370 1416
1417 if (sta) {
1418 struct carl9170_sta_info *stai = (void *) sta->drv_priv;
1419 atomic_inc(&stai->pending_frames);
1420 }
1421
1371 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1422 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1372 run = carl9170_tx_ampdu_queue(ar, sta, skb); 1423 run = carl9170_tx_ampdu_queue(ar, sta, skb);
1373 if (run) 1424 if (run)