531-ath9k_fix_ap_ps_buffering.patch 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. --- a/drivers/net/wireless/ath/ath9k/ath9k.h
  2. +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
  3. @@ -205,6 +205,7 @@ struct ath_atx_ac {
  4. int sched;
  5. struct list_head list;
  6. struct list_head tid_q;
  7. + bool clear_ps_filter;
  8. };
  9. struct ath_frame_info {
  10. @@ -262,6 +263,8 @@ struct ath_node {
  11. struct ath_atx_ac ac[WME_NUM_AC];
  12. u16 maxampdu;
  13. u8 mpdudensity;
  14. +
  15. + bool sleeping;
  16. };
  17. #define AGGR_CLEANUP BIT(1)
  18. @@ -343,6 +346,9 @@ int ath_tx_aggr_start(struct ath_softc *
  19. void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
  20. void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
  21. +void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
  22. +bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an);
  23. +
  24. /********/
  25. /* VIFs */
  26. /********/
  27. --- a/drivers/net/wireless/ath/ath9k/main.c
  28. +++ b/drivers/net/wireless/ath/ath9k/main.c
  29. @@ -1791,6 +1791,27 @@ static int ath9k_sta_remove(struct ieee8
  30. return 0;
  31. }
  32. +static void ath9k_sta_notify(struct ieee80211_hw *hw,
  33. + struct ieee80211_vif *vif,
  34. + enum sta_notify_cmd cmd,
  35. + struct ieee80211_sta *sta)
  36. +{
  37. + struct ath_softc *sc = hw->priv;
  38. + struct ath_node *an = (struct ath_node *) sta->drv_priv;
  39. +
  40. + switch (cmd) {
  41. + case STA_NOTIFY_SLEEP:
  42. + an->sleeping = true;
  43. + if (ath_tx_aggr_sleep(sc, an))
  44. + ieee80211_sta_set_tim(sta);
  45. + break;
  46. + case STA_NOTIFY_AWAKE:
  47. + an->sleeping = false;
  48. + ath_tx_aggr_wakeup(sc, an);
  49. + break;
  50. + }
  51. +}
  52. +
  53. static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
  54. const struct ieee80211_tx_queue_params *params)
  55. {
  56. @@ -2130,6 +2151,7 @@ struct ieee80211_ops ath9k_ops = {
  57. .configure_filter = ath9k_configure_filter,
  58. .sta_add = ath9k_sta_add,
  59. .sta_remove = ath9k_sta_remove,
  60. + .sta_notify = ath9k_sta_notify,
  61. .conf_tx = ath9k_conf_tx,
  62. .bss_info_changed = ath9k_bss_info_changed,
  63. .set_key = ath9k_set_key,
  64. --- a/drivers/net/wireless/ath/ath9k/xmit.c
  65. +++ b/drivers/net/wireless/ath/ath9k/xmit.c
  66. @@ -357,6 +357,7 @@ static void ath_tx_complete_aggr(struct
  67. struct ath_frame_info *fi;
  68. int nframes;
  69. u8 tidno;
  70. + bool clear_filter;
  71. skb = bf->bf_mpdu;
  72. hdr = (struct ieee80211_hdr *)skb->data;
  73. @@ -442,7 +443,11 @@ static void ath_tx_complete_aggr(struct
  74. acked_cnt++;
  75. } else {
  76. if (!(tid->state & AGGR_CLEANUP) && retry) {
  77. - if (fi->retries < ATH_MAX_SW_RETRIES) {
  78. + if (ts->ts_status & ATH9K_TXERR_FILT) {
  79. + if (!an->sleeping)
  80. + clear_filter = true;
  81. + txpending = 1;
  82. + } else if (fi->retries < ATH_MAX_SW_RETRIES) {
  83. ath_tx_set_retry(sc, txq, bf->bf_mpdu);
  84. txpending = 1;
  85. } else {
  86. @@ -496,6 +501,7 @@ static void ath_tx_complete_aggr(struct
  87. !txfail, sendbar);
  88. } else {
  89. /* retry the un-acked ones */
  90. + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
  91. if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
  92. if (bf->bf_next == NULL && bf_last->bf_stale) {
  93. struct ath_buf *tbf;
  94. @@ -547,6 +553,8 @@ static void ath_tx_complete_aggr(struct
  95. /* prepend un-acked frames to the beginning of the pending frame queue */
  96. if (!list_empty(&bf_pending)) {
  97. spin_lock_bh(&txq->axq_lock);
  98. + if (clear_filter)
  99. + tid->ac->clear_ps_filter = true;
  100. list_splice(&bf_pending, &tid->buf_q);
  101. ath_tx_queue_tid(txq, tid);
  102. spin_unlock_bh(&txq->axq_lock);
  103. @@ -816,6 +824,11 @@ static void ath_tx_sched_aggr(struct ath
  104. bf = list_first_entry(&bf_q, struct ath_buf, list);
  105. bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
  106. + if (tid->ac->clear_ps_filter) {
  107. + tid->ac->clear_ps_filter = false;
  108. + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
  109. + }
  110. +
  111. /* if only one frame, send as non-aggregate */
  112. if (bf == bf->bf_lastbf) {
  113. fi = get_frame_info(bf->bf_mpdu);
  114. @@ -896,6 +909,67 @@ void ath_tx_aggr_stop(struct ath_softc *
  115. ath_tx_flush_tid(sc, txtid);
  116. }
  117. +bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
  118. +{
  119. + struct ath_atx_tid *tid;
  120. + struct ath_atx_ac *ac;
  121. + struct ath_txq *txq;
  122. + bool buffered = false;
  123. + int tidno;
  124. +
  125. + for (tidno = 0, tid = &an->tid[tidno];
  126. + tidno < WME_NUM_TID; tidno++, tid++) {
  127. +
  128. + if (!tid->sched)
  129. + continue;
  130. +
  131. + ac = tid->ac;
  132. + txq = ac->txq;
  133. +
  134. + spin_lock_bh(&txq->axq_lock);
  135. +
  136. + if (!list_empty(&tid->buf_q))
  137. + buffered = true;
  138. +
  139. + tid->sched = false;
  140. + list_del(&tid->list);
  141. +
  142. + if (ac->sched) {
  143. + ac->sched = false;
  144. + list_del(&ac->list);
  145. + }
  146. +
  147. + spin_unlock_bh(&txq->axq_lock);
  148. + }
  149. +
  150. + return buffered;
  151. +}
  152. +
  153. +void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
  154. +{
  155. + struct ath_atx_tid *tid;
  156. + struct ath_atx_ac *ac;
  157. + struct ath_txq *txq;
  158. + int tidno;
  159. +
  160. + for (tidno = 0, tid = &an->tid[tidno];
  161. + tidno < WME_NUM_TID; tidno++, tid++) {
  162. +
  163. + ac = tid->ac;
  164. + txq = ac->txq;
  165. +
  166. + spin_lock_bh(&txq->axq_lock);
  167. + ac->clear_ps_filter = true;
  168. +
  169. + if (!list_empty(&tid->buf_q) && !tid->paused) {
  170. + ath_tx_queue_tid(txq, tid);
  171. + ath_txq_schedule(sc, txq);
  172. + }
  173. +
  174. + spin_unlock_bh(&txq->axq_lock);
  175. + }
  176. +}
  177. +
  178. void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
  179. {
  180. struct ath_atx_tid *txtid;
  181. @@ -1492,7 +1566,6 @@ static int setup_tx_flags(struct sk_buff
  182. struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
  183. int flags = 0;
  184. - flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
  185. flags |= ATH9K_TXDESC_INTREQ;
  186. if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
  187. @@ -1755,6 +1828,9 @@ static void ath_tx_start_dma(struct ath_
  188. if (txctl->paprd)
  189. bf->bf_state.bfs_paprd_timestamp = jiffies;
  190. + if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
  191. + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
  192. +
  193. ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
  194. }
  195. --- a/drivers/net/wireless/ath/ath9k/hw-ops.h
  196. +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
  197. @@ -128,6 +128,11 @@ static inline void ath9k_hw_set11n_virtu
  198. ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
  199. }
  200. +static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
  201. +{
  202. + ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
  203. +}
  204. +
  205. /* Private hardware call ops */
  206. /* PHY ops */
  207. --- a/drivers/net/wireless/ath/ath9k/hw.h
  208. +++ b/drivers/net/wireless/ath/ath9k/hw.h
  209. @@ -642,6 +642,7 @@ struct ath_hw_ops {
  210. u32 burstDuration);
  211. void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
  212. u32 vmf);
  213. + void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
  214. };
  215. struct ath_nf_limits {
  216. --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
  217. +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
  218. @@ -290,7 +290,6 @@ static void ar9002_hw_set11n_txdesc(stru
  219. | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
  220. | SM(txPower, AR_XmitPower)
  221. | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
  222. - | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
  223. | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
  224. | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
  225. @@ -311,6 +310,16 @@ static void ar9002_hw_set11n_txdesc(stru
  226. }
  227. }
  228. +static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
  229. +{
  230. + struct ar5416_desc *ads = AR5416DESC(ds);
  231. +
  232. + if (val)
  233. + ads->ds_ctl0 |= AR_ClrDestMask;
  234. + else
  235. + ads->ds_ctl0 &= ~AR_ClrDestMask;
  236. +}
  237. +
  238. static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
  239. void *lastds,
  240. u32 durUpdateEn, u32 rtsctsRate,
  241. @@ -460,4 +469,5 @@ void ar9002_hw_attach_mac_ops(struct ath
  242. ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
  243. ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
  244. ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
  245. + ops->set_clrdmask = ar9002_hw_set_clrdmask;
  246. }
  247. --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
  248. +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
  249. @@ -329,7 +329,6 @@ static void ar9003_hw_set11n_txdesc(stru
  250. | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
  251. | SM(txpower, AR_XmitPower)
  252. | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
  253. - | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
  254. | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
  255. | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
  256. @@ -350,6 +349,16 @@ static void ar9003_hw_set11n_txdesc(stru
  257. ads->ctl22 = 0;
  258. }
  259. +static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
  260. +{
  261. + struct ar9003_txc *ads = (struct ar9003_txc *) ds;
  262. +
  263. + if (val)
  264. + ads->ctl11 |= AR_ClrDestMask;
  265. + else
  266. + ads->ctl11 &= ~AR_ClrDestMask;
  267. +}
  268. +
  269. static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
  270. void *lastds,
  271. u32 durUpdateEn, u32 rtsctsRate,
  272. @@ -522,6 +531,7 @@ void ar9003_hw_attach_mac_ops(struct ath
  273. ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
  274. ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
  275. ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
  276. + ops->set_clrdmask = ar9003_hw_set_clrdmask;
  277. }
  278. void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
  279. --- a/drivers/net/wireless/ath/ath9k/mac.h
  280. +++ b/drivers/net/wireless/ath/ath9k/mac.h
  281. @@ -239,7 +239,6 @@ struct ath_desc {
  282. void *ds_vdata;
  283. } __packed __aligned(4);
  284. -#define ATH9K_TXDESC_CLRDMASK 0x0001
  285. #define ATH9K_TXDESC_NOACK 0x0002
  286. #define ATH9K_TXDESC_RTSENA 0x0004
  287. #define ATH9K_TXDESC_CTSENA 0x0008