311-pending_work.patch 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. --- a/drivers/net/wireless/ath/ath9k/mac.c
  2. +++ b/drivers/net/wireless/ath/ath9k/mac.c
  3. @@ -766,14 +766,6 @@ void ath9k_hw_startpcureceive(struct ath
  4. }
  5. EXPORT_SYMBOL(ath9k_hw_startpcureceive);
  6. -void ath9k_hw_stoppcurecv(struct ath_hw *ah)
  7. -{
  8. - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
  9. -
  10. - ath9k_hw_disable_mib_counters(ah);
  11. -}
  12. -EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
  13. -
  14. void ath9k_hw_abortpcurecv(struct ath_hw *ah)
  15. {
  16. REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
  17. --- a/drivers/net/wireless/ath/ath9k/mac.h
  18. +++ b/drivers/net/wireless/ath/ath9k/mac.h
  19. @@ -691,7 +691,6 @@ void ath9k_hw_setuprxdesc(struct ath_hw
  20. bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
  21. void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
  22. void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
  23. -void ath9k_hw_stoppcurecv(struct ath_hw *ah);
  24. void ath9k_hw_abortpcurecv(struct ath_hw *ah);
  25. bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
  26. int ath9k_hw_beaconq_setup(struct ath_hw *ah);
  27. --- a/drivers/net/wireless/ath/ath9k/recv.c
  28. +++ b/drivers/net/wireless/ath/ath9k/recv.c
  29. @@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
  30. bool stopped;
  31. spin_lock_bh(&sc->rx.rxbuflock);
  32. - ath9k_hw_stoppcurecv(ah);
  33. + ath9k_hw_abortpcurecv(ah);
  34. ath9k_hw_setrxfilter(ah, 0);
  35. stopped = ath9k_hw_stopdmarecv(ah);
  36. --- a/drivers/net/wireless/ath/ath9k/xmit.c
  37. +++ b/drivers/net/wireless/ath/ath9k/xmit.c
  38. @@ -163,6 +163,7 @@ static void ath_tx_flush_tid(struct ath_
  39. bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
  40. list_move_tail(&bf->list, &bf_head);
  41. + spin_unlock_bh(&txq->axq_lock);
  42. fi = get_frame_info(bf->bf_mpdu);
  43. if (fi->retries) {
  44. ath_tx_update_baw(sc, tid, fi->seqno);
  45. @@ -170,6 +171,7 @@ static void ath_tx_flush_tid(struct ath_
  46. } else {
  47. ath_tx_send_normal(sc, txq, tid, &bf_head);
  48. }
  49. + spin_lock_bh(&txq->axq_lock);
  50. }
  51. spin_unlock_bh(&txq->axq_lock);
  52. --- a/net/mac80211/ieee80211_i.h
  53. +++ b/net/mac80211/ieee80211_i.h
  54. @@ -349,6 +349,7 @@ struct ieee80211_if_managed {
  55. struct work_struct chswitch_work;
  56. struct work_struct beacon_connection_loss_work;
  57. + unsigned long beacon_timeout;
  58. unsigned long probe_timeout;
  59. int probe_send_count;
  60. @@ -1269,6 +1270,8 @@ void ieee80211_send_nullfunc(struct ieee
  61. int powersave);
  62. void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
  63. struct ieee80211_hdr *hdr);
  64. +void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
  65. + struct ieee80211_hdr *hdr);
  66. void ieee80211_beacon_connection_loss_work(struct work_struct *work);
  67. void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
  68. --- a/net/mac80211/mlme.c
  69. +++ b/net/mac80211/mlme.c
  70. @@ -28,13 +28,19 @@
  71. #include "rate.h"
  72. #include "led.h"
  73. +#define IEEE80211_MAX_NULLFUNC_TRIES 2
  74. #define IEEE80211_MAX_PROBE_TRIES 5
  75. /*
  76. - * beacon loss detection timeout
  77. - * XXX: should depend on beacon interval
  78. + * Beacon loss timeout is calculated as N frames times the
  79. + * advertised beacon interval. This may need to be somewhat
  80. + * higher than what hardware might detect to account for
  81. + * delays in the host processing frames. But since we also
  82. + * probe on beacon miss before declaring the connection lost
  83. + * default to what we want.
  84. */
  85. -#define IEEE80211_BEACON_LOSS_TIME (2 * HZ)
  86. +#define IEEE80211_BEACON_LOSS_COUNT 7
  87. +
  88. /*
  89. * Time the connection can be idle before we probe
  90. * it to see if we can still talk to the AP.
  91. @@ -121,7 +127,7 @@ void ieee80211_sta_reset_beacon_monitor(
  92. return;
  93. mod_timer(&sdata->u.mgd.bcn_mon_timer,
  94. - round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
  95. + round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
  96. }
  97. void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
  98. @@ -871,6 +877,9 @@ static void ieee80211_set_associated(str
  99. bss_info_changed |= ieee80211_handle_bss_capability(sdata,
  100. cbss->capability, bss->has_erp_value, bss->erp_value);
  101. + sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
  102. + IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
  103. +
  104. sdata->u.mgd.associated = cbss;
  105. memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
  106. @@ -1026,6 +1035,51 @@ void ieee80211_sta_rx_notify(struct ieee
  107. ieee80211_sta_reset_conn_monitor(sdata);
  108. }
  109. +static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
  110. +{
  111. + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  112. +
  113. + if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
  114. + IEEE80211_STA_CONNECTION_POLL)))
  115. + return;
  116. +
  117. + ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
  118. + IEEE80211_STA_BEACON_POLL);
  119. + mutex_lock(&sdata->local->iflist_mtx);
  120. + ieee80211_recalc_ps(sdata->local, -1);
  121. + mutex_unlock(&sdata->local->iflist_mtx);
  122. +
  123. + if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
  124. + return;
  125. +
  126. + /*
  127. + * We've received a probe response, but are not sure whether
  128. + * we have or will be receiving any beacons or data, so let's
  129. + * schedule the timers again, just in case.
  130. + */
  131. + ieee80211_sta_reset_beacon_monitor(sdata);
  132. +
  133. + mod_timer(&ifmgd->conn_mon_timer,
  134. + round_jiffies_up(jiffies +
  135. + IEEE80211_CONNECTION_IDLE_TIME));
  136. +}
  137. +
  138. +void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
  139. + struct ieee80211_hdr *hdr)
  140. +{
  141. + if (!ieee80211_is_data(hdr->frame_control) &&
  142. + !ieee80211_is_nullfunc(hdr->frame_control))
  143. + return;
  144. +
  145. + ieee80211_sta_reset_conn_monitor(sdata);
  146. +
  147. + if (ieee80211_is_nullfunc(hdr->frame_control) &&
  148. + sdata->u.mgd.probe_send_count > 0) {
  149. + sdata->u.mgd.probe_send_count = 0;
  150. + ieee80211_queue_work(&sdata->local->hw, &sdata->work);
  151. + }
  152. +}
  153. +
  154. static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
  155. {
  156. struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  157. @@ -1041,8 +1095,19 @@ static void ieee80211_mgd_probe_ap_send(
  158. if (ifmgd->probe_send_count >= unicast_limit)
  159. dst = NULL;
  160. - ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
  161. - ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
  162. + /*
  163. + * When the hardware reports an accurate Tx ACK status, it's
  164. + * better to send a nullfunc frame instead of a probe request,
  165. + * as it will kick us off the AP quickly if we aren't associated
  166. + * anymore. The timeout will be reset if the frame is ACKed by
  167. + * the AP.
  168. + */
  169. + if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
  170. + ieee80211_send_nullfunc(sdata->local, sdata, 0);
  171. + else {
  172. + ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
  173. + ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
  174. + }
  175. ifmgd->probe_send_count++;
  176. ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
  177. @@ -1509,29 +1574,8 @@ static void ieee80211_rx_mgmt_probe_resp
  178. ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
  179. if (ifmgd->associated &&
  180. - memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
  181. - ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
  182. - IEEE80211_STA_CONNECTION_POLL)) {
  183. - ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
  184. - IEEE80211_STA_BEACON_POLL);
  185. - mutex_lock(&sdata->local->iflist_mtx);
  186. - ieee80211_recalc_ps(sdata->local, -1);
  187. - mutex_unlock(&sdata->local->iflist_mtx);
  188. -
  189. - if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
  190. - return;
  191. -
  192. - /*
  193. - * We've received a probe response, but are not sure whether
  194. - * we have or will be receiving any beacons or data, so let's
  195. - * schedule the timers again, just in case.
  196. - */
  197. - ieee80211_sta_reset_beacon_monitor(sdata);
  198. -
  199. - mod_timer(&ifmgd->conn_mon_timer,
  200. - round_jiffies_up(jiffies +
  201. - IEEE80211_CONNECTION_IDLE_TIME));
  202. - }
  203. + memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
  204. + ieee80211_reset_ap_probe(sdata);
  205. }
  206. /*
  207. @@ -1881,12 +1925,23 @@ void ieee80211_sta_work(struct ieee80211
  208. IEEE80211_STA_CONNECTION_POLL) &&
  209. ifmgd->associated) {
  210. u8 bssid[ETH_ALEN];
  211. + int max_tries;
  212. +
  213. + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
  214. + max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
  215. + else
  216. + max_tries = IEEE80211_MAX_PROBE_TRIES;
  217. memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
  218. - if (time_is_after_jiffies(ifmgd->probe_timeout))
  219. +
  220. + /* ACK received for nullfunc probing frame */
  221. + if (!ifmgd->probe_send_count)
  222. + ieee80211_reset_ap_probe(sdata);
  223. +
  224. + else if (time_is_after_jiffies(ifmgd->probe_timeout))
  225. run_again(ifmgd, ifmgd->probe_timeout);
  226. - else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
  227. + else if (ifmgd->probe_send_count < max_tries) {
  228. #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
  229. wiphy_debug(local->hw.wiphy,
  230. "%s: No probe response from AP %pM"
  231. @@ -2012,6 +2067,8 @@ void ieee80211_sta_restart(struct ieee80
  232. add_timer(&ifmgd->timer);
  233. if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
  234. add_timer(&ifmgd->chswitch_timer);
  235. + ieee80211_sta_reset_beacon_monitor(sdata);
  236. + ieee80211_send_nullfunc(sdata->local, sdata, 0);
  237. }
  238. #endif
  239. --- a/net/mac80211/status.c
  240. +++ b/net/mac80211/status.c
  241. @@ -155,6 +155,10 @@ static void ieee80211_frame_acked(struct
  242. ieee80211_queue_work(&local->hw, &local->recalc_smps);
  243. }
  244. +
  245. + if ((sdata->vif.type == NL80211_IFTYPE_STATION) &&
  246. + (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
  247. + ieee80211_sta_tx_notify(sdata, (void *) skb->data);
  248. }
  249. void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)