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