diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-29 10:04:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-30 15:57:12 -0400 |
commit | 948d887dec1042a7d78ae311908113e26502062f (patch) | |
tree | e4240d0f45c0200d3625693bd6d543d243859d0a /net/mac80211/tx.c | |
parent | 60750397122fe0fb81a6e52fd790b3f749b6e010 (diff) |
mac80211: split PS buffers into ACs
For uAPSD support we'll need to have per-AC PS
buffers. As this is a major undertaking, split
the buffers before really adding support for
uAPSD. This already makes some reference to the
uapsd_queues variable, but for now that will
never be non-zero.
Since book-keeping is complicated, also change
the logic for keeping a maximum of frames only
and allow 64 frames per AC (up from 128 for a
station).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d6754908ff79..a1029449df44 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -343,13 +343,22 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
343 | total += skb_queue_len(&ap->ps_bc_buf); | 343 | total += skb_queue_len(&ap->ps_bc_buf); |
344 | } | 344 | } |
345 | 345 | ||
346 | /* | ||
347 | * Drop one frame from each station from the lowest-priority | ||
348 | * AC that has frames at all. | ||
349 | */ | ||
346 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 350 | list_for_each_entry_rcu(sta, &local->sta_list, list) { |
347 | skb = skb_dequeue(&sta->ps_tx_buf); | 351 | int ac; |
348 | if (skb) { | 352 | |
349 | purged++; | 353 | for (ac = IEEE80211_AC_BK; ac >= IEEE80211_AC_VO; ac--) { |
350 | dev_kfree_skb(skb); | 354 | skb = skb_dequeue(&sta->ps_tx_buf[ac]); |
355 | total += skb_queue_len(&sta->ps_tx_buf[ac]); | ||
356 | if (skb) { | ||
357 | purged++; | ||
358 | dev_kfree_skb(skb); | ||
359 | break; | ||
360 | } | ||
351 | } | 361 | } |
352 | total += skb_queue_len(&sta->ps_tx_buf); | ||
353 | } | 362 | } |
354 | 363 | ||
355 | rcu_read_unlock(); | 364 | rcu_read_unlock(); |
@@ -448,22 +457,21 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
448 | 457 | ||
449 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && | 458 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && |
450 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { | 459 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { |
460 | int ac = skb_get_queue_mapping(tx->skb); | ||
461 | |||
451 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 462 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
452 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " | 463 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", |
453 | "before %d)\n", | 464 | sta->sta.addr, sta->sta.aid, ac); |
454 | sta->sta.addr, sta->sta.aid, | ||
455 | skb_queue_len(&sta->ps_tx_buf)); | ||
456 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 465 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
457 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 466 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
458 | purge_old_ps_buffers(tx->local); | 467 | purge_old_ps_buffers(tx->local); |
459 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 468 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { |
460 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 469 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); |
461 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 470 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
462 | if (net_ratelimit()) { | 471 | if (net_ratelimit()) |
463 | printk(KERN_DEBUG "%s: STA %pM TX " | 472 | printk(KERN_DEBUG "%s: STA %pM TX buffer for " |
464 | "buffer full - dropping oldest frame\n", | 473 | "AC %d full - dropping oldest frame\n", |
465 | tx->sdata->name, sta->sta.addr); | 474 | tx->sdata->name, sta->sta.addr, ac); |
466 | } | ||
467 | #endif | 475 | #endif |
468 | dev_kfree_skb(old); | 476 | dev_kfree_skb(old); |
469 | } else | 477 | } else |
@@ -472,7 +480,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
472 | info->control.jiffies = jiffies; | 480 | info->control.jiffies = jiffies; |
473 | info->control.vif = &tx->sdata->vif; | 481 | info->control.vif = &tx->sdata->vif; |
474 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 482 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
475 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 483 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
476 | 484 | ||
477 | if (!timer_pending(&local->sta_cleanup)) | 485 | if (!timer_pending(&local->sta_cleanup)) |
478 | mod_timer(&local->sta_cleanup, | 486 | mod_timer(&local->sta_cleanup, |