mac80211: update to 2011-08-10
[openwrt.git] / package / mac80211 / patches / 300-pending_work.patch
1 --- a/drivers/net/wireless/b43/main.c
2 +++ b/drivers/net/wireless/b43/main.c
3 @@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struc
4  static int b43_wireless_core_init(struct b43_wldev *dev);
5  static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
6  static int b43_wireless_core_start(struct b43_wldev *dev);
7 +static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
8 +                                   struct ieee80211_vif *vif,
9 +                                   struct ieee80211_bss_conf *conf,
10 +                                   u32 changed);
11  
12  static int b43_ratelimit(struct b43_wl *wl)
13  {
14 @@ -3754,14 +3758,24 @@ static int b43_op_config(struct ieee8021
15         struct ieee80211_conf *conf = &hw->conf;
16         int antenna;
17         int err = 0;
18 +       bool reload_bss = false;
19  
20         mutex_lock(&wl->mutex);
21  
22 +       dev = wl->current_dev;
23 +
24         /* Switch the band (if necessary). This might change the active core. */
25         err = b43_switch_band(wl, conf->channel);
26         if (err)
27                 goto out_unlock_mutex;
28 -       dev = wl->current_dev;
29 +
30 +       /* Need to reload all settings if the core changed */
31 +       if (dev != wl->current_dev) {
32 +               dev = wl->current_dev;
33 +               changed = ~0;
34 +               reload_bss = true;
35 +       }
36 +
37         phy = &dev->phy;
38  
39         if (conf_is_ht(conf))
40 @@ -3822,6 +3836,9 @@ out_mac_enable:
41  out_unlock_mutex:
42         mutex_unlock(&wl->mutex);
43  
44 +       if (wl->vif && reload_bss)
45 +               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
46 +
47         return err;
48  }
49  
50 @@ -3910,7 +3927,8 @@ static void b43_op_bss_info_changed(stru
51         if (changed & BSS_CHANGED_BEACON_INT &&
52             (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
53              b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
54 -            b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
55 +            b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
56 +           conf->beacon_int)
57                 b43_set_beacon_int(dev, conf->beacon_int);
58  
59         if (changed & BSS_CHANGED_BASIC_RATES)
60 @@ -4691,6 +4709,9 @@ static int b43_op_add_interface(struct i
61   out_mutex_unlock:
62         mutex_unlock(&wl->mutex);
63  
64 +       if (err == 0)
65 +               b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
66 +
67         return err;
68  }
69  
70 @@ -4761,6 +4782,9 @@ static int b43_op_start(struct ieee80211
71   out_mutex_unlock:
72         mutex_unlock(&wl->mutex);
73  
74 +       /* reload configuration */
75 +       b43_op_config(hw, ~0);
76 +
77         return err;
78  }
79  
80 @@ -4917,10 +4941,18 @@ out:
81         if (err)
82                 wl->current_dev = NULL; /* Failed to init the dev. */
83         mutex_unlock(&wl->mutex);
84 -       if (err)
85 +
86 +       if (err) {
87                 b43err(wl, "Controller restart FAILED\n");
88 -       else
89 -               b43info(wl, "Controller restarted\n");
90 +               return;
91 +       }
92 +
93 +       /* reload configuration */
94 +       b43_op_config(wl->hw, ~0);
95 +       if (wl->vif)
96 +               b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
97 +
98 +       b43info(wl, "Controller restarted\n");
99  }
100  
101  static int b43_setup_bands(struct b43_wldev *dev,
102 --- a/net/mac80211/agg-rx.c
103 +++ b/net/mac80211/agg-rx.c
104 @@ -184,6 +184,8 @@ static void ieee80211_send_addba_resp(st
105                 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
106         else if (sdata->vif.type == NL80211_IFTYPE_STATION)
107                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
108 +       else if (sdata->vif.type == NL80211_IFTYPE_WDS)
109 +               memcpy(mgmt->bssid, da, ETH_ALEN);
110  
111         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
112                                           IEEE80211_STYPE_ACTION);
113 --- a/net/mac80211/agg-tx.c
114 +++ b/net/mac80211/agg-tx.c
115 @@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
116         memcpy(mgmt->da, da, ETH_ALEN);
117         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
118         if (sdata->vif.type == NL80211_IFTYPE_AP ||
119 -           sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
120 +           sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
121 +           sdata->vif.type == NL80211_IFTYPE_WDS)
122                 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
123         else if (sdata->vif.type == NL80211_IFTYPE_STATION)
124                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
125 @@ -398,7 +399,8 @@ int ieee80211_start_tx_ba_session(struct
126          */
127         if (sdata->vif.type != NL80211_IFTYPE_STATION &&
128             sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
129 -           sdata->vif.type != NL80211_IFTYPE_AP)
130 +           sdata->vif.type != NL80211_IFTYPE_AP &&
131 +           sdata->vif.type != NL80211_IFTYPE_WDS)
132                 return -EINVAL;
133  
134         if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
135 --- a/net/mac80211/debugfs_sta.c
136 +++ b/net/mac80211/debugfs_sta.c
137 @@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
138         char buf[100];
139         struct sta_info *sta = file->private_data;
140         u32 staflags = get_sta_flags(sta);
141 -       int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
142 +       int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
143                 staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
144                 staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
145                 staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
146 @@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
147                 staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
148                 staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
149                 staflags & WLAN_STA_WME ? "WME\n" : "",
150 -               staflags & WLAN_STA_WDS ? "WDS\n" : "",
151                 staflags & WLAN_STA_MFP ? "MFP\n" : "");
152         return simple_read_from_buffer(userbuf, count, ppos, buf, res);
153  }
154 --- a/net/mac80211/iface.c
155 +++ b/net/mac80211/iface.c
156 @@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
157  {
158         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
159         struct ieee80211_local *local = sdata->local;
160 -       struct sta_info *sta;
161         u32 changed = 0;
162         int res;
163         u32 hw_reconf_flags = 0;
164 @@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
165  
166         set_bit(SDATA_STATE_RUNNING, &sdata->state);
167  
168 -       if (sdata->vif.type == NL80211_IFTYPE_WDS) {
169 -               /* Create STA entry for the WDS peer */
170 -               sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
171 -                                    GFP_KERNEL);
172 -               if (!sta) {
173 -                       res = -ENOMEM;
174 -                       goto err_del_interface;
175 -               }
176 -
177 -               /* no locking required since STA is not live yet */
178 -               sta->flags |= WLAN_STA_AUTHORIZED;
179 -
180 -               res = sta_info_insert(sta);
181 -               if (res) {
182 -                       /* STA has been freed */
183 -                       goto err_del_interface;
184 -               }
185 -
186 -               rate_control_rate_init(sta);
187 -       }
188 -
189         /*
190          * set_multicast_list will be invoked by the networking core
191          * which will check whether any increments here were done in
192 @@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
193         netif_tx_start_all_queues(dev);
194  
195         return 0;
196 - err_del_interface:
197 -       drv_remove_interface(local, &sdata->vif);
198 +
199   err_stop:
200         if (!local->open_count)
201                 drv_stop(local);
202 @@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
203         dev->destructor = free_netdev;
204  }
205  
206 +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
207 +                                        struct sk_buff *skb)
208 +{
209 +       struct ieee80211_local *local = sdata->local;
210 +       struct ieee80211_rx_status *rx_status;
211 +       struct ieee802_11_elems elems;
212 +       struct ieee80211_mgmt *mgmt;
213 +       struct sta_info *sta;
214 +       size_t baselen;
215 +       u32 rates = 0;
216 +       u16 stype;
217 +       bool new = false;
218 +       enum ieee80211_band band = local->hw.conf.channel->band;
219 +       struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
220 +
221 +       rx_status = IEEE80211_SKB_RXCB(skb);
222 +       mgmt = (struct ieee80211_mgmt *) skb->data;
223 +       stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
224 +
225 +       if (stype != IEEE80211_STYPE_BEACON)
226 +               return;
227 +
228 +       baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
229 +       if (baselen > skb->len)
230 +               return;
231 +
232 +       ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
233 +                              skb->len - baselen, &elems);
234 +
235 +       rates = ieee80211_sta_get_rates(local, &elems, band);
236 +
237 +       rcu_read_lock();
238 +
239 +       sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
240 +
241 +       if (!sta) {
242 +               rcu_read_unlock();
243 +               sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
244 +                                    GFP_KERNEL);
245 +               if (!sta)
246 +                       return;
247 +
248 +               new = true;
249 +       }
250 +
251 +       sta->last_rx = jiffies;
252 +       sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
253 +
254 +       if (elems.ht_cap_elem)
255 +               ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
256 +                               elems.ht_cap_elem, &sta->sta.ht_cap);
257 +
258 +       if (elems.wmm_param)
259 +               set_sta_flags(sta, WLAN_STA_WME);
260 +
261 +       if (new) {
262 +               sta->flags = WLAN_STA_AUTHORIZED;
263 +               rate_control_rate_init(sta);
264 +               sta_info_insert_rcu(sta);
265 +       }
266 +
267 +       rcu_read_unlock();
268 +}
269 +
270  static void ieee80211_iface_work(struct work_struct *work)
271  {
272         struct ieee80211_sub_if_data *sdata =
273 @@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct 
274                                 break;
275                         ieee80211_mesh_rx_queued_mgmt(sdata, skb);
276                         break;
277 +               case NL80211_IFTYPE_WDS:
278 +                       ieee80211_wds_rx_queued_mgmt(sdata, skb);
279 +                       break;
280                 default:
281                         WARN(1, "frame for unexpected interface type");
282                         break;
283 --- a/net/mac80211/rx.c
284 +++ b/net/mac80211/rx.c
285 @@ -2147,7 +2147,8 @@ ieee80211_rx_h_action(struct ieee80211_r
286                  */
287                 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
288                     sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
289 -                   sdata->vif.type != NL80211_IFTYPE_AP)
290 +                   sdata->vif.type != NL80211_IFTYPE_AP &&
291 +                   sdata->vif.type != NL80211_IFTYPE_WDS)
292                         break;
293  
294                 /* verify action_code is present */
295 @@ -2345,13 +2346,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
296  
297         if (!ieee80211_vif_is_mesh(&sdata->vif) &&
298             sdata->vif.type != NL80211_IFTYPE_ADHOC &&
299 -           sdata->vif.type != NL80211_IFTYPE_STATION)
300 +           sdata->vif.type != NL80211_IFTYPE_STATION &&
301 +           sdata->vif.type != NL80211_IFTYPE_WDS)
302                 return RX_DROP_MONITOR;
303  
304         switch (stype) {
305         case cpu_to_le16(IEEE80211_STYPE_BEACON):
306         case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
307 -               /* process for all: mesh, mlme, ibss */
308 +               /* process for all: mesh, mlme, ibss, wds */
309                 break;
310         case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
311         case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
312 @@ -2692,10 +2694,16 @@ static int prepare_for_handlers(struct i
313                 }
314                 break;
315         case NL80211_IFTYPE_WDS:
316 -               if (bssid || !ieee80211_is_data(hdr->frame_control))
317 -                       return 0;
318                 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
319                         return 0;
320 +
321 +               if (ieee80211_is_data(hdr->frame_control) ||
322 +                   ieee80211_is_action(hdr->frame_control)) {
323 +                       if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
324 +                               return 0;
325 +               } else if (!ieee80211_is_beacon(hdr->frame_control))
326 +                       return 0;
327 +
328                 break;
329         default:
330                 /* should never get here */
331 --- a/net/mac80211/sta_info.h
332 +++ b/net/mac80211/sta_info.h
333 @@ -31,7 +31,6 @@
334   *     frames.
335   * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
336   * @WLAN_STA_WME: Station is a QoS-STA.
337 - * @WLAN_STA_WDS: Station is one of our WDS peers.
338   * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
339   *     IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
340   *     frame to this station is transmitted.
341 @@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
342         WLAN_STA_SHORT_PREAMBLE = 1<<4,
343         WLAN_STA_ASSOC_AP       = 1<<5,
344         WLAN_STA_WME            = 1<<6,
345 -       WLAN_STA_WDS            = 1<<7,
346         WLAN_STA_CLEAR_PS_FILT  = 1<<9,
347         WLAN_STA_MFP            = 1<<10,
348         WLAN_STA_BLOCK_BA       = 1<<11,
349 --- a/drivers/net/wireless/ath/ath9k/xmit.c
350 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
351 @@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct 
352                 if (clear_filter)
353                         tid->ac->clear_ps_filter = true;
354                 list_splice(&bf_pending, &tid->buf_q);
355 -               ath_tx_queue_tid(txq, tid);
356 +               if (!an->sleeping)
357 +                       ath_tx_queue_tid(txq, tid);
358                 spin_unlock_bh(&txq->axq_lock);
359         }
360  
361 @@ -1413,7 +1414,8 @@ static void ath_tx_send_ampdu(struct ath
362                  */
363                 TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
364                 list_add_tail(&bf->list, &tid->buf_q);
365 -               ath_tx_queue_tid(txctl->txq, tid);
366 +               if (!txctl->an || !txctl->an->sleeping)
367 +                       ath_tx_queue_tid(txctl->txq, tid);
368                 return;
369         }
370  
371 --- a/include/net/cfg80211.h
372 +++ b/include/net/cfg80211.h
373 @@ -421,6 +421,7 @@ struct station_parameters {
374   * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
375   * @STATION_INFO_BSS_PARAM: @bss_param filled
376   * @STATION_INFO_CONNECTED_TIME: @connected_time filled
377 + * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
378   */
379  enum station_info_flags {
380         STATION_INFO_INACTIVE_TIME      = 1<<0,
381 @@ -439,7 +440,8 @@ enum station_info_flags {
382         STATION_INFO_SIGNAL_AVG         = 1<<13,
383         STATION_INFO_RX_BITRATE         = 1<<14,
384         STATION_INFO_BSS_PARAM          = 1<<15,
385 -       STATION_INFO_CONNECTED_TIME     = 1<<16
386 +       STATION_INFO_CONNECTED_TIME     = 1<<16,
387 +       STATION_INFO_ASSOC_REQ_IES      = 1<<17
388  };
389  
390  /**
391 --- a/net/wireless/nl80211.c
392 +++ b/net/wireless/nl80211.c
393 @@ -2236,7 +2236,7 @@ static int nl80211_send_station(struct s
394         }
395         nla_nest_end(msg, sinfoattr);
396  
397 -       if (sinfo->assoc_req_ies)
398 +       if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
399                 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
400                         sinfo->assoc_req_ies);
401