diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 1003 |
1 files changed, 93 insertions, 910 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index aa5a191598c9..ae62ad40ad63 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -45,16 +45,9 @@ struct ieee80211_tx_status_rtap_hdr { | |||
45 | u8 data_retries; | 45 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 46 | } __attribute__ ((packed)); |
47 | 47 | ||
48 | /* common interface routines */ | ||
49 | |||
50 | static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) | ||
51 | { | ||
52 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
53 | return ETH_ALEN; | ||
54 | } | ||
55 | 48 | ||
56 | /* must be called under mdev tx lock */ | 49 | /* must be called under mdev tx lock */ |
57 | static void ieee80211_configure_filter(struct ieee80211_local *local) | 50 | void ieee80211_configure_filter(struct ieee80211_local *local) |
58 | { | 51 | { |
59 | unsigned int changed_flags; | 52 | unsigned int changed_flags; |
60 | unsigned int new_flags = 0; | 53 | unsigned int new_flags = 0; |
@@ -97,9 +90,24 @@ static void ieee80211_configure_filter(struct ieee80211_local *local) | |||
97 | 90 | ||
98 | /* master interface */ | 91 | /* master interface */ |
99 | 92 | ||
93 | static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) | ||
94 | { | ||
95 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
96 | return ETH_ALEN; | ||
97 | } | ||
98 | |||
99 | static const struct header_ops ieee80211_header_ops = { | ||
100 | .create = eth_header, | ||
101 | .parse = header_parse_80211, | ||
102 | .rebuild = eth_rebuild_header, | ||
103 | .cache = eth_header_cache, | ||
104 | .cache_update = eth_header_cache_update, | ||
105 | }; | ||
106 | |||
100 | static int ieee80211_master_open(struct net_device *dev) | 107 | static int ieee80211_master_open(struct net_device *dev) |
101 | { | 108 | { |
102 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 109 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); |
110 | struct ieee80211_local *local = mpriv->local; | ||
103 | struct ieee80211_sub_if_data *sdata; | 111 | struct ieee80211_sub_if_data *sdata; |
104 | int res = -EOPNOTSUPP; | 112 | int res = -EOPNOTSUPP; |
105 | 113 | ||
@@ -121,7 +129,8 @@ static int ieee80211_master_open(struct net_device *dev) | |||
121 | 129 | ||
122 | static int ieee80211_master_stop(struct net_device *dev) | 130 | static int ieee80211_master_stop(struct net_device *dev) |
123 | { | 131 | { |
124 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 132 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); |
133 | struct ieee80211_local *local = mpriv->local; | ||
125 | struct ieee80211_sub_if_data *sdata; | 134 | struct ieee80211_sub_if_data *sdata; |
126 | 135 | ||
127 | /* we hold the RTNL here so can safely walk the list */ | 136 | /* we hold the RTNL here so can safely walk the list */ |
@@ -134,849 +143,12 @@ static int ieee80211_master_stop(struct net_device *dev) | |||
134 | 143 | ||
135 | static void ieee80211_master_set_multicast_list(struct net_device *dev) | 144 | static void ieee80211_master_set_multicast_list(struct net_device *dev) |
136 | { | 145 | { |
137 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 146 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); |
147 | struct ieee80211_local *local = mpriv->local; | ||
138 | 148 | ||
139 | ieee80211_configure_filter(local); | 149 | ieee80211_configure_filter(local); |
140 | } | 150 | } |
141 | 151 | ||
142 | /* regular interfaces */ | ||
143 | |||
144 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | ||
145 | { | ||
146 | int meshhdrlen; | ||
147 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
148 | |||
149 | meshhdrlen = (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) ? 5 : 0; | ||
150 | |||
151 | /* FIX: what would be proper limits for MTU? | ||
152 | * This interface uses 802.3 frames. */ | ||
153 | if (new_mtu < 256 || | ||
154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
159 | printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); | ||
160 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
161 | dev->mtu = new_mtu; | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static inline int identical_mac_addr_allowed(int type1, int type2) | ||
166 | { | ||
167 | return (type1 == IEEE80211_IF_TYPE_MNTR || | ||
168 | type2 == IEEE80211_IF_TYPE_MNTR || | ||
169 | (type1 == IEEE80211_IF_TYPE_AP && | ||
170 | type2 == IEEE80211_IF_TYPE_WDS) || | ||
171 | (type1 == IEEE80211_IF_TYPE_WDS && | ||
172 | (type2 == IEEE80211_IF_TYPE_WDS || | ||
173 | type2 == IEEE80211_IF_TYPE_AP)) || | ||
174 | (type1 == IEEE80211_IF_TYPE_AP && | ||
175 | type2 == IEEE80211_IF_TYPE_VLAN) || | ||
176 | (type1 == IEEE80211_IF_TYPE_VLAN && | ||
177 | (type2 == IEEE80211_IF_TYPE_AP || | ||
178 | type2 == IEEE80211_IF_TYPE_VLAN))); | ||
179 | } | ||
180 | |||
181 | static int ieee80211_open(struct net_device *dev) | ||
182 | { | ||
183 | struct ieee80211_sub_if_data *sdata, *nsdata; | ||
184 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
185 | struct sta_info *sta; | ||
186 | struct ieee80211_if_init_conf conf; | ||
187 | u32 changed = 0; | ||
188 | int res; | ||
189 | bool need_hw_reconfig = 0; | ||
190 | |||
191 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
192 | |||
193 | /* we hold the RTNL here so can safely walk the list */ | ||
194 | list_for_each_entry(nsdata, &local->interfaces, list) { | ||
195 | struct net_device *ndev = nsdata->dev; | ||
196 | |||
197 | if (ndev != dev && netif_running(ndev)) { | ||
198 | /* | ||
199 | * Allow only a single IBSS interface to be up at any | ||
200 | * time. This is restricted because beacon distribution | ||
201 | * cannot work properly if both are in the same IBSS. | ||
202 | * | ||
203 | * To remove this restriction we'd have to disallow them | ||
204 | * from setting the same SSID on different IBSS interfaces | ||
205 | * belonging to the same hardware. Then, however, we're | ||
206 | * faced with having to adopt two different TSF timers... | ||
207 | */ | ||
208 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | ||
209 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS) | ||
210 | return -EBUSY; | ||
211 | |||
212 | /* | ||
213 | * The remaining checks are only performed for interfaces | ||
214 | * with the same MAC address. | ||
215 | */ | ||
216 | if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) | ||
217 | continue; | ||
218 | |||
219 | /* | ||
220 | * check whether it may have the same address | ||
221 | */ | ||
222 | if (!identical_mac_addr_allowed(sdata->vif.type, | ||
223 | nsdata->vif.type)) | ||
224 | return -ENOTUNIQ; | ||
225 | |||
226 | /* | ||
227 | * can only add VLANs to enabled APs | ||
228 | */ | ||
229 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | ||
230 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) | ||
231 | sdata->bss = &nsdata->u.ap; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | switch (sdata->vif.type) { | ||
236 | case IEEE80211_IF_TYPE_WDS: | ||
237 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) | ||
238 | return -ENOLINK; | ||
239 | break; | ||
240 | case IEEE80211_IF_TYPE_VLAN: | ||
241 | if (!sdata->bss) | ||
242 | return -ENOLINK; | ||
243 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | ||
244 | break; | ||
245 | case IEEE80211_IF_TYPE_AP: | ||
246 | sdata->bss = &sdata->u.ap; | ||
247 | break; | ||
248 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
249 | /* mesh ifaces must set allmulti to forward mcast traffic */ | ||
250 | atomic_inc(&local->iff_allmultis); | ||
251 | break; | ||
252 | case IEEE80211_IF_TYPE_STA: | ||
253 | case IEEE80211_IF_TYPE_MNTR: | ||
254 | case IEEE80211_IF_TYPE_IBSS: | ||
255 | /* no special treatment */ | ||
256 | break; | ||
257 | case IEEE80211_IF_TYPE_INVALID: | ||
258 | /* cannot happen */ | ||
259 | WARN_ON(1); | ||
260 | break; | ||
261 | } | ||
262 | |||
263 | if (local->open_count == 0) { | ||
264 | res = 0; | ||
265 | if (local->ops->start) | ||
266 | res = local->ops->start(local_to_hw(local)); | ||
267 | if (res) | ||
268 | goto err_del_bss; | ||
269 | need_hw_reconfig = 1; | ||
270 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | ||
271 | } | ||
272 | |||
273 | switch (sdata->vif.type) { | ||
274 | case IEEE80211_IF_TYPE_VLAN: | ||
275 | /* no need to tell driver */ | ||
276 | break; | ||
277 | case IEEE80211_IF_TYPE_MNTR: | ||
278 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
279 | local->cooked_mntrs++; | ||
280 | break; | ||
281 | } | ||
282 | |||
283 | /* must be before the call to ieee80211_configure_filter */ | ||
284 | local->monitors++; | ||
285 | if (local->monitors == 1) | ||
286 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | ||
287 | |||
288 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
289 | local->fif_fcsfail++; | ||
290 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
291 | local->fif_plcpfail++; | ||
292 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
293 | local->fif_control++; | ||
294 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
295 | local->fif_other_bss++; | ||
296 | |||
297 | netif_addr_lock_bh(local->mdev); | ||
298 | ieee80211_configure_filter(local); | ||
299 | netif_addr_unlock_bh(local->mdev); | ||
300 | break; | ||
301 | case IEEE80211_IF_TYPE_STA: | ||
302 | case IEEE80211_IF_TYPE_IBSS: | ||
303 | sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
304 | /* fall through */ | ||
305 | default: | ||
306 | conf.vif = &sdata->vif; | ||
307 | conf.type = sdata->vif.type; | ||
308 | conf.mac_addr = dev->dev_addr; | ||
309 | res = local->ops->add_interface(local_to_hw(local), &conf); | ||
310 | if (res) | ||
311 | goto err_stop; | ||
312 | |||
313 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
314 | ieee80211_start_mesh(sdata->dev); | ||
315 | changed |= ieee80211_reset_erp_info(dev); | ||
316 | ieee80211_bss_info_change_notify(sdata, changed); | ||
317 | ieee80211_enable_keys(sdata); | ||
318 | |||
319 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | ||
320 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) | ||
321 | netif_carrier_off(dev); | ||
322 | else | ||
323 | netif_carrier_on(dev); | ||
324 | } | ||
325 | |||
326 | if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { | ||
327 | /* Create STA entry for the WDS peer */ | ||
328 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | ||
329 | GFP_KERNEL); | ||
330 | if (!sta) { | ||
331 | res = -ENOMEM; | ||
332 | goto err_del_interface; | ||
333 | } | ||
334 | |||
335 | /* no locking required since STA is not live yet */ | ||
336 | sta->flags |= WLAN_STA_AUTHORIZED; | ||
337 | |||
338 | res = sta_info_insert(sta); | ||
339 | if (res) { | ||
340 | /* STA has been freed */ | ||
341 | goto err_del_interface; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | if (local->open_count == 0) { | ||
346 | res = dev_open(local->mdev); | ||
347 | WARN_ON(res); | ||
348 | if (res) | ||
349 | goto err_del_interface; | ||
350 | tasklet_enable(&local->tx_pending_tasklet); | ||
351 | tasklet_enable(&local->tasklet); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * set_multicast_list will be invoked by the networking core | ||
356 | * which will check whether any increments here were done in | ||
357 | * error and sync them down to the hardware as filter flags. | ||
358 | */ | ||
359 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | ||
360 | atomic_inc(&local->iff_allmultis); | ||
361 | |||
362 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
363 | atomic_inc(&local->iff_promiscs); | ||
364 | |||
365 | local->open_count++; | ||
366 | if (need_hw_reconfig) | ||
367 | ieee80211_hw_config(local); | ||
368 | |||
369 | /* | ||
370 | * ieee80211_sta_work is disabled while network interface | ||
371 | * is down. Therefore, some configuration changes may not | ||
372 | * yet be effective. Trigger execution of ieee80211_sta_work | ||
373 | * to fix this. | ||
374 | */ | ||
375 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
376 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | ||
377 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
378 | queue_work(local->hw.workqueue, &ifsta->work); | ||
379 | } | ||
380 | |||
381 | netif_tx_start_all_queues(dev); | ||
382 | |||
383 | return 0; | ||
384 | err_del_interface: | ||
385 | local->ops->remove_interface(local_to_hw(local), &conf); | ||
386 | err_stop: | ||
387 | if (!local->open_count && local->ops->stop) | ||
388 | local->ops->stop(local_to_hw(local)); | ||
389 | err_del_bss: | ||
390 | sdata->bss = NULL; | ||
391 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | ||
392 | list_del(&sdata->u.vlan.list); | ||
393 | return res; | ||
394 | } | ||
395 | |||
396 | static int ieee80211_stop(struct net_device *dev) | ||
397 | { | ||
398 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
399 | struct ieee80211_local *local = sdata->local; | ||
400 | struct ieee80211_if_init_conf conf; | ||
401 | struct sta_info *sta; | ||
402 | |||
403 | /* | ||
404 | * Stop TX on this interface first. | ||
405 | */ | ||
406 | netif_tx_stop_all_queues(dev); | ||
407 | |||
408 | /* | ||
409 | * Now delete all active aggregation sessions. | ||
410 | */ | ||
411 | rcu_read_lock(); | ||
412 | |||
413 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||
414 | if (sta->sdata == sdata) | ||
415 | ieee80211_sta_tear_down_BA_sessions(dev, sta->addr); | ||
416 | } | ||
417 | |||
418 | rcu_read_unlock(); | ||
419 | |||
420 | /* | ||
421 | * Remove all stations associated with this interface. | ||
422 | * | ||
423 | * This must be done before calling ops->remove_interface() | ||
424 | * because otherwise we can later invoke ops->sta_notify() | ||
425 | * whenever the STAs are removed, and that invalidates driver | ||
426 | * assumptions about always getting a vif pointer that is valid | ||
427 | * (because if we remove a STA after ops->remove_interface() | ||
428 | * the driver will have removed the vif info already!) | ||
429 | * | ||
430 | * We could relax this and only unlink the stations from the | ||
431 | * hash table and list but keep them on a per-sdata list that | ||
432 | * will be inserted back again when the interface is brought | ||
433 | * up again, but I don't currently see a use case for that, | ||
434 | * except with WDS which gets a STA entry created when it is | ||
435 | * brought up. | ||
436 | */ | ||
437 | sta_info_flush(local, sdata); | ||
438 | |||
439 | /* | ||
440 | * Don't count this interface for promisc/allmulti while it | ||
441 | * is down. dev_mc_unsync() will invoke set_multicast_list | ||
442 | * on the master interface which will sync these down to the | ||
443 | * hardware as filter flags. | ||
444 | */ | ||
445 | if (sdata->flags & IEEE80211_SDATA_ALLMULTI) | ||
446 | atomic_dec(&local->iff_allmultis); | ||
447 | |||
448 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | ||
449 | atomic_dec(&local->iff_promiscs); | ||
450 | |||
451 | dev_mc_unsync(local->mdev, dev); | ||
452 | |||
453 | /* APs need special treatment */ | ||
454 | if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | ||
455 | struct ieee80211_sub_if_data *vlan, *tmp; | ||
456 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | ||
457 | |||
458 | /* remove beacon */ | ||
459 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
460 | synchronize_rcu(); | ||
461 | kfree(old_beacon); | ||
462 | |||
463 | /* down all dependent devices, that is VLANs */ | ||
464 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, | ||
465 | u.vlan.list) | ||
466 | dev_close(vlan->dev); | ||
467 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | ||
468 | } | ||
469 | |||
470 | local->open_count--; | ||
471 | |||
472 | switch (sdata->vif.type) { | ||
473 | case IEEE80211_IF_TYPE_VLAN: | ||
474 | list_del(&sdata->u.vlan.list); | ||
475 | /* no need to tell driver */ | ||
476 | break; | ||
477 | case IEEE80211_IF_TYPE_MNTR: | ||
478 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
479 | local->cooked_mntrs--; | ||
480 | break; | ||
481 | } | ||
482 | |||
483 | local->monitors--; | ||
484 | if (local->monitors == 0) | ||
485 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | ||
486 | |||
487 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
488 | local->fif_fcsfail--; | ||
489 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
490 | local->fif_plcpfail--; | ||
491 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
492 | local->fif_control--; | ||
493 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
494 | local->fif_other_bss--; | ||
495 | |||
496 | netif_addr_lock_bh(local->mdev); | ||
497 | ieee80211_configure_filter(local); | ||
498 | netif_addr_unlock_bh(local->mdev); | ||
499 | break; | ||
500 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
501 | /* allmulti is always set on mesh ifaces */ | ||
502 | atomic_dec(&local->iff_allmultis); | ||
503 | /* fall through */ | ||
504 | case IEEE80211_IF_TYPE_STA: | ||
505 | case IEEE80211_IF_TYPE_IBSS: | ||
506 | sdata->u.sta.state = IEEE80211_DISABLED; | ||
507 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); | ||
508 | del_timer_sync(&sdata->u.sta.timer); | ||
509 | /* | ||
510 | * When we get here, the interface is marked down. | ||
511 | * Call synchronize_rcu() to wait for the RX path | ||
512 | * should it be using the interface and enqueuing | ||
513 | * frames at this very time on another CPU. | ||
514 | */ | ||
515 | synchronize_rcu(); | ||
516 | skb_queue_purge(&sdata->u.sta.skb_queue); | ||
517 | |||
518 | if (local->scan_dev == sdata->dev) { | ||
519 | if (!local->ops->hw_scan) { | ||
520 | local->sta_sw_scanning = 0; | ||
521 | cancel_delayed_work(&local->scan_work); | ||
522 | } else | ||
523 | local->sta_hw_scanning = 0; | ||
524 | } | ||
525 | |||
526 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | ||
527 | kfree(sdata->u.sta.extra_ie); | ||
528 | sdata->u.sta.extra_ie = NULL; | ||
529 | sdata->u.sta.extra_ie_len = 0; | ||
530 | /* fall through */ | ||
531 | default: | ||
532 | conf.vif = &sdata->vif; | ||
533 | conf.type = sdata->vif.type; | ||
534 | conf.mac_addr = dev->dev_addr; | ||
535 | /* disable all keys for as long as this netdev is down */ | ||
536 | ieee80211_disable_keys(sdata); | ||
537 | local->ops->remove_interface(local_to_hw(local), &conf); | ||
538 | } | ||
539 | |||
540 | sdata->bss = NULL; | ||
541 | |||
542 | if (local->open_count == 0) { | ||
543 | if (netif_running(local->mdev)) | ||
544 | dev_close(local->mdev); | ||
545 | |||
546 | if (local->ops->stop) | ||
547 | local->ops->stop(local_to_hw(local)); | ||
548 | |||
549 | ieee80211_led_radio(local, 0); | ||
550 | |||
551 | flush_workqueue(local->hw.workqueue); | ||
552 | |||
553 | tasklet_disable(&local->tx_pending_tasklet); | ||
554 | tasklet_disable(&local->tasklet); | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
561 | { | ||
562 | struct ieee80211_local *local = hw_to_local(hw); | ||
563 | struct sta_info *sta; | ||
564 | struct ieee80211_sub_if_data *sdata; | ||
565 | u16 start_seq_num = 0; | ||
566 | u8 *state; | ||
567 | int ret; | ||
568 | DECLARE_MAC_BUF(mac); | ||
569 | |||
570 | if (tid >= STA_TID_NUM) | ||
571 | return -EINVAL; | ||
572 | |||
573 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
574 | printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", | ||
575 | print_mac(mac, ra), tid); | ||
576 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
577 | |||
578 | rcu_read_lock(); | ||
579 | |||
580 | sta = sta_info_get(local, ra); | ||
581 | if (!sta) { | ||
582 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
583 | printk(KERN_DEBUG "Could not find the station\n"); | ||
584 | #endif | ||
585 | ret = -ENOENT; | ||
586 | goto exit; | ||
587 | } | ||
588 | |||
589 | spin_lock_bh(&sta->lock); | ||
590 | |||
591 | /* we have tried too many times, receiver does not want A-MPDU */ | ||
592 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | ||
593 | ret = -EBUSY; | ||
594 | goto err_unlock_sta; | ||
595 | } | ||
596 | |||
597 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
598 | /* check if the TID is not in aggregation flow already */ | ||
599 | if (*state != HT_AGG_STATE_IDLE) { | ||
600 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
601 | printk(KERN_DEBUG "BA request denied - session is not " | ||
602 | "idle on tid %u\n", tid); | ||
603 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
604 | ret = -EAGAIN; | ||
605 | goto err_unlock_sta; | ||
606 | } | ||
607 | |||
608 | /* prepare A-MPDU MLME for Tx aggregation */ | ||
609 | sta->ampdu_mlme.tid_tx[tid] = | ||
610 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | ||
611 | if (!sta->ampdu_mlme.tid_tx[tid]) { | ||
612 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
613 | if (net_ratelimit()) | ||
614 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | ||
615 | tid); | ||
616 | #endif | ||
617 | ret = -ENOMEM; | ||
618 | goto err_unlock_sta; | ||
619 | } | ||
620 | /* Tx timer */ | ||
621 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | ||
622 | sta_addba_resp_timer_expired; | ||
623 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data = | ||
624 | (unsigned long)&sta->timer_to_tid[tid]; | ||
625 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
626 | |||
627 | /* create a new queue for this aggregation */ | ||
628 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | ||
629 | |||
630 | /* case no queue is available to aggregation | ||
631 | * don't switch to aggregation */ | ||
632 | if (ret) { | ||
633 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
634 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | ||
635 | " tid %d\n", tid); | ||
636 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
637 | goto err_unlock_queue; | ||
638 | } | ||
639 | sdata = sta->sdata; | ||
640 | |||
641 | /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the | ||
642 | * call back right away, it must see that the flow has begun */ | ||
643 | *state |= HT_ADDBA_REQUESTED_MSK; | ||
644 | |||
645 | if (local->ops->ampdu_action) | ||
646 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, | ||
647 | ra, tid, &start_seq_num); | ||
648 | |||
649 | if (ret) { | ||
650 | /* No need to requeue the packets in the agg queue, since we | ||
651 | * held the tx lock: no packet could be enqueued to the newly | ||
652 | * allocated queue */ | ||
653 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | ||
654 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
655 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | ||
656 | " tid %d\n", tid); | ||
657 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
658 | *state = HT_AGG_STATE_IDLE; | ||
659 | goto err_unlock_queue; | ||
660 | } | ||
661 | |||
662 | /* Will put all the packets in the new SW queue */ | ||
663 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | ||
664 | spin_unlock_bh(&sta->lock); | ||
665 | |||
666 | /* send an addBA request */ | ||
667 | sta->ampdu_mlme.dialog_token_allocator++; | ||
668 | sta->ampdu_mlme.tid_tx[tid]->dialog_token = | ||
669 | sta->ampdu_mlme.dialog_token_allocator; | ||
670 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | ||
671 | |||
672 | |||
673 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | ||
674 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | ||
675 | sta->ampdu_mlme.tid_tx[tid]->ssn, | ||
676 | 0x40, 5000); | ||
677 | /* activate the timer for the recipient's addBA response */ | ||
678 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | ||
679 | jiffies + ADDBA_RESP_INTERVAL; | ||
680 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
681 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
682 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | ||
683 | #endif | ||
684 | goto exit; | ||
685 | |||
686 | err_unlock_queue: | ||
687 | kfree(sta->ampdu_mlme.tid_tx[tid]); | ||
688 | sta->ampdu_mlme.tid_tx[tid] = NULL; | ||
689 | ret = -EBUSY; | ||
690 | err_unlock_sta: | ||
691 | spin_unlock_bh(&sta->lock); | ||
692 | exit: | ||
693 | rcu_read_unlock(); | ||
694 | return ret; | ||
695 | } | ||
696 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | ||
697 | |||
698 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | ||
699 | u8 *ra, u16 tid, | ||
700 | enum ieee80211_back_parties initiator) | ||
701 | { | ||
702 | struct ieee80211_local *local = hw_to_local(hw); | ||
703 | struct sta_info *sta; | ||
704 | u8 *state; | ||
705 | int ret = 0; | ||
706 | DECLARE_MAC_BUF(mac); | ||
707 | |||
708 | if (tid >= STA_TID_NUM) | ||
709 | return -EINVAL; | ||
710 | |||
711 | rcu_read_lock(); | ||
712 | sta = sta_info_get(local, ra); | ||
713 | if (!sta) { | ||
714 | rcu_read_unlock(); | ||
715 | return -ENOENT; | ||
716 | } | ||
717 | |||
718 | /* check if the TID is in aggregation */ | ||
719 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
720 | spin_lock_bh(&sta->lock); | ||
721 | |||
722 | if (*state != HT_AGG_STATE_OPERATIONAL) { | ||
723 | ret = -ENOENT; | ||
724 | goto stop_BA_exit; | ||
725 | } | ||
726 | |||
727 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
728 | printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n", | ||
729 | print_mac(mac, ra), tid); | ||
730 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
731 | |||
732 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | ||
733 | |||
734 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | ||
735 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | ||
736 | |||
737 | if (local->ops->ampdu_action) | ||
738 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP, | ||
739 | ra, tid, NULL); | ||
740 | |||
741 | /* case HW denied going back to legacy */ | ||
742 | if (ret) { | ||
743 | WARN_ON(ret != -EBUSY); | ||
744 | *state = HT_AGG_STATE_OPERATIONAL; | ||
745 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
746 | goto stop_BA_exit; | ||
747 | } | ||
748 | |||
749 | stop_BA_exit: | ||
750 | spin_unlock_bh(&sta->lock); | ||
751 | rcu_read_unlock(); | ||
752 | return ret; | ||
753 | } | ||
754 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | ||
755 | |||
756 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
757 | { | ||
758 | struct ieee80211_local *local = hw_to_local(hw); | ||
759 | struct sta_info *sta; | ||
760 | u8 *state; | ||
761 | DECLARE_MAC_BUF(mac); | ||
762 | |||
763 | if (tid >= STA_TID_NUM) { | ||
764 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
765 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
766 | tid, STA_TID_NUM); | ||
767 | #endif | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | rcu_read_lock(); | ||
772 | sta = sta_info_get(local, ra); | ||
773 | if (!sta) { | ||
774 | rcu_read_unlock(); | ||
775 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
776 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
777 | print_mac(mac, ra)); | ||
778 | #endif | ||
779 | return; | ||
780 | } | ||
781 | |||
782 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
783 | spin_lock_bh(&sta->lock); | ||
784 | |||
785 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | ||
786 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
787 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | ||
788 | *state); | ||
789 | #endif | ||
790 | spin_unlock_bh(&sta->lock); | ||
791 | rcu_read_unlock(); | ||
792 | return; | ||
793 | } | ||
794 | |||
795 | WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK); | ||
796 | |||
797 | *state |= HT_ADDBA_DRV_READY_MSK; | ||
798 | |||
799 | if (*state == HT_AGG_STATE_OPERATIONAL) { | ||
800 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
801 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | ||
802 | #endif | ||
803 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
804 | } | ||
805 | spin_unlock_bh(&sta->lock); | ||
806 | rcu_read_unlock(); | ||
807 | } | ||
808 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | ||
809 | |||
810 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | ||
811 | { | ||
812 | struct ieee80211_local *local = hw_to_local(hw); | ||
813 | struct sta_info *sta; | ||
814 | u8 *state; | ||
815 | int agg_queue; | ||
816 | DECLARE_MAC_BUF(mac); | ||
817 | |||
818 | if (tid >= STA_TID_NUM) { | ||
819 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
820 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
821 | tid, STA_TID_NUM); | ||
822 | #endif | ||
823 | return; | ||
824 | } | ||
825 | |||
826 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
827 | printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n", | ||
828 | print_mac(mac, ra), tid); | ||
829 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
830 | |||
831 | rcu_read_lock(); | ||
832 | sta = sta_info_get(local, ra); | ||
833 | if (!sta) { | ||
834 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
835 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
836 | print_mac(mac, ra)); | ||
837 | #endif | ||
838 | rcu_read_unlock(); | ||
839 | return; | ||
840 | } | ||
841 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
842 | |||
843 | /* NOTE: no need to use sta->lock in this state check, as | ||
844 | * ieee80211_stop_tx_ba_session will let only one stop call to | ||
845 | * pass through per sta/tid | ||
846 | */ | ||
847 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | ||
848 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
849 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | ||
850 | #endif | ||
851 | rcu_read_unlock(); | ||
852 | return; | ||
853 | } | ||
854 | |||
855 | if (*state & HT_AGG_STATE_INITIATOR_MSK) | ||
856 | ieee80211_send_delba(sta->sdata->dev, ra, tid, | ||
857 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | ||
858 | |||
859 | agg_queue = sta->tid_to_tx_q[tid]; | ||
860 | |||
861 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | ||
862 | |||
863 | /* We just requeued the all the frames that were in the | ||
864 | * removed queue, and since we might miss a softirq we do | ||
865 | * netif_schedule_queue. ieee80211_wake_queue is not used | ||
866 | * here as this queue is not necessarily stopped | ||
867 | */ | ||
868 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | ||
869 | spin_lock_bh(&sta->lock); | ||
870 | *state = HT_AGG_STATE_IDLE; | ||
871 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
872 | kfree(sta->ampdu_mlme.tid_tx[tid]); | ||
873 | sta->ampdu_mlme.tid_tx[tid] = NULL; | ||
874 | spin_unlock_bh(&sta->lock); | ||
875 | |||
876 | rcu_read_unlock(); | ||
877 | } | ||
878 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | ||
879 | |||
880 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
881 | const u8 *ra, u16 tid) | ||
882 | { | ||
883 | struct ieee80211_local *local = hw_to_local(hw); | ||
884 | struct ieee80211_ra_tid *ra_tid; | ||
885 | struct sk_buff *skb = dev_alloc_skb(0); | ||
886 | |||
887 | if (unlikely(!skb)) { | ||
888 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
889 | if (net_ratelimit()) | ||
890 | printk(KERN_WARNING "%s: Not enough memory, " | ||
891 | "dropping start BA session", skb->dev->name); | ||
892 | #endif | ||
893 | return; | ||
894 | } | ||
895 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
896 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
897 | ra_tid->tid = tid; | ||
898 | |||
899 | skb->pkt_type = IEEE80211_ADDBA_MSG; | ||
900 | skb_queue_tail(&local->skb_queue, skb); | ||
901 | tasklet_schedule(&local->tasklet); | ||
902 | } | ||
903 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | ||
904 | |||
905 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
906 | const u8 *ra, u16 tid) | ||
907 | { | ||
908 | struct ieee80211_local *local = hw_to_local(hw); | ||
909 | struct ieee80211_ra_tid *ra_tid; | ||
910 | struct sk_buff *skb = dev_alloc_skb(0); | ||
911 | |||
912 | if (unlikely(!skb)) { | ||
913 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
914 | if (net_ratelimit()) | ||
915 | printk(KERN_WARNING "%s: Not enough memory, " | ||
916 | "dropping stop BA session", skb->dev->name); | ||
917 | #endif | ||
918 | return; | ||
919 | } | ||
920 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
921 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
922 | ra_tid->tid = tid; | ||
923 | |||
924 | skb->pkt_type = IEEE80211_DELBA_MSG; | ||
925 | skb_queue_tail(&local->skb_queue, skb); | ||
926 | tasklet_schedule(&local->tasklet); | ||
927 | } | ||
928 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); | ||
929 | |||
930 | static void ieee80211_set_multicast_list(struct net_device *dev) | ||
931 | { | ||
932 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
933 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
934 | int allmulti, promisc, sdata_allmulti, sdata_promisc; | ||
935 | |||
936 | allmulti = !!(dev->flags & IFF_ALLMULTI); | ||
937 | promisc = !!(dev->flags & IFF_PROMISC); | ||
938 | sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); | ||
939 | sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC); | ||
940 | |||
941 | if (allmulti != sdata_allmulti) { | ||
942 | if (dev->flags & IFF_ALLMULTI) | ||
943 | atomic_inc(&local->iff_allmultis); | ||
944 | else | ||
945 | atomic_dec(&local->iff_allmultis); | ||
946 | sdata->flags ^= IEEE80211_SDATA_ALLMULTI; | ||
947 | } | ||
948 | |||
949 | if (promisc != sdata_promisc) { | ||
950 | if (dev->flags & IFF_PROMISC) | ||
951 | atomic_inc(&local->iff_promiscs); | ||
952 | else | ||
953 | atomic_dec(&local->iff_promiscs); | ||
954 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | ||
955 | } | ||
956 | |||
957 | dev_mc_sync(local->mdev, dev); | ||
958 | } | ||
959 | |||
960 | static const struct header_ops ieee80211_header_ops = { | ||
961 | .create = eth_header, | ||
962 | .parse = header_parse_80211, | ||
963 | .rebuild = eth_rebuild_header, | ||
964 | .cache = eth_header_cache, | ||
965 | .cache_update = eth_header_cache_update, | ||
966 | }; | ||
967 | |||
968 | void ieee80211_if_setup(struct net_device *dev) | ||
969 | { | ||
970 | ether_setup(dev); | ||
971 | dev->hard_start_xmit = ieee80211_subif_start_xmit; | ||
972 | dev->wireless_handlers = &ieee80211_iw_handler_def; | ||
973 | dev->set_multicast_list = ieee80211_set_multicast_list; | ||
974 | dev->change_mtu = ieee80211_change_mtu; | ||
975 | dev->open = ieee80211_open; | ||
976 | dev->stop = ieee80211_stop; | ||
977 | dev->destructor = free_netdev; | ||
978 | } | ||
979 | |||
980 | /* everything else */ | 152 | /* everything else */ |
981 | 153 | ||
982 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | 154 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) |
@@ -987,18 +159,21 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
987 | if (WARN_ON(!netif_running(sdata->dev))) | 159 | if (WARN_ON(!netif_running(sdata->dev))) |
988 | return 0; | 160 | return 0; |
989 | 161 | ||
162 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
163 | return -EINVAL; | ||
164 | |||
990 | if (!local->ops->config_interface) | 165 | if (!local->ops->config_interface) |
991 | return 0; | 166 | return 0; |
992 | 167 | ||
993 | memset(&conf, 0, sizeof(conf)); | 168 | memset(&conf, 0, sizeof(conf)); |
994 | conf.changed = changed; | 169 | conf.changed = changed; |
995 | 170 | ||
996 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | 171 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
997 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 172 | sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
998 | conf.bssid = sdata->u.sta.bssid; | 173 | conf.bssid = sdata->u.sta.bssid; |
999 | conf.ssid = sdata->u.sta.ssid; | 174 | conf.ssid = sdata->u.sta.ssid; |
1000 | conf.ssid_len = sdata->u.sta.ssid_len; | 175 | conf.ssid_len = sdata->u.sta.ssid_len; |
1001 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 176 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { |
1002 | conf.bssid = sdata->dev->dev_addr; | 177 | conf.bssid = sdata->dev->dev_addr; |
1003 | conf.ssid = sdata->u.ap.ssid; | 178 | conf.ssid = sdata->u.ap.ssid; |
1004 | conf.ssid_len = sdata->u.ap.ssid_len; | 179 | conf.ssid_len = sdata->u.ap.ssid_len; |
@@ -1027,7 +202,7 @@ int ieee80211_hw_config(struct ieee80211_local *local) | |||
1027 | struct ieee80211_channel *chan; | 202 | struct ieee80211_channel *chan; |
1028 | int ret = 0; | 203 | int ret = 0; |
1029 | 204 | ||
1030 | if (local->sta_sw_scanning) | 205 | if (local->sw_scanning) |
1031 | chan = local->scan_channel; | 206 | chan = local->scan_channel; |
1032 | else | 207 | else |
1033 | chan = local->oper_channel; | 208 | chan = local->oper_channel; |
@@ -1099,8 +274,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
1099 | ht_conf.ht_supported = 1; | 274 | ht_conf.ht_supported = 1; |
1100 | 275 | ||
1101 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 276 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
1102 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 277 | ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS); |
1103 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 278 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS; |
1104 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | 279 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; |
1105 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 280 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
1106 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 281 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
@@ -1152,6 +327,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
1152 | { | 327 | { |
1153 | struct ieee80211_local *local = sdata->local; | 328 | struct ieee80211_local *local = sdata->local; |
1154 | 329 | ||
330 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
331 | return; | ||
332 | |||
1155 | if (!changed) | 333 | if (!changed) |
1156 | return; | 334 | return; |
1157 | 335 | ||
@@ -1162,10 +340,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
1162 | changed); | 340 | changed); |
1163 | } | 341 | } |
1164 | 342 | ||
1165 | u32 ieee80211_reset_erp_info(struct net_device *dev) | 343 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
1166 | { | 344 | { |
1167 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1168 | |||
1169 | sdata->bss_conf.use_cts_prot = 0; | 345 | sdata->bss_conf.use_cts_prot = 0; |
1170 | sdata->bss_conf.use_short_preamble = 0; | 346 | sdata->bss_conf.use_short_preamble = 0; |
1171 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; | 347 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; |
@@ -1244,9 +420,10 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | |||
1244 | struct ieee80211_key *key, | 420 | struct ieee80211_key *key, |
1245 | struct sk_buff *skb) | 421 | struct sk_buff *skb) |
1246 | { | 422 | { |
1247 | int hdrlen, iv_len, mic_len; | 423 | unsigned int hdrlen, iv_len, mic_len; |
424 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1248 | 425 | ||
1249 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 426 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1250 | 427 | ||
1251 | if (!key) | 428 | if (!key) |
1252 | goto no_key; | 429 | goto no_key; |
@@ -1268,24 +445,20 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | |||
1268 | goto no_key; | 445 | goto no_key; |
1269 | } | 446 | } |
1270 | 447 | ||
1271 | if (skb->len >= mic_len && | 448 | if (skb->len >= hdrlen + mic_len && |
1272 | !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 449 | !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
1273 | skb_trim(skb, skb->len - mic_len); | 450 | skb_trim(skb, skb->len - mic_len); |
1274 | if (skb->len >= iv_len && skb->len > hdrlen) { | 451 | if (skb->len >= hdrlen + iv_len) { |
1275 | memmove(skb->data + iv_len, skb->data, hdrlen); | 452 | memmove(skb->data + iv_len, skb->data, hdrlen); |
1276 | skb_pull(skb, iv_len); | 453 | hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); |
1277 | } | 454 | } |
1278 | 455 | ||
1279 | no_key: | 456 | no_key: |
1280 | { | 457 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
1281 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 458 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
1282 | u16 fc = le16_to_cpu(hdr->frame_control); | 459 | memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, |
1283 | if ((fc & 0x8C) == 0x88) /* QoS Control Field */ { | 460 | hdrlen - IEEE80211_QOS_CTL_LEN); |
1284 | fc &= ~IEEE80211_STYPE_QOS_DATA; | 461 | skb_pull(skb, IEEE80211_QOS_CTL_LEN); |
1285 | hdr->frame_control = cpu_to_le16(fc); | ||
1286 | memmove(skb->data + 2, skb->data, hdrlen - 2); | ||
1287 | skb_pull(skb, 2); | ||
1288 | } | ||
1289 | } | 462 | } |
1290 | } | 463 | } |
1291 | 464 | ||
@@ -1369,6 +542,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1369 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 542 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1370 | u16 frag, type; | 543 | u16 frag, type; |
1371 | __le16 fc; | 544 | __le16 fc; |
545 | struct ieee80211_supported_band *sband; | ||
1372 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 546 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
1373 | struct ieee80211_sub_if_data *sdata; | 547 | struct ieee80211_sub_if_data *sdata; |
1374 | struct net_device *prev_dev = NULL; | 548 | struct net_device *prev_dev = NULL; |
@@ -1376,47 +550,48 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1376 | 550 | ||
1377 | rcu_read_lock(); | 551 | rcu_read_lock(); |
1378 | 552 | ||
1379 | if (info->status.excessive_retries) { | 553 | sta = sta_info_get(local, hdr->addr1); |
1380 | sta = sta_info_get(local, hdr->addr1); | 554 | |
1381 | if (sta) { | 555 | if (sta) { |
1382 | if (test_sta_flags(sta, WLAN_STA_PS)) { | 556 | if (info->status.excessive_retries && |
1383 | /* | 557 | test_sta_flags(sta, WLAN_STA_PS)) { |
1384 | * The STA is in power save mode, so assume | 558 | /* |
1385 | * that this TX packet failed because of that. | 559 | * The STA is in power save mode, so assume |
1386 | */ | 560 | * that this TX packet failed because of that. |
1387 | ieee80211_handle_filtered_frame(local, sta, skb); | 561 | */ |
1388 | rcu_read_unlock(); | 562 | ieee80211_handle_filtered_frame(local, sta, skb); |
1389 | return; | 563 | rcu_read_unlock(); |
1390 | } | 564 | return; |
1391 | } | 565 | } |
1392 | } | ||
1393 | 566 | ||
1394 | fc = hdr->frame_control; | 567 | fc = hdr->frame_control; |
568 | |||
569 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
570 | (ieee80211_is_data_qos(fc))) { | ||
571 | u16 tid, ssn; | ||
572 | u8 *qc; | ||
1395 | 573 | ||
1396 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
1397 | (ieee80211_is_data_qos(fc))) { | ||
1398 | u16 tid, ssn; | ||
1399 | u8 *qc; | ||
1400 | sta = sta_info_get(local, hdr->addr1); | ||
1401 | if (sta) { | ||
1402 | qc = ieee80211_get_qos_ctl(hdr); | 574 | qc = ieee80211_get_qos_ctl(hdr); |
1403 | tid = qc[0] & 0xf; | 575 | tid = qc[0] & 0xf; |
1404 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | 576 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) |
1405 | & IEEE80211_SCTL_SEQ); | 577 | & IEEE80211_SCTL_SEQ); |
1406 | ieee80211_send_bar(sta->sdata->dev, hdr->addr1, | 578 | ieee80211_send_bar(sta->sdata, hdr->addr1, |
1407 | tid, ssn); | 579 | tid, ssn); |
1408 | } | 580 | } |
1409 | } | ||
1410 | 581 | ||
1411 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | 582 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
1412 | sta = sta_info_get(local, hdr->addr1); | ||
1413 | if (sta) { | ||
1414 | ieee80211_handle_filtered_frame(local, sta, skb); | 583 | ieee80211_handle_filtered_frame(local, sta, skb); |
1415 | rcu_read_unlock(); | 584 | rcu_read_unlock(); |
1416 | return; | 585 | return; |
586 | } else { | ||
587 | if (info->status.excessive_retries) | ||
588 | sta->tx_retry_failed++; | ||
589 | sta->tx_retry_count += info->status.retry_count; | ||
1417 | } | 590 | } |
1418 | } else | 591 | |
1419 | rate_control_tx_status(local->mdev, skb); | 592 | sband = local->hw.wiphy->bands[info->band]; |
593 | rate_control_tx_status(local, sband, sta, skb); | ||
594 | } | ||
1420 | 595 | ||
1421 | rcu_read_unlock(); | 596 | rcu_read_unlock(); |
1422 | 597 | ||
@@ -1504,7 +679,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1504 | 679 | ||
1505 | rcu_read_lock(); | 680 | rcu_read_lock(); |
1506 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 681 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
1507 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { | 682 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { |
1508 | if (!netif_running(sdata->dev)) | 683 | if (!netif_running(sdata->dev)) |
1509 | continue; | 684 | continue; |
1510 | 685 | ||
@@ -1580,8 +755,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1580 | 755 | ||
1581 | local->hw.queues = 1; /* default */ | 756 | local->hw.queues = 1; /* default */ |
1582 | 757 | ||
1583 | local->bridge_packets = 1; | ||
1584 | |||
1585 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 758 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
1586 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 759 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
1587 | local->short_retry_limit = 7; | 760 | local->short_retry_limit = 7; |
@@ -1592,7 +765,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1592 | 765 | ||
1593 | spin_lock_init(&local->key_lock); | 766 | spin_lock_init(&local->key_lock); |
1594 | 767 | ||
1595 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 768 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
1596 | 769 | ||
1597 | sta_info_init(local); | 770 | sta_info_init(local); |
1598 | 771 | ||
@@ -1619,7 +792,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1619 | int result; | 792 | int result; |
1620 | enum ieee80211_band band; | 793 | enum ieee80211_band band; |
1621 | struct net_device *mdev; | 794 | struct net_device *mdev; |
1622 | struct wireless_dev *mwdev; | 795 | struct ieee80211_master_priv *mpriv; |
1623 | 796 | ||
1624 | /* | 797 | /* |
1625 | * generic code guarantees at least one band, | 798 | * generic code guarantees at least one band, |
@@ -1639,6 +812,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1639 | } | 812 | } |
1640 | } | 813 | } |
1641 | 814 | ||
815 | /* if low-level driver supports AP, we also support VLAN */ | ||
816 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) | ||
817 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | ||
818 | |||
819 | /* mac80211 always supports monitor */ | ||
820 | local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); | ||
821 | |||
1642 | result = wiphy_register(local->hw.wiphy); | 822 | result = wiphy_register(local->hw.wiphy); |
1643 | if (result < 0) | 823 | if (result < 0) |
1644 | return result; | 824 | return result; |
@@ -1654,16 +834,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1654 | if (hw->queues < 4) | 834 | if (hw->queues < 4) |
1655 | hw->ampdu_queues = 0; | 835 | hw->ampdu_queues = 0; |
1656 | 836 | ||
1657 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), | 837 | mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv), |
1658 | "wmaster%d", ether_setup, | 838 | "wmaster%d", ether_setup, |
1659 | ieee80211_num_queues(hw)); | 839 | ieee80211_num_queues(hw)); |
1660 | if (!mdev) | 840 | if (!mdev) |
1661 | goto fail_mdev_alloc; | 841 | goto fail_mdev_alloc; |
1662 | 842 | ||
1663 | mwdev = netdev_priv(mdev); | 843 | mpriv = netdev_priv(mdev); |
1664 | mdev->ieee80211_ptr = mwdev; | 844 | mpriv->local = local; |
1665 | mwdev->wiphy = local->hw.wiphy; | ||
1666 | |||
1667 | local->mdev = mdev; | 845 | local->mdev = mdev; |
1668 | 846 | ||
1669 | ieee80211_rx_bss_list_init(local); | 847 | ieee80211_rx_bss_list_init(local); |
@@ -1745,7 +923,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1745 | 923 | ||
1746 | /* add one default STA interface */ | 924 | /* add one default STA interface */ |
1747 | result = ieee80211_if_add(local, "wlan%d", NULL, | 925 | result = ieee80211_if_add(local, "wlan%d", NULL, |
1748 | IEEE80211_IF_TYPE_STA, NULL); | 926 | NL80211_IFTYPE_STATION, NULL); |
1749 | if (result) | 927 | if (result) |
1750 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 928 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
1751 | wiphy_name(local->hw.wiphy)); | 929 | wiphy_name(local->hw.wiphy)); |
@@ -1837,6 +1015,10 @@ static int __init ieee80211_init(void) | |||
1837 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | 1015 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + |
1838 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | 1016 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); |
1839 | 1017 | ||
1018 | ret = rc80211_minstrel_init(); | ||
1019 | if (ret) | ||
1020 | return ret; | ||
1021 | |||
1840 | ret = rc80211_pid_init(); | 1022 | ret = rc80211_pid_init(); |
1841 | if (ret) | 1023 | if (ret) |
1842 | return ret; | 1024 | return ret; |
@@ -1849,6 +1031,7 @@ static int __init ieee80211_init(void) | |||
1849 | static void __exit ieee80211_exit(void) | 1031 | static void __exit ieee80211_exit(void) |
1850 | { | 1032 | { |
1851 | rc80211_pid_exit(); | 1033 | rc80211_pid_exit(); |
1034 | rc80211_minstrel_exit(); | ||
1852 | 1035 | ||
1853 | /* | 1036 | /* |
1854 | * For key todo, it'll be empty by now but the work | 1037 | * For key todo, it'll be empty by now but the work |