334-mac80211-fix-purging-multicast-PS-buffer-queue.patch 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. From: Felix Fietkau <[email protected]>
  2. Date: Tue, 2 Aug 2016 11:11:13 +0200
  3. Subject: [PATCH] mac80211: fix purging multicast PS buffer queue
  4. The code currently assumes that buffered multicast PS frames don't have
  5. a pending ACK frame for tx status reporting.
  6. However, hostapd sends a broadcast deauth frame on teardown for which tx
  7. status is requested. This can lead to the "Have pending ack frames"
  8. warning on module reload.
  9. Fix this by using ieee80211_free_txskb/ieee80211_purge_tx_queue.
  10. Signed-off-by: Felix Fietkau <[email protected]>
  11. ---
  12. --- a/net/mac80211/cfg.c
  13. +++ b/net/mac80211/cfg.c
  14. @@ -868,7 +868,7 @@ static int ieee80211_stop_ap(struct wiph
  15. /* free all potentially still buffered bcast frames */
  16. local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
  17. - skb_queue_purge(&sdata->u.ap.ps.bc_buf);
  18. + ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf);
  19. mutex_lock(&local->mtx);
  20. ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
  21. --- a/net/mac80211/tx.c
  22. +++ b/net/mac80211/tx.c
  23. @@ -368,7 +368,7 @@ static void purge_old_ps_buffers(struct
  24. skb = skb_dequeue(&ps->bc_buf);
  25. if (skb) {
  26. purged++;
  27. - dev_kfree_skb(skb);
  28. + ieee80211_free_txskb(&local->hw, skb);
  29. }
  30. total += skb_queue_len(&ps->bc_buf);
  31. }
  32. @@ -451,7 +451,7 @@ ieee80211_tx_h_multicast_ps_buf(struct i
  33. if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) {
  34. ps_dbg(tx->sdata,
  35. "BC TX buffer full - dropping the oldest frame\n");
  36. - dev_kfree_skb(skb_dequeue(&ps->bc_buf));
  37. + ieee80211_free_txskb(&tx->local->hw, skb_dequeue(&ps->bc_buf));
  38. } else
  39. tx->local->total_ps_buffered++;
  40. @@ -4276,7 +4276,7 @@ ieee80211_get_buffered_bc(struct ieee802
  41. sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
  42. if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb))
  43. break;
  44. - dev_kfree_skb_any(skb);
  45. + ieee80211_free_txskb(hw, skb);
  46. }
  47. info = IEEE80211_SKB_CB(skb);