aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2015-03-27 16:30:37 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-04-01 14:44:34 -0400
commitba8c3d6f16a1f9305c23ac1d2fd3992508c5ac03 (patch)
treec03bbdf0affccbd1f3a4fd0c239e59bb44f28e99 /net/mac80211/sta_info.c
parentcef2fc1ce4326f7f24c3cf938b94a661fbe773e3 (diff)
mac80211: add an intermediate software queue implementation
This allows drivers to request per-vif and per-sta-tid queues from which they can pull frames. This makes it easier to keep the hardware queues short, and to improve fairness between clients and vifs. The task of scheduling packet transmission is left up to the driver - queueing is controlled by mac80211. Drivers can only dequeue packets by calling ieee80211_tx_dequeue. This makes it possible to add active queue management later without changing drivers using this code. This can also be used as a starting point to implement A-MSDU aggregation in a way that does not add artificially induced latency. Signed-off-by: Felix Fietkau <nbd@openwrt.org> [resolved minor context conflict, minor changes, endian annotations] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 81cc499fa4a9..12971b71d0fa 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -106,6 +106,16 @@ static void __cleanup_single_sta(struct sta_info *sta)
106 atomic_dec(&ps->num_sta_ps); 106 atomic_dec(&ps->num_sta_ps);
107 } 107 }
108 108
109 if (sta->sta.txq[0]) {
110 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
111 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
112 int n = skb_queue_len(&txqi->queue);
113
114 ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
115 atomic_sub(n, &sdata->txqs_len[txqi->txq.ac]);
116 }
117 }
118
109 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 119 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
110 local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); 120 local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
111 ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); 121 ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
@@ -218,6 +228,8 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
218 228
219 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); 229 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
220 230
231 if (sta->sta.txq[0])
232 kfree(to_txq_info(sta->sta.txq[0]));
221 kfree(rcu_dereference_raw(sta->sta.rates)); 233 kfree(rcu_dereference_raw(sta->sta.rates));
222 kfree(sta); 234 kfree(sta);
223} 235}
@@ -268,11 +280,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
268 const u8 *addr, gfp_t gfp) 280 const u8 *addr, gfp_t gfp)
269{ 281{
270 struct ieee80211_local *local = sdata->local; 282 struct ieee80211_local *local = sdata->local;
283 struct ieee80211_hw *hw = &local->hw;
271 struct sta_info *sta; 284 struct sta_info *sta;
272 struct timespec uptime; 285 struct timespec uptime;
273 int i; 286 int i;
274 287
275 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); 288 sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
276 if (!sta) 289 if (!sta)
277 return NULL; 290 return NULL;
278 291
@@ -304,11 +317,25 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
304 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) 317 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
305 ewma_init(&sta->chain_signal_avg[i], 1024, 8); 318 ewma_init(&sta->chain_signal_avg[i], 1024, 8);
306 319
307 if (sta_prepare_rate_control(local, sta, gfp)) { 320 if (local->ops->wake_tx_queue) {
308 kfree(sta); 321 void *txq_data;
309 return NULL; 322 int size = sizeof(struct txq_info) +
323 ALIGN(hw->txq_data_size, sizeof(void *));
324
325 txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp);
326 if (!txq_data)
327 goto free;
328
329 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
330 struct txq_info *txq = txq_data + i * size;
331
332 ieee80211_init_tx_queue(sdata, sta, txq, i);
333 }
310 } 334 }
311 335
336 if (sta_prepare_rate_control(local, sta, gfp))
337 goto free_txq;
338
312 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 339 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
313 /* 340 /*
314 * timer_to_tid must be initialized with identity mapping 341 * timer_to_tid must be initialized with identity mapping
@@ -329,7 +356,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
329 if (sdata->vif.type == NL80211_IFTYPE_AP || 356 if (sdata->vif.type == NL80211_IFTYPE_AP ||
330 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 357 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
331 struct ieee80211_supported_band *sband = 358 struct ieee80211_supported_band *sband =
332 local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; 359 hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
333 u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 360 u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
334 IEEE80211_HT_CAP_SM_PS_SHIFT; 361 IEEE80211_HT_CAP_SM_PS_SHIFT;
335 /* 362 /*
@@ -354,6 +381,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
354 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 381 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
355 382
356 return sta; 383 return sta;
384
385free_txq:
386 if (sta->sta.txq[0])
387 kfree(to_txq_info(sta->sta.txq[0]));
388free:
389 kfree(sta);
390 return NULL;
357} 391}
358 392
359static int sta_info_insert_check(struct sta_info *sta) 393static int sta_info_insert_check(struct sta_info *sta)
@@ -623,6 +657,8 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
623 657
624 indicate_tim |= 658 indicate_tim |=
625 sta->driver_buffered_tids & tids; 659 sta->driver_buffered_tids & tids;
660 indicate_tim |=
661 sta->txq_buffered_tids & tids;
626 } 662 }
627 663
628 done: 664 done:
@@ -1072,7 +1108,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1072 struct ieee80211_sub_if_data *sdata = sta->sdata; 1108 struct ieee80211_sub_if_data *sdata = sta->sdata;
1073 struct ieee80211_local *local = sdata->local; 1109 struct ieee80211_local *local = sdata->local;
1074 struct sk_buff_head pending; 1110 struct sk_buff_head pending;
1075 int filtered = 0, buffered = 0, ac; 1111 int filtered = 0, buffered = 0, ac, i;
1076 unsigned long flags; 1112 unsigned long flags;
1077 struct ps_data *ps; 1113 struct ps_data *ps;
1078 1114
@@ -1091,10 +1127,22 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1091 1127
1092 BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); 1128 BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
1093 sta->driver_buffered_tids = 0; 1129 sta->driver_buffered_tids = 0;
1130 sta->txq_buffered_tids = 0;
1094 1131
1095 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 1132 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
1096 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); 1133 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
1097 1134
1135 if (sta->sta.txq[0]) {
1136 for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
1137 struct txq_info *txqi = to_txq_info(sta->sta.txq[i]);
1138
1139 if (!skb_queue_len(&txqi->queue))
1140 continue;
1141
1142 drv_wake_tx_queue(local, txqi);
1143 }
1144 }
1145
1098 skb_queue_head_init(&pending); 1146 skb_queue_head_init(&pending);
1099 1147
1100 /* sync with ieee80211_tx_h_unicast_ps_buf */ 1148 /* sync with ieee80211_tx_h_unicast_ps_buf */
@@ -1276,8 +1324,10 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1276 /* if we already have frames from software, then we can't also 1324 /* if we already have frames from software, then we can't also
1277 * release from hardware queues 1325 * release from hardware queues
1278 */ 1326 */
1279 if (skb_queue_empty(&frames)) 1327 if (skb_queue_empty(&frames)) {
1280 driver_release_tids |= sta->driver_buffered_tids & tids; 1328 driver_release_tids |= sta->driver_buffered_tids & tids;
1329 driver_release_tids |= sta->txq_buffered_tids & tids;
1330 }
1281 1331
1282 if (driver_release_tids) { 1332 if (driver_release_tids) {
1283 /* If the driver has data on more than one TID then 1333 /* If the driver has data on more than one TID then
@@ -1448,6 +1498,9 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1448 1498
1449 sta_info_recalc_tim(sta); 1499 sta_info_recalc_tim(sta);
1450 } else { 1500 } else {
1501 unsigned long tids = sta->txq_buffered_tids & driver_release_tids;
1502 int tid;
1503
1451 /* 1504 /*
1452 * We need to release a frame that is buffered somewhere in the 1505 * We need to release a frame that is buffered somewhere in the
1453 * driver ... it'll have to handle that. 1506 * driver ... it'll have to handle that.
@@ -1467,8 +1520,22 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1467 * that the TID(s) became empty before returning here from the 1520 * that the TID(s) became empty before returning here from the
1468 * release function. 1521 * release function.
1469 * Either way, however, when the driver tells us that the TID(s) 1522 * Either way, however, when the driver tells us that the TID(s)
1470 * became empty we'll do the TIM recalculation. 1523 * became empty or we find that a txq became empty, we'll do the
1524 * TIM recalculation.
1471 */ 1525 */
1526
1527 if (!sta->sta.txq[0])
1528 return;
1529
1530 for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
1531 struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
1532
1533 if (!(tids & BIT(tid)) || skb_queue_len(&txqi->queue))
1534 continue;
1535
1536 sta_info_recalc_tim(sta);
1537 break;
1538 }
1472 } 1539 }
1473} 1540}
1474 1541