diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 609 |
1 files changed, 284 insertions, 325 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index df0836ff1a20..f1a83d450ea0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -35,8 +35,6 @@ | |||
35 | #include "debugfs.h" | 35 | #include "debugfs.h" |
36 | #include "debugfs_netdev.h" | 36 | #include "debugfs_netdev.h" |
37 | 37 | ||
38 | #define SUPP_MCS_SET_LEN 16 | ||
39 | |||
40 | /* | 38 | /* |
41 | * For seeing transmitted packets on monitor interfaces | 39 | * For seeing transmitted packets on monitor interfaces |
42 | * we have a radiotap header too. | 40 | * we have a radiotap header too. |
@@ -107,12 +105,18 @@ static int ieee80211_master_open(struct net_device *dev) | |||
107 | 105 | ||
108 | /* we hold the RTNL here so can safely walk the list */ | 106 | /* we hold the RTNL here so can safely walk the list */ |
109 | list_for_each_entry(sdata, &local->interfaces, list) { | 107 | list_for_each_entry(sdata, &local->interfaces, list) { |
110 | if (sdata->dev != dev && netif_running(sdata->dev)) { | 108 | if (netif_running(sdata->dev)) { |
111 | res = 0; | 109 | res = 0; |
112 | break; | 110 | break; |
113 | } | 111 | } |
114 | } | 112 | } |
115 | return res; | 113 | |
114 | if (res) | ||
115 | return res; | ||
116 | |||
117 | netif_tx_start_all_queues(local->mdev); | ||
118 | |||
119 | return 0; | ||
116 | } | 120 | } |
117 | 121 | ||
118 | static int ieee80211_master_stop(struct net_device *dev) | 122 | static int ieee80211_master_stop(struct net_device *dev) |
@@ -122,7 +126,7 @@ static int ieee80211_master_stop(struct net_device *dev) | |||
122 | 126 | ||
123 | /* we hold the RTNL here so can safely walk the list */ | 127 | /* we hold the RTNL here so can safely walk the list */ |
124 | list_for_each_entry(sdata, &local->interfaces, list) | 128 | list_for_each_entry(sdata, &local->interfaces, list) |
125 | if (sdata->dev != dev && netif_running(sdata->dev)) | 129 | if (netif_running(sdata->dev)) |
126 | dev_close(sdata->dev); | 130 | dev_close(sdata->dev); |
127 | 131 | ||
128 | return 0; | 132 | return 0; |
@@ -147,9 +151,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
147 | /* FIX: what would be proper limits for MTU? | 151 | /* FIX: what would be proper limits for MTU? |
148 | * This interface uses 802.3 frames. */ | 152 | * This interface uses 802.3 frames. */ |
149 | if (new_mtu < 256 || | 153 | if (new_mtu < 256 || |
150 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | 154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { |
151 | printk(KERN_WARNING "%s: invalid MTU %d\n", | ||
152 | dev->name, new_mtu); | ||
153 | return -EINVAL; | 155 | return -EINVAL; |
154 | } | 156 | } |
155 | 157 | ||
@@ -180,10 +182,11 @@ static int ieee80211_open(struct net_device *dev) | |||
180 | { | 182 | { |
181 | struct ieee80211_sub_if_data *sdata, *nsdata; | 183 | struct ieee80211_sub_if_data *sdata, *nsdata; |
182 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 184 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
185 | struct sta_info *sta; | ||
183 | struct ieee80211_if_init_conf conf; | 186 | struct ieee80211_if_init_conf conf; |
187 | u32 changed = 0; | ||
184 | int res; | 188 | int res; |
185 | bool need_hw_reconfig = 0; | 189 | bool need_hw_reconfig = 0; |
186 | struct sta_info *sta; | ||
187 | 190 | ||
188 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 191 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
189 | 192 | ||
@@ -191,7 +194,7 @@ static int ieee80211_open(struct net_device *dev) | |||
191 | list_for_each_entry(nsdata, &local->interfaces, list) { | 194 | list_for_each_entry(nsdata, &local->interfaces, list) { |
192 | struct net_device *ndev = nsdata->dev; | 195 | struct net_device *ndev = nsdata->dev; |
193 | 196 | ||
194 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { | 197 | if (ndev != dev && netif_running(ndev)) { |
195 | /* | 198 | /* |
196 | * Allow only a single IBSS interface to be up at any | 199 | * Allow only a single IBSS interface to be up at any |
197 | * time. This is restricted because beacon distribution | 200 | * time. This is restricted because beacon distribution |
@@ -207,30 +210,6 @@ static int ieee80211_open(struct net_device *dev) | |||
207 | return -EBUSY; | 210 | return -EBUSY; |
208 | 211 | ||
209 | /* | 212 | /* |
210 | * Disallow multiple IBSS/STA mode interfaces. | ||
211 | * | ||
212 | * This is a technical restriction, it is possible although | ||
213 | * most likely not IEEE 802.11 compliant to have multiple | ||
214 | * STAs with just a single hardware (the TSF timer will not | ||
215 | * be adjusted properly.) | ||
216 | * | ||
217 | * However, because mac80211 uses the master device's BSS | ||
218 | * information for each STA/IBSS interface, doing this will | ||
219 | * currently corrupt that BSS information completely, unless, | ||
220 | * a not very useful case, both STAs are associated to the | ||
221 | * same BSS. | ||
222 | * | ||
223 | * To remove this restriction, the BSS information needs to | ||
224 | * be embedded in the STA/IBSS mode sdata instead of using | ||
225 | * the master device's BSS structure. | ||
226 | */ | ||
227 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
228 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && | ||
229 | (nsdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
230 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)) | ||
231 | return -EBUSY; | ||
232 | |||
233 | /* | ||
234 | * The remaining checks are only performed for interfaces | 213 | * The remaining checks are only performed for interfaces |
235 | * with the same MAC address. | 214 | * with the same MAC address. |
236 | */ | 215 | */ |
@@ -249,7 +228,7 @@ static int ieee80211_open(struct net_device *dev) | |||
249 | */ | 228 | */ |
250 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 229 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
251 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) | 230 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
252 | sdata->u.vlan.ap = nsdata; | 231 | sdata->bss = &nsdata->u.ap; |
253 | } | 232 | } |
254 | } | 233 | } |
255 | 234 | ||
@@ -259,10 +238,13 @@ static int ieee80211_open(struct net_device *dev) | |||
259 | return -ENOLINK; | 238 | return -ENOLINK; |
260 | break; | 239 | break; |
261 | case IEEE80211_IF_TYPE_VLAN: | 240 | case IEEE80211_IF_TYPE_VLAN: |
262 | if (!sdata->u.vlan.ap) | 241 | if (!sdata->bss) |
263 | return -ENOLINK; | 242 | return -ENOLINK; |
243 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | ||
264 | break; | 244 | break; |
265 | case IEEE80211_IF_TYPE_AP: | 245 | case IEEE80211_IF_TYPE_AP: |
246 | sdata->bss = &sdata->u.ap; | ||
247 | break; | ||
266 | case IEEE80211_IF_TYPE_STA: | 248 | case IEEE80211_IF_TYPE_STA: |
267 | case IEEE80211_IF_TYPE_MNTR: | 249 | case IEEE80211_IF_TYPE_MNTR: |
268 | case IEEE80211_IF_TYPE_IBSS: | 250 | case IEEE80211_IF_TYPE_IBSS: |
@@ -280,14 +262,13 @@ static int ieee80211_open(struct net_device *dev) | |||
280 | if (local->ops->start) | 262 | if (local->ops->start) |
281 | res = local->ops->start(local_to_hw(local)); | 263 | res = local->ops->start(local_to_hw(local)); |
282 | if (res) | 264 | if (res) |
283 | return res; | 265 | goto err_del_bss; |
284 | need_hw_reconfig = 1; | 266 | need_hw_reconfig = 1; |
285 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 267 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
286 | } | 268 | } |
287 | 269 | ||
288 | switch (sdata->vif.type) { | 270 | switch (sdata->vif.type) { |
289 | case IEEE80211_IF_TYPE_VLAN: | 271 | case IEEE80211_IF_TYPE_VLAN: |
290 | list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans); | ||
291 | /* no need to tell driver */ | 272 | /* no need to tell driver */ |
292 | break; | 273 | break; |
293 | case IEEE80211_IF_TYPE_MNTR: | 274 | case IEEE80211_IF_TYPE_MNTR: |
@@ -310,9 +291,9 @@ static int ieee80211_open(struct net_device *dev) | |||
310 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 291 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
311 | local->fif_other_bss++; | 292 | local->fif_other_bss++; |
312 | 293 | ||
313 | netif_tx_lock_bh(local->mdev); | 294 | netif_addr_lock_bh(local->mdev); |
314 | ieee80211_configure_filter(local); | 295 | ieee80211_configure_filter(local); |
315 | netif_tx_unlock_bh(local->mdev); | 296 | netif_addr_unlock_bh(local->mdev); |
316 | break; | 297 | break; |
317 | case IEEE80211_IF_TYPE_STA: | 298 | case IEEE80211_IF_TYPE_STA: |
318 | case IEEE80211_IF_TYPE_IBSS: | 299 | case IEEE80211_IF_TYPE_IBSS: |
@@ -326,8 +307,10 @@ static int ieee80211_open(struct net_device *dev) | |||
326 | if (res) | 307 | if (res) |
327 | goto err_stop; | 308 | goto err_stop; |
328 | 309 | ||
329 | ieee80211_if_config(dev); | 310 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
330 | ieee80211_reset_erp_info(dev); | 311 | ieee80211_start_mesh(sdata->dev); |
312 | changed |= ieee80211_reset_erp_info(dev); | ||
313 | ieee80211_bss_info_change_notify(sdata, changed); | ||
331 | ieee80211_enable_keys(sdata); | 314 | ieee80211_enable_keys(sdata); |
332 | 315 | ||
333 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 316 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
@@ -346,6 +329,7 @@ static int ieee80211_open(struct net_device *dev) | |||
346 | goto err_del_interface; | 329 | goto err_del_interface; |
347 | } | 330 | } |
348 | 331 | ||
332 | /* no locking required since STA is not live yet */ | ||
349 | sta->flags |= WLAN_STA_AUTHORIZED; | 333 | sta->flags |= WLAN_STA_AUTHORIZED; |
350 | 334 | ||
351 | res = sta_info_insert(sta); | 335 | res = sta_info_insert(sta); |
@@ -385,13 +369,13 @@ static int ieee80211_open(struct net_device *dev) | |||
385 | * yet be effective. Trigger execution of ieee80211_sta_work | 369 | * yet be effective. Trigger execution of ieee80211_sta_work |
386 | * to fix this. | 370 | * to fix this. |
387 | */ | 371 | */ |
388 | if(sdata->vif.type == IEEE80211_IF_TYPE_STA || | 372 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
389 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 373 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
390 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 374 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
391 | queue_work(local->hw.workqueue, &ifsta->work); | 375 | queue_work(local->hw.workqueue, &ifsta->work); |
392 | } | 376 | } |
393 | 377 | ||
394 | netif_start_queue(dev); | 378 | netif_tx_start_all_queues(dev); |
395 | 379 | ||
396 | return 0; | 380 | return 0; |
397 | err_del_interface: | 381 | err_del_interface: |
@@ -399,6 +383,10 @@ static int ieee80211_open(struct net_device *dev) | |||
399 | err_stop: | 383 | err_stop: |
400 | if (!local->open_count && local->ops->stop) | 384 | if (!local->open_count && local->ops->stop) |
401 | local->ops->stop(local_to_hw(local)); | 385 | local->ops->stop(local_to_hw(local)); |
386 | err_del_bss: | ||
387 | sdata->bss = NULL; | ||
388 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | ||
389 | list_del(&sdata->u.vlan.list); | ||
402 | return res; | 390 | return res; |
403 | } | 391 | } |
404 | 392 | ||
@@ -412,7 +400,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
412 | /* | 400 | /* |
413 | * Stop TX on this interface first. | 401 | * Stop TX on this interface first. |
414 | */ | 402 | */ |
415 | netif_stop_queue(dev); | 403 | netif_tx_stop_all_queues(dev); |
416 | 404 | ||
417 | /* | 405 | /* |
418 | * Now delete all active aggregation sessions. | 406 | * Now delete all active aggregation sessions. |
@@ -481,7 +469,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
481 | switch (sdata->vif.type) { | 469 | switch (sdata->vif.type) { |
482 | case IEEE80211_IF_TYPE_VLAN: | 470 | case IEEE80211_IF_TYPE_VLAN: |
483 | list_del(&sdata->u.vlan.list); | 471 | list_del(&sdata->u.vlan.list); |
484 | sdata->u.vlan.ap = NULL; | ||
485 | /* no need to tell driver */ | 472 | /* no need to tell driver */ |
486 | break; | 473 | break; |
487 | case IEEE80211_IF_TYPE_MNTR: | 474 | case IEEE80211_IF_TYPE_MNTR: |
@@ -503,9 +490,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
503 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 490 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
504 | local->fif_other_bss--; | 491 | local->fif_other_bss--; |
505 | 492 | ||
506 | netif_tx_lock_bh(local->mdev); | 493 | netif_addr_lock_bh(local->mdev); |
507 | ieee80211_configure_filter(local); | 494 | ieee80211_configure_filter(local); |
508 | netif_tx_unlock_bh(local->mdev); | 495 | netif_addr_unlock_bh(local->mdev); |
509 | break; | 496 | break; |
510 | case IEEE80211_IF_TYPE_MESH_POINT: | 497 | case IEEE80211_IF_TYPE_MESH_POINT: |
511 | case IEEE80211_IF_TYPE_STA: | 498 | case IEEE80211_IF_TYPE_STA: |
@@ -544,6 +531,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
544 | local->ops->remove_interface(local_to_hw(local), &conf); | 531 | local->ops->remove_interface(local_to_hw(local), &conf); |
545 | } | 532 | } |
546 | 533 | ||
534 | sdata->bss = NULL; | ||
535 | |||
547 | if (local->open_count == 0) { | 536 | if (local->open_count == 0) { |
548 | if (netif_running(local->mdev)) | 537 | if (netif_running(local->mdev)) |
549 | dev_close(local->mdev); | 538 | dev_close(local->mdev); |
@@ -584,17 +573,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
584 | 573 | ||
585 | sta = sta_info_get(local, ra); | 574 | sta = sta_info_get(local, ra); |
586 | if (!sta) { | 575 | if (!sta) { |
576 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
587 | printk(KERN_DEBUG "Could not find the station\n"); | 577 | printk(KERN_DEBUG "Could not find the station\n"); |
588 | rcu_read_unlock(); | 578 | #endif |
589 | return -ENOENT; | 579 | ret = -ENOENT; |
580 | goto exit; | ||
590 | } | 581 | } |
591 | 582 | ||
592 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 583 | spin_lock_bh(&sta->lock); |
593 | 584 | ||
594 | /* we have tried too many times, receiver does not want A-MPDU */ | 585 | /* we have tried too many times, receiver does not want A-MPDU */ |
595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 586 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
596 | ret = -EBUSY; | 587 | ret = -EBUSY; |
597 | goto start_ba_exit; | 588 | goto err_unlock_sta; |
598 | } | 589 | } |
599 | 590 | ||
600 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 591 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
@@ -605,18 +596,20 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
605 | "idle on tid %u\n", tid); | 596 | "idle on tid %u\n", tid); |
606 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 597 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
607 | ret = -EAGAIN; | 598 | ret = -EAGAIN; |
608 | goto start_ba_exit; | 599 | goto err_unlock_sta; |
609 | } | 600 | } |
610 | 601 | ||
611 | /* prepare A-MPDU MLME for Tx aggregation */ | 602 | /* prepare A-MPDU MLME for Tx aggregation */ |
612 | sta->ampdu_mlme.tid_tx[tid] = | 603 | sta->ampdu_mlme.tid_tx[tid] = |
613 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | 604 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); |
614 | if (!sta->ampdu_mlme.tid_tx[tid]) { | 605 | if (!sta->ampdu_mlme.tid_tx[tid]) { |
606 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
615 | if (net_ratelimit()) | 607 | if (net_ratelimit()) |
616 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | 608 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", |
617 | tid); | 609 | tid); |
610 | #endif | ||
618 | ret = -ENOMEM; | 611 | ret = -ENOMEM; |
619 | goto start_ba_exit; | 612 | goto err_unlock_sta; |
620 | } | 613 | } |
621 | /* Tx timer */ | 614 | /* Tx timer */ |
622 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | 615 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = |
@@ -625,10 +618,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
625 | (unsigned long)&sta->timer_to_tid[tid]; | 618 | (unsigned long)&sta->timer_to_tid[tid]; |
626 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 619 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
627 | 620 | ||
628 | /* ensure that TX flow won't interrupt us | ||
629 | * until the end of the call to requeue function */ | ||
630 | spin_lock_bh(&local->mdev->queue_lock); | ||
631 | |||
632 | /* create a new queue for this aggregation */ | 621 | /* create a new queue for this aggregation */ |
633 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | 622 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); |
634 | 623 | ||
@@ -639,7 +628,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
639 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 628 | printk(KERN_DEBUG "BA request denied - queue unavailable for" |
640 | " tid %d\n", tid); | 629 | " tid %d\n", tid); |
641 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 630 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
642 | goto start_ba_err; | 631 | goto err_unlock_queue; |
643 | } | 632 | } |
644 | sdata = sta->sdata; | 633 | sdata = sta->sdata; |
645 | 634 | ||
@@ -655,18 +644,18 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
655 | /* No need to requeue the packets in the agg queue, since we | 644 | /* No need to requeue the packets in the agg queue, since we |
656 | * held the tx lock: no packet could be enqueued to the newly | 645 | * held the tx lock: no packet could be enqueued to the newly |
657 | * allocated queue */ | 646 | * allocated queue */ |
658 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | 647 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); |
659 | #ifdef CONFIG_MAC80211_HT_DEBUG | 648 | #ifdef CONFIG_MAC80211_HT_DEBUG |
660 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 649 | printk(KERN_DEBUG "BA request denied - HW unavailable for" |
661 | " tid %d\n", tid); | 650 | " tid %d\n", tid); |
662 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 651 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
663 | *state = HT_AGG_STATE_IDLE; | 652 | *state = HT_AGG_STATE_IDLE; |
664 | goto start_ba_err; | 653 | goto err_unlock_queue; |
665 | } | 654 | } |
666 | 655 | ||
667 | /* Will put all the packets in the new SW queue */ | 656 | /* Will put all the packets in the new SW queue */ |
668 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 657 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); |
669 | spin_unlock_bh(&local->mdev->queue_lock); | 658 | spin_unlock_bh(&sta->lock); |
670 | 659 | ||
671 | /* send an addBA request */ | 660 | /* send an addBA request */ |
672 | sta->ampdu_mlme.dialog_token_allocator++; | 661 | sta->ampdu_mlme.dialog_token_allocator++; |
@@ -674,25 +663,27 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
674 | sta->ampdu_mlme.dialog_token_allocator; | 663 | sta->ampdu_mlme.dialog_token_allocator; |
675 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 664 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
676 | 665 | ||
666 | |||
677 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | 667 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, |
678 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 668 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
679 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 669 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
680 | 0x40, 5000); | 670 | 0x40, 5000); |
681 | |||
682 | /* activate the timer for the recipient's addBA response */ | 671 | /* activate the timer for the recipient's addBA response */ |
683 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 672 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
684 | jiffies + ADDBA_RESP_INTERVAL; | 673 | jiffies + ADDBA_RESP_INTERVAL; |
685 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 674 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
675 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
686 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 676 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
687 | goto start_ba_exit; | 677 | #endif |
678 | goto exit; | ||
688 | 679 | ||
689 | start_ba_err: | 680 | err_unlock_queue: |
690 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 681 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
691 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 682 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
692 | spin_unlock_bh(&local->mdev->queue_lock); | ||
693 | ret = -EBUSY; | 683 | ret = -EBUSY; |
694 | start_ba_exit: | 684 | err_unlock_sta: |
695 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 685 | spin_unlock_bh(&sta->lock); |
686 | exit: | ||
696 | rcu_read_unlock(); | 687 | rcu_read_unlock(); |
697 | return ret; | 688 | return ret; |
698 | } | 689 | } |
@@ -720,7 +711,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
720 | 711 | ||
721 | /* check if the TID is in aggregation */ | 712 | /* check if the TID is in aggregation */ |
722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 713 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
723 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 714 | spin_lock_bh(&sta->lock); |
724 | 715 | ||
725 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 716 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
726 | ret = -ENOENT; | 717 | ret = -ENOENT; |
@@ -750,7 +741,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
750 | } | 741 | } |
751 | 742 | ||
752 | stop_BA_exit: | 743 | stop_BA_exit: |
753 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 744 | spin_unlock_bh(&sta->lock); |
754 | rcu_read_unlock(); | 745 | rcu_read_unlock(); |
755 | return ret; | 746 | return ret; |
756 | } | 747 | } |
@@ -764,8 +755,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
764 | DECLARE_MAC_BUF(mac); | 755 | DECLARE_MAC_BUF(mac); |
765 | 756 | ||
766 | if (tid >= STA_TID_NUM) { | 757 | if (tid >= STA_TID_NUM) { |
758 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
767 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 759 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
768 | tid, STA_TID_NUM); | 760 | tid, STA_TID_NUM); |
761 | #endif | ||
769 | return; | 762 | return; |
770 | } | 763 | } |
771 | 764 | ||
@@ -773,18 +766,22 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
773 | sta = sta_info_get(local, ra); | 766 | sta = sta_info_get(local, ra); |
774 | if (!sta) { | 767 | if (!sta) { |
775 | rcu_read_unlock(); | 768 | rcu_read_unlock(); |
769 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
776 | printk(KERN_DEBUG "Could not find station: %s\n", | 770 | printk(KERN_DEBUG "Could not find station: %s\n", |
777 | print_mac(mac, ra)); | 771 | print_mac(mac, ra)); |
772 | #endif | ||
778 | return; | 773 | return; |
779 | } | 774 | } |
780 | 775 | ||
781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 776 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
782 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 777 | spin_lock_bh(&sta->lock); |
783 | 778 | ||
784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 779 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
780 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 781 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
786 | *state); | 782 | *state); |
787 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 783 | #endif |
784 | spin_unlock_bh(&sta->lock); | ||
788 | rcu_read_unlock(); | 785 | rcu_read_unlock(); |
789 | return; | 786 | return; |
790 | } | 787 | } |
@@ -794,10 +791,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
794 | *state |= HT_ADDBA_DRV_READY_MSK; | 791 | *state |= HT_ADDBA_DRV_READY_MSK; |
795 | 792 | ||
796 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 793 | if (*state == HT_AGG_STATE_OPERATIONAL) { |
794 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 795 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
796 | #endif | ||
798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 797 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
799 | } | 798 | } |
800 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 799 | spin_unlock_bh(&sta->lock); |
801 | rcu_read_unlock(); | 800 | rcu_read_unlock(); |
802 | } | 801 | } |
803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 802 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
@@ -811,8 +810,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
811 | DECLARE_MAC_BUF(mac); | 810 | DECLARE_MAC_BUF(mac); |
812 | 811 | ||
813 | if (tid >= STA_TID_NUM) { | 812 | if (tid >= STA_TID_NUM) { |
813 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
814 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 814 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
815 | tid, STA_TID_NUM); | 815 | tid, STA_TID_NUM); |
816 | #endif | ||
816 | return; | 817 | return; |
817 | } | 818 | } |
818 | 819 | ||
@@ -824,17 +825,23 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
824 | rcu_read_lock(); | 825 | rcu_read_lock(); |
825 | sta = sta_info_get(local, ra); | 826 | sta = sta_info_get(local, ra); |
826 | if (!sta) { | 827 | if (!sta) { |
828 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
827 | printk(KERN_DEBUG "Could not find station: %s\n", | 829 | printk(KERN_DEBUG "Could not find station: %s\n", |
828 | print_mac(mac, ra)); | 830 | print_mac(mac, ra)); |
831 | #endif | ||
829 | rcu_read_unlock(); | 832 | rcu_read_unlock(); |
830 | return; | 833 | return; |
831 | } | 834 | } |
832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 835 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
833 | 836 | ||
834 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 837 | /* NOTE: no need to use sta->lock in this state check, as |
838 | * ieee80211_stop_tx_ba_session will let only one stop call to | ||
839 | * pass through per sta/tid | ||
840 | */ | ||
835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 841 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
842 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 843 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
837 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 844 | #endif |
838 | rcu_read_unlock(); | 845 | rcu_read_unlock(); |
839 | return; | 846 | return; |
840 | } | 847 | } |
@@ -845,23 +852,20 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
845 | 852 | ||
846 | agg_queue = sta->tid_to_tx_q[tid]; | 853 | agg_queue = sta->tid_to_tx_q[tid]; |
847 | 854 | ||
848 | /* avoid ordering issues: we are the only one that can modify | ||
849 | * the content of the qdiscs */ | ||
850 | spin_lock_bh(&local->mdev->queue_lock); | ||
851 | /* remove the queue for this aggregation */ | ||
852 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | 855 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); |
853 | spin_unlock_bh(&local->mdev->queue_lock); | ||
854 | 856 | ||
855 | /* we just requeued the all the frames that were in the removed | 857 | /* We just requeued the all the frames that were in the |
856 | * queue, and since we might miss a softirq we do netif_schedule. | 858 | * removed queue, and since we might miss a softirq we do |
857 | * ieee80211_wake_queue is not used here as this queue is not | 859 | * netif_schedule_queue. ieee80211_wake_queue is not used |
858 | * necessarily stopped */ | 860 | * here as this queue is not necessarily stopped |
859 | netif_schedule(local->mdev); | 861 | */ |
862 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | ||
863 | spin_lock_bh(&sta->lock); | ||
860 | *state = HT_AGG_STATE_IDLE; | 864 | *state = HT_AGG_STATE_IDLE; |
861 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 865 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
862 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 866 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
863 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 867 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
864 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 868 | spin_unlock_bh(&sta->lock); |
865 | 869 | ||
866 | rcu_read_unlock(); | 870 | rcu_read_unlock(); |
867 | } | 871 | } |
@@ -875,9 +879,11 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
875 | struct sk_buff *skb = dev_alloc_skb(0); | 879 | struct sk_buff *skb = dev_alloc_skb(0); |
876 | 880 | ||
877 | if (unlikely(!skb)) { | 881 | if (unlikely(!skb)) { |
882 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
878 | if (net_ratelimit()) | 883 | if (net_ratelimit()) |
879 | printk(KERN_WARNING "%s: Not enough memory, " | 884 | printk(KERN_WARNING "%s: Not enough memory, " |
880 | "dropping start BA session", skb->dev->name); | 885 | "dropping start BA session", skb->dev->name); |
886 | #endif | ||
881 | return; | 887 | return; |
882 | } | 888 | } |
883 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 889 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -898,9 +904,11 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
898 | struct sk_buff *skb = dev_alloc_skb(0); | 904 | struct sk_buff *skb = dev_alloc_skb(0); |
899 | 905 | ||
900 | if (unlikely(!skb)) { | 906 | if (unlikely(!skb)) { |
907 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
901 | if (net_ratelimit()) | 908 | if (net_ratelimit()) |
902 | printk(KERN_WARNING "%s: Not enough memory, " | 909 | printk(KERN_WARNING "%s: Not enough memory, " |
903 | "dropping stop BA session", skb->dev->name); | 910 | "dropping stop BA session", skb->dev->name); |
911 | #endif | ||
904 | return; | 912 | return; |
905 | } | 913 | } |
906 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 914 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -951,7 +959,6 @@ static const struct header_ops ieee80211_header_ops = { | |||
951 | .cache_update = eth_header_cache_update, | 959 | .cache_update = eth_header_cache_update, |
952 | }; | 960 | }; |
953 | 961 | ||
954 | /* Must not be called for mdev */ | ||
955 | void ieee80211_if_setup(struct net_device *dev) | 962 | void ieee80211_if_setup(struct net_device *dev) |
956 | { | 963 | { |
957 | ether_setup(dev); | 964 | ether_setup(dev); |
@@ -961,67 +968,52 @@ void ieee80211_if_setup(struct net_device *dev) | |||
961 | dev->change_mtu = ieee80211_change_mtu; | 968 | dev->change_mtu = ieee80211_change_mtu; |
962 | dev->open = ieee80211_open; | 969 | dev->open = ieee80211_open; |
963 | dev->stop = ieee80211_stop; | 970 | dev->stop = ieee80211_stop; |
964 | dev->destructor = ieee80211_if_free; | 971 | dev->destructor = free_netdev; |
965 | } | 972 | } |
966 | 973 | ||
967 | /* everything else */ | 974 | /* everything else */ |
968 | 975 | ||
969 | static int __ieee80211_if_config(struct net_device *dev, | 976 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) |
970 | struct sk_buff *beacon, | ||
971 | struct ieee80211_tx_control *control) | ||
972 | { | 977 | { |
973 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 978 | struct ieee80211_local *local = sdata->local; |
974 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
975 | struct ieee80211_if_conf conf; | 979 | struct ieee80211_if_conf conf; |
976 | 980 | ||
977 | if (!local->ops->config_interface || !netif_running(dev)) | 981 | if (WARN_ON(!netif_running(sdata->dev))) |
982 | return 0; | ||
983 | |||
984 | if (!local->ops->config_interface) | ||
978 | return 0; | 985 | return 0; |
979 | 986 | ||
980 | memset(&conf, 0, sizeof(conf)); | 987 | memset(&conf, 0, sizeof(conf)); |
981 | conf.type = sdata->vif.type; | 988 | conf.changed = changed; |
989 | |||
982 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | 990 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
983 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 991 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
984 | conf.bssid = sdata->u.sta.bssid; | 992 | conf.bssid = sdata->u.sta.bssid; |
985 | conf.ssid = sdata->u.sta.ssid; | 993 | conf.ssid = sdata->u.sta.ssid; |
986 | conf.ssid_len = sdata->u.sta.ssid_len; | 994 | conf.ssid_len = sdata->u.sta.ssid_len; |
987 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
988 | conf.beacon = beacon; | ||
989 | conf.beacon_control = control; | ||
990 | ieee80211_start_mesh(dev); | ||
991 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 995 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
996 | conf.bssid = sdata->dev->dev_addr; | ||
992 | conf.ssid = sdata->u.ap.ssid; | 997 | conf.ssid = sdata->u.ap.ssid; |
993 | conf.ssid_len = sdata->u.ap.ssid_len; | 998 | conf.ssid_len = sdata->u.ap.ssid_len; |
994 | conf.beacon = beacon; | 999 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
995 | conf.beacon_control = control; | 1000 | u8 zero[ETH_ALEN] = { 0 }; |
1001 | conf.bssid = zero; | ||
1002 | conf.ssid = zero; | ||
1003 | conf.ssid_len = 0; | ||
1004 | } else { | ||
1005 | WARN_ON(1); | ||
1006 | return -EINVAL; | ||
996 | } | 1007 | } |
997 | return local->ops->config_interface(local_to_hw(local), | ||
998 | &sdata->vif, &conf); | ||
999 | } | ||
1000 | 1008 | ||
1001 | int ieee80211_if_config(struct net_device *dev) | 1009 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) |
1002 | { | 1010 | return -EINVAL; |
1003 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1004 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1005 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | ||
1006 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | ||
1007 | return ieee80211_if_config_beacon(dev); | ||
1008 | return __ieee80211_if_config(dev, NULL, NULL); | ||
1009 | } | ||
1010 | 1011 | ||
1011 | int ieee80211_if_config_beacon(struct net_device *dev) | 1012 | if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID))) |
1012 | { | 1013 | return -EINVAL; |
1013 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1014 | struct ieee80211_tx_control control; | ||
1015 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1016 | struct sk_buff *skb; | ||
1017 | 1014 | ||
1018 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1015 | return local->ops->config_interface(local_to_hw(local), |
1019 | return 0; | 1016 | &sdata->vif, &conf); |
1020 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, | ||
1021 | &control); | ||
1022 | if (!skb) | ||
1023 | return -ENOMEM; | ||
1024 | return __ieee80211_if_config(dev, skb, &control); | ||
1025 | } | 1017 | } |
1026 | 1018 | ||
1027 | int ieee80211_hw_config(struct ieee80211_local *local) | 1019 | int ieee80211_hw_config(struct ieee80211_local *local) |
@@ -1068,56 +1060,84 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
1068 | struct ieee80211_supported_band *sband; | 1060 | struct ieee80211_supported_band *sband; |
1069 | struct ieee80211_ht_info ht_conf; | 1061 | struct ieee80211_ht_info ht_conf; |
1070 | struct ieee80211_ht_bss_info ht_bss_conf; | 1062 | struct ieee80211_ht_bss_info ht_bss_conf; |
1071 | int i; | ||
1072 | u32 changed = 0; | 1063 | u32 changed = 0; |
1064 | int i; | ||
1065 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
1066 | u8 tx_mcs_set_cap; | ||
1073 | 1067 | ||
1074 | sband = local->hw.wiphy->bands[conf->channel->band]; | 1068 | sband = local->hw.wiphy->bands[conf->channel->band]; |
1075 | 1069 | ||
1070 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
1071 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
1072 | |||
1076 | /* HT is not supported */ | 1073 | /* HT is not supported */ |
1077 | if (!sband->ht_info.ht_supported) { | 1074 | if (!sband->ht_info.ht_supported) { |
1078 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1075 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
1079 | return 0; | 1076 | goto out; |
1080 | } | 1077 | } |
1081 | 1078 | ||
1082 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | 1079 | /* disable HT */ |
1083 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | 1080 | if (!enable_ht) { |
1084 | 1081 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | |
1085 | if (enable_ht) { | ||
1086 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
1087 | changed |= BSS_CHANGED_HT; | 1082 | changed |= BSS_CHANGED_HT; |
1083 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1084 | conf->ht_conf.ht_supported = 0; | ||
1085 | goto out; | ||
1086 | } | ||
1088 | 1087 | ||
1089 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1090 | ht_conf.ht_supported = 1; | ||
1091 | 1088 | ||
1092 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 1089 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) |
1093 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1090 | changed |= BSS_CHANGED_HT; |
1094 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | ||
1095 | 1091 | ||
1096 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1092 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
1097 | ht_conf.supp_mcs_set[i] = | 1093 | ht_conf.ht_supported = 1; |
1098 | sband->ht_info.supp_mcs_set[i] & | ||
1099 | req_ht_cap->supp_mcs_set[i]; | ||
1100 | 1094 | ||
1101 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | 1095 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
1102 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1096 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
1103 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1097 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
1098 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
1099 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
1100 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
1104 | 1101 | ||
1105 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | 1102 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; |
1106 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | 1103 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; |
1107 | 1104 | ||
1108 | /* if bss configuration changed store the new one */ | 1105 | /* Bits 96-100 */ |
1109 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | 1106 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; |
1110 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | 1107 | |
1111 | changed |= BSS_CHANGED_HT; | 1108 | /* configure suppoerted Tx MCS according to requested MCS |
1112 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | 1109 | * (based in most cases on Rx capabilities of peer) and self |
1113 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | 1110 | * Tx MCS capabilities (as defined by low level driver HW |
1114 | } | 1111 | * Tx capabilities) */ |
1115 | } else { | 1112 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) |
1116 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 1113 | goto check_changed; |
1117 | changed |= BSS_CHANGED_HT; | ||
1118 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1119 | } | ||
1120 | 1114 | ||
1115 | /* Counting from 0 therfore + 1 */ | ||
1116 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
1117 | max_tx_streams = ((tx_mcs_set_cap & | ||
1118 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
1119 | |||
1120 | for (i = 0; i < max_tx_streams; i++) | ||
1121 | ht_conf.supp_mcs_set[i] = | ||
1122 | sband->ht_info.supp_mcs_set[i] & | ||
1123 | req_ht_cap->supp_mcs_set[i]; | ||
1124 | |||
1125 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
1126 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
1127 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
1128 | ht_conf.supp_mcs_set[i] = | ||
1129 | sband->ht_info.supp_mcs_set[i] & | ||
1130 | req_ht_cap->supp_mcs_set[i]; | ||
1131 | |||
1132 | check_changed: | ||
1133 | /* if bss configuration changed store the new one */ | ||
1134 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
1135 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
1136 | changed |= BSS_CHANGED_HT; | ||
1137 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
1138 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
1139 | } | ||
1140 | out: | ||
1121 | return changed; | 1141 | return changed; |
1122 | } | 1142 | } |
1123 | 1143 | ||
@@ -1136,50 +1156,30 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
1136 | changed); | 1156 | changed); |
1137 | } | 1157 | } |
1138 | 1158 | ||
1139 | void ieee80211_reset_erp_info(struct net_device *dev) | 1159 | u32 ieee80211_reset_erp_info(struct net_device *dev) |
1140 | { | 1160 | { |
1141 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1161 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1142 | 1162 | ||
1143 | sdata->bss_conf.use_cts_prot = 0; | 1163 | sdata->bss_conf.use_cts_prot = 0; |
1144 | sdata->bss_conf.use_short_preamble = 0; | 1164 | sdata->bss_conf.use_short_preamble = 0; |
1145 | ieee80211_bss_info_change_notify(sdata, | 1165 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; |
1146 | BSS_CHANGED_ERP_CTS_PROT | | ||
1147 | BSS_CHANGED_ERP_PREAMBLE); | ||
1148 | } | 1166 | } |
1149 | 1167 | ||
1150 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1168 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
1151 | struct sk_buff *skb, | 1169 | struct sk_buff *skb) |
1152 | struct ieee80211_tx_status *status) | ||
1153 | { | 1170 | { |
1154 | struct ieee80211_local *local = hw_to_local(hw); | 1171 | struct ieee80211_local *local = hw_to_local(hw); |
1155 | struct ieee80211_tx_status *saved; | 1172 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1156 | int tmp; | 1173 | int tmp; |
1157 | 1174 | ||
1158 | skb->dev = local->mdev; | 1175 | skb->dev = local->mdev; |
1159 | saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC); | ||
1160 | if (unlikely(!saved)) { | ||
1161 | if (net_ratelimit()) | ||
1162 | printk(KERN_WARNING "%s: Not enough memory, " | ||
1163 | "dropping tx status", skb->dev->name); | ||
1164 | /* should be dev_kfree_skb_irq, but due to this function being | ||
1165 | * named _irqsafe instead of just _irq we can't be sure that | ||
1166 | * people won't call it from non-irq contexts */ | ||
1167 | dev_kfree_skb_any(skb); | ||
1168 | return; | ||
1169 | } | ||
1170 | memcpy(saved, status, sizeof(struct ieee80211_tx_status)); | ||
1171 | /* copy pointer to saved status into skb->cb for use by tasklet */ | ||
1172 | memcpy(skb->cb, &saved, sizeof(saved)); | ||
1173 | |||
1174 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 1176 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
1175 | skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? | 1177 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
1176 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 1178 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
1177 | tmp = skb_queue_len(&local->skb_queue) + | 1179 | tmp = skb_queue_len(&local->skb_queue) + |
1178 | skb_queue_len(&local->skb_queue_unreliable); | 1180 | skb_queue_len(&local->skb_queue_unreliable); |
1179 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 1181 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
1180 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1182 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
1181 | memcpy(&saved, skb->cb, sizeof(saved)); | ||
1182 | kfree(saved); | ||
1183 | dev_kfree_skb_irq(skb); | 1183 | dev_kfree_skb_irq(skb); |
1184 | tmp--; | 1184 | tmp--; |
1185 | I802_DEBUG_INC(local->tx_status_drop); | 1185 | I802_DEBUG_INC(local->tx_status_drop); |
@@ -1193,7 +1193,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
1194 | struct sk_buff *skb; | 1194 | struct sk_buff *skb; |
1195 | struct ieee80211_rx_status rx_status; | 1195 | struct ieee80211_rx_status rx_status; |
1196 | struct ieee80211_tx_status *tx_status; | ||
1197 | struct ieee80211_ra_tid *ra_tid; | 1196 | struct ieee80211_ra_tid *ra_tid; |
1198 | 1197 | ||
1199 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1198 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -1208,12 +1207,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1208 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 1207 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
1209 | break; | 1208 | break; |
1210 | case IEEE80211_TX_STATUS_MSG: | 1209 | case IEEE80211_TX_STATUS_MSG: |
1211 | /* get pointer to saved status out of skb->cb */ | ||
1212 | memcpy(&tx_status, skb->cb, sizeof(tx_status)); | ||
1213 | skb->pkt_type = 0; | 1210 | skb->pkt_type = 0; |
1214 | ieee80211_tx_status(local_to_hw(local), | 1211 | ieee80211_tx_status(local_to_hw(local), skb); |
1215 | skb, tx_status); | ||
1216 | kfree(tx_status); | ||
1217 | break; | 1212 | break; |
1218 | case IEEE80211_DELBA_MSG: | 1213 | case IEEE80211_DELBA_MSG: |
1219 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 1214 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -1227,9 +1222,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1227 | ra_tid->ra, ra_tid->tid); | 1222 | ra_tid->ra, ra_tid->tid); |
1228 | dev_kfree_skb(skb); | 1223 | dev_kfree_skb(skb); |
1229 | break ; | 1224 | break ; |
1230 | default: /* should never get here! */ | 1225 | default: |
1231 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1226 | WARN_ON(1); |
1232 | wiphy_name(local->hw.wiphy), skb->pkt_type); | ||
1233 | dev_kfree_skb(skb); | 1227 | dev_kfree_skb(skb); |
1234 | break; | 1228 | break; |
1235 | } | 1229 | } |
@@ -1242,24 +1236,15 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1242 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1236 | * Also, tx_packet_data in cb is restored from tx_control. */ |
1243 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1244 | struct ieee80211_key *key, | 1238 | struct ieee80211_key *key, |
1245 | struct sk_buff *skb, | 1239 | struct sk_buff *skb) |
1246 | struct ieee80211_tx_control *control) | ||
1247 | { | 1240 | { |
1248 | int hdrlen, iv_len, mic_len; | 1241 | int hdrlen, iv_len, mic_len; |
1249 | struct ieee80211_tx_packet_data *pkt_data; | 1242 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1250 | 1243 | ||
1251 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1244 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | |
1252 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; | 1245 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | |
1253 | pkt_data->flags = 0; | 1246 | IEEE80211_TX_CTL_REQUEUE | |
1254 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 1247 | IEEE80211_TX_CTL_EAPOL_FRAME; |
1255 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1256 | if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT) | ||
1257 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | ||
1258 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | ||
1259 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | ||
1260 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
1261 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
1262 | pkt_data->queue = control->queue; | ||
1263 | 1248 | ||
1264 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1249 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1265 | 1250 | ||
@@ -1306,9 +1291,10 @@ no_key: | |||
1306 | 1291 | ||
1307 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 1292 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
1308 | struct sta_info *sta, | 1293 | struct sta_info *sta, |
1309 | struct sk_buff *skb, | 1294 | struct sk_buff *skb) |
1310 | struct ieee80211_tx_status *status) | ||
1311 | { | 1295 | { |
1296 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1297 | |||
1312 | sta->tx_filtered_count++; | 1298 | sta->tx_filtered_count++; |
1313 | 1299 | ||
1314 | /* | 1300 | /* |
@@ -1316,7 +1302,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1316 | * packet. If the STA went to power save mode, this will happen | 1302 | * packet. If the STA went to power save mode, this will happen |
1317 | * when it wakes up for the next time. | 1303 | * when it wakes up for the next time. |
1318 | */ | 1304 | */ |
1319 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1305 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
1320 | 1306 | ||
1321 | /* | 1307 | /* |
1322 | * This code races in the following way: | 1308 | * This code races in the following way: |
@@ -1348,84 +1334,89 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1348 | * can be unknown, for example with different interrupt status | 1334 | * can be unknown, for example with different interrupt status |
1349 | * bits. | 1335 | * bits. |
1350 | */ | 1336 | */ |
1351 | if (sta->flags & WLAN_STA_PS && | 1337 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1338 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1353 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1339 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1354 | &status->control); | ||
1355 | skb_queue_tail(&sta->tx_filtered, skb); | 1340 | skb_queue_tail(&sta->tx_filtered, skb); |
1356 | return; | 1341 | return; |
1357 | } | 1342 | } |
1358 | 1343 | ||
1359 | if (!(sta->flags & WLAN_STA_PS) && | 1344 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1345 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { |
1361 | /* Software retry the packet once */ | 1346 | /* Software retry the packet once */ |
1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1347 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
1363 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1348 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1364 | &status->control); | ||
1365 | dev_queue_xmit(skb); | 1349 | dev_queue_xmit(skb); |
1366 | return; | 1350 | return; |
1367 | } | 1351 | } |
1368 | 1352 | ||
1353 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1369 | if (net_ratelimit()) | 1354 | if (net_ratelimit()) |
1370 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 1355 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
1371 | "queue_len=%d PS=%d @%lu\n", | 1356 | "queue_len=%d PS=%d @%lu\n", |
1372 | wiphy_name(local->hw.wiphy), | 1357 | wiphy_name(local->hw.wiphy), |
1373 | skb_queue_len(&sta->tx_filtered), | 1358 | skb_queue_len(&sta->tx_filtered), |
1374 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1359 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1360 | #endif | ||
1375 | dev_kfree_skb(skb); | 1361 | dev_kfree_skb(skb); |
1376 | } | 1362 | } |
1377 | 1363 | ||
1378 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1364 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
1379 | struct ieee80211_tx_status *status) | ||
1380 | { | 1365 | { |
1381 | struct sk_buff *skb2; | 1366 | struct sk_buff *skb2; |
1382 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1367 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1383 | struct ieee80211_local *local = hw_to_local(hw); | 1368 | struct ieee80211_local *local = hw_to_local(hw); |
1369 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1384 | u16 frag, type; | 1370 | u16 frag, type; |
1371 | __le16 fc; | ||
1385 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1372 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
1386 | struct ieee80211_sub_if_data *sdata; | 1373 | struct ieee80211_sub_if_data *sdata; |
1387 | struct net_device *prev_dev = NULL; | 1374 | struct net_device *prev_dev = NULL; |
1388 | 1375 | struct sta_info *sta; | |
1389 | if (!status) { | ||
1390 | printk(KERN_ERR | ||
1391 | "%s: ieee80211_tx_status called with NULL status\n", | ||
1392 | wiphy_name(local->hw.wiphy)); | ||
1393 | dev_kfree_skb(skb); | ||
1394 | return; | ||
1395 | } | ||
1396 | 1376 | ||
1397 | rcu_read_lock(); | 1377 | rcu_read_lock(); |
1398 | 1378 | ||
1399 | if (status->excessive_retries) { | 1379 | if (info->status.excessive_retries) { |
1400 | struct sta_info *sta; | ||
1401 | sta = sta_info_get(local, hdr->addr1); | 1380 | sta = sta_info_get(local, hdr->addr1); |
1402 | if (sta) { | 1381 | if (sta) { |
1403 | if (sta->flags & WLAN_STA_PS) { | 1382 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
1404 | /* | 1383 | /* |
1405 | * The STA is in power save mode, so assume | 1384 | * The STA is in power save mode, so assume |
1406 | * that this TX packet failed because of that. | 1385 | * that this TX packet failed because of that. |
1407 | */ | 1386 | */ |
1408 | status->excessive_retries = 0; | 1387 | ieee80211_handle_filtered_frame(local, sta, skb); |
1409 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | ||
1410 | ieee80211_handle_filtered_frame(local, sta, | ||
1411 | skb, status); | ||
1412 | rcu_read_unlock(); | 1388 | rcu_read_unlock(); |
1413 | return; | 1389 | return; |
1414 | } | 1390 | } |
1415 | } | 1391 | } |
1416 | } | 1392 | } |
1417 | 1393 | ||
1418 | if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { | 1394 | fc = hdr->frame_control; |
1419 | struct sta_info *sta; | 1395 | |
1396 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
1397 | (ieee80211_is_data_qos(fc))) { | ||
1398 | u16 tid, ssn; | ||
1399 | u8 *qc; | ||
1420 | sta = sta_info_get(local, hdr->addr1); | 1400 | sta = sta_info_get(local, hdr->addr1); |
1421 | if (sta) { | 1401 | if (sta) { |
1422 | ieee80211_handle_filtered_frame(local, sta, skb, | 1402 | qc = ieee80211_get_qos_ctl(hdr); |
1423 | status); | 1403 | tid = qc[0] & 0xf; |
1404 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | ||
1405 | & IEEE80211_SCTL_SEQ); | ||
1406 | ieee80211_send_bar(sta->sdata->dev, hdr->addr1, | ||
1407 | tid, ssn); | ||
1408 | } | ||
1409 | } | ||
1410 | |||
1411 | 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); | ||
1424 | rcu_read_unlock(); | 1415 | rcu_read_unlock(); |
1425 | return; | 1416 | return; |
1426 | } | 1417 | } |
1427 | } else | 1418 | } else |
1428 | rate_control_tx_status(local->mdev, skb, status); | 1419 | rate_control_tx_status(local->mdev, skb); |
1429 | 1420 | ||
1430 | rcu_read_unlock(); | 1421 | rcu_read_unlock(); |
1431 | 1422 | ||
@@ -1439,14 +1430,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1439 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 1430 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
1440 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | 1431 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; |
1441 | 1432 | ||
1442 | if (status->flags & IEEE80211_TX_STATUS_ACK) { | 1433 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
1443 | if (frag == 0) { | 1434 | if (frag == 0) { |
1444 | local->dot11TransmittedFrameCount++; | 1435 | local->dot11TransmittedFrameCount++; |
1445 | if (is_multicast_ether_addr(hdr->addr1)) | 1436 | if (is_multicast_ether_addr(hdr->addr1)) |
1446 | local->dot11MulticastTransmittedFrameCount++; | 1437 | local->dot11MulticastTransmittedFrameCount++; |
1447 | if (status->retry_count > 0) | 1438 | if (info->status.retry_count > 0) |
1448 | local->dot11RetryCount++; | 1439 | local->dot11RetryCount++; |
1449 | if (status->retry_count > 1) | 1440 | if (info->status.retry_count > 1) |
1450 | local->dot11MultipleRetryCount++; | 1441 | local->dot11MultipleRetryCount++; |
1451 | } | 1442 | } |
1452 | 1443 | ||
@@ -1483,7 +1474,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1483 | return; | 1474 | return; |
1484 | } | 1475 | } |
1485 | 1476 | ||
1486 | rthdr = (struct ieee80211_tx_status_rtap_hdr*) | 1477 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) |
1487 | skb_push(skb, sizeof(*rthdr)); | 1478 | skb_push(skb, sizeof(*rthdr)); |
1488 | 1479 | ||
1489 | memset(rthdr, 0, sizeof(*rthdr)); | 1480 | memset(rthdr, 0, sizeof(*rthdr)); |
@@ -1492,17 +1483,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1492 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 1483 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
1493 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 1484 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); |
1494 | 1485 | ||
1495 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | 1486 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
1496 | !is_multicast_ether_addr(hdr->addr1)) | 1487 | !is_multicast_ether_addr(hdr->addr1)) |
1497 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 1488 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
1498 | 1489 | ||
1499 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | 1490 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && |
1500 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | 1491 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) |
1501 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 1492 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
1502 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1493 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1503 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 1494 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
1504 | 1495 | ||
1505 | rthdr->data_retries = status->retry_count; | 1496 | rthdr->data_retries = info->status.retry_count; |
1506 | 1497 | ||
1507 | /* XXX: is this sufficient for BPF? */ | 1498 | /* XXX: is this sufficient for BPF? */ |
1508 | skb_set_mac_header(skb, 0); | 1499 | skb_set_mac_header(skb, 0); |
@@ -1628,7 +1619,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1628 | int result; | 1619 | int result; |
1629 | enum ieee80211_band band; | 1620 | enum ieee80211_band band; |
1630 | struct net_device *mdev; | 1621 | struct net_device *mdev; |
1631 | struct ieee80211_sub_if_data *sdata; | 1622 | struct wireless_dev *mwdev; |
1632 | 1623 | ||
1633 | /* | 1624 | /* |
1634 | * generic code guarantees at least one band, | 1625 | * generic code guarantees at least one band, |
@@ -1652,19 +1643,30 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1652 | if (result < 0) | 1643 | if (result < 0) |
1653 | return result; | 1644 | return result; |
1654 | 1645 | ||
1655 | /* for now, mdev needs sub_if_data :/ */ | 1646 | /* |
1656 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | 1647 | * We use the number of queues for feature tests (QoS, HT) internally |
1657 | "wmaster%d", ether_setup); | 1648 | * so restrict them appropriately. |
1649 | */ | ||
1650 | if (hw->queues > IEEE80211_MAX_QUEUES) | ||
1651 | hw->queues = IEEE80211_MAX_QUEUES; | ||
1652 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) | ||
1653 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; | ||
1654 | if (hw->queues < 4) | ||
1655 | hw->ampdu_queues = 0; | ||
1656 | |||
1657 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), | ||
1658 | "wmaster%d", ether_setup, | ||
1659 | ieee80211_num_queues(hw)); | ||
1658 | if (!mdev) | 1660 | if (!mdev) |
1659 | goto fail_mdev_alloc; | 1661 | goto fail_mdev_alloc; |
1660 | 1662 | ||
1661 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | 1663 | mwdev = netdev_priv(mdev); |
1662 | mdev->ieee80211_ptr = &sdata->wdev; | 1664 | mdev->ieee80211_ptr = mwdev; |
1663 | sdata->wdev.wiphy = local->hw.wiphy; | 1665 | mwdev->wiphy = local->hw.wiphy; |
1664 | 1666 | ||
1665 | local->mdev = mdev; | 1667 | local->mdev = mdev; |
1666 | 1668 | ||
1667 | ieee80211_rx_bss_list_init(mdev); | 1669 | ieee80211_rx_bss_list_init(local); |
1668 | 1670 | ||
1669 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | 1671 | mdev->hard_start_xmit = ieee80211_master_start_xmit; |
1670 | mdev->open = ieee80211_master_open; | 1672 | mdev->open = ieee80211_master_open; |
@@ -1673,18 +1675,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1673 | mdev->header_ops = &ieee80211_header_ops; | 1675 | mdev->header_ops = &ieee80211_header_ops; |
1674 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 1676 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
1675 | 1677 | ||
1676 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1677 | sdata->dev = mdev; | ||
1678 | sdata->local = local; | ||
1679 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1680 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1681 | ieee80211_if_sdata_init(sdata); | ||
1682 | |||
1683 | /* no RCU needed since we're still during init phase */ | ||
1684 | list_add_tail(&sdata->list, &local->interfaces); | ||
1685 | |||
1686 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1678 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
1687 | local->hw.workqueue = create_singlethread_workqueue(name); | 1679 | local->hw.workqueue = create_freezeable_workqueue(name); |
1688 | if (!local->hw.workqueue) { | 1680 | if (!local->hw.workqueue) { |
1689 | result = -ENOMEM; | 1681 | result = -ENOMEM; |
1690 | goto fail_workqueue; | 1682 | goto fail_workqueue; |
@@ -1700,15 +1692,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1700 | 1692 | ||
1701 | debugfs_hw_add(local); | 1693 | debugfs_hw_add(local); |
1702 | 1694 | ||
1703 | local->hw.conf.beacon_int = 1000; | 1695 | if (local->hw.conf.beacon_int < 10) |
1696 | local->hw.conf.beacon_int = 100; | ||
1704 | 1697 | ||
1705 | local->wstats_flags |= local->hw.max_rssi ? | 1698 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1706 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1699 | IEEE80211_HW_SIGNAL_DB | |
1707 | local->wstats_flags |= local->hw.max_signal ? | 1700 | IEEE80211_HW_SIGNAL_DBM) ? |
1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1701 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
1709 | local->wstats_flags |= local->hw.max_noise ? | 1702 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1703 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
1711 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1704 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
1712 | local->wstats_flags |= IW_QUAL_DBM; | 1705 | local->wstats_flags |= IW_QUAL_DBM; |
1713 | 1706 | ||
1714 | result = sta_info_start(local); | 1707 | result = sta_info_start(local); |
@@ -1727,9 +1720,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1727 | if (result < 0) | 1720 | if (result < 0) |
1728 | goto fail_dev; | 1721 | goto fail_dev; |
1729 | 1722 | ||
1730 | ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
1731 | ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); | ||
1732 | |||
1733 | result = ieee80211_init_rate_ctrl_alg(local, | 1723 | result = ieee80211_init_rate_ctrl_alg(local, |
1734 | hw->rate_control_algorithm); | 1724 | hw->rate_control_algorithm); |
1735 | if (result < 0) { | 1725 | if (result < 0) { |
@@ -1746,16 +1736,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1746 | goto fail_wep; | 1736 | goto fail_wep; |
1747 | } | 1737 | } |
1748 | 1738 | ||
1749 | ieee80211_install_qdisc(local->mdev); | 1739 | local->mdev->select_queue = ieee80211_select_queue; |
1750 | 1740 | ||
1751 | /* add one default STA interface */ | 1741 | /* add one default STA interface */ |
1752 | result = ieee80211_if_add(local->mdev, "wlan%d", NULL, | 1742 | result = ieee80211_if_add(local, "wlan%d", NULL, |
1753 | IEEE80211_IF_TYPE_STA, NULL); | 1743 | IEEE80211_IF_TYPE_STA, NULL); |
1754 | if (result) | 1744 | if (result) |
1755 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 1745 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
1756 | wiphy_name(local->hw.wiphy)); | 1746 | wiphy_name(local->hw.wiphy)); |
1757 | 1747 | ||
1758 | local->reg_state = IEEE80211_DEV_REGISTERED; | ||
1759 | rtnl_unlock(); | 1748 | rtnl_unlock(); |
1760 | 1749 | ||
1761 | ieee80211_led_init(local); | 1750 | ieee80211_led_init(local); |
@@ -1765,7 +1754,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1765 | fail_wep: | 1754 | fail_wep: |
1766 | rate_control_deinitialize(local); | 1755 | rate_control_deinitialize(local); |
1767 | fail_rate: | 1756 | fail_rate: |
1768 | ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
1769 | unregister_netdevice(local->mdev); | 1757 | unregister_netdevice(local->mdev); |
1770 | local->mdev = NULL; | 1758 | local->mdev = NULL; |
1771 | fail_dev: | 1759 | fail_dev: |
@@ -1775,10 +1763,8 @@ fail_sta_info: | |||
1775 | debugfs_hw_del(local); | 1763 | debugfs_hw_del(local); |
1776 | destroy_workqueue(local->hw.workqueue); | 1764 | destroy_workqueue(local->hw.workqueue); |
1777 | fail_workqueue: | 1765 | fail_workqueue: |
1778 | if (local->mdev != NULL) { | 1766 | if (local->mdev) |
1779 | ieee80211_if_free(local->mdev); | 1767 | free_netdev(local->mdev); |
1780 | local->mdev = NULL; | ||
1781 | } | ||
1782 | fail_mdev_alloc: | 1768 | fail_mdev_alloc: |
1783 | wiphy_unregister(local->hw.wiphy); | 1769 | wiphy_unregister(local->hw.wiphy); |
1784 | return result; | 1770 | return result; |
@@ -1788,42 +1774,27 @@ EXPORT_SYMBOL(ieee80211_register_hw); | |||
1788 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1774 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1789 | { | 1775 | { |
1790 | struct ieee80211_local *local = hw_to_local(hw); | 1776 | struct ieee80211_local *local = hw_to_local(hw); |
1791 | struct ieee80211_sub_if_data *sdata, *tmp; | ||
1792 | 1777 | ||
1793 | tasklet_kill(&local->tx_pending_tasklet); | 1778 | tasklet_kill(&local->tx_pending_tasklet); |
1794 | tasklet_kill(&local->tasklet); | 1779 | tasklet_kill(&local->tasklet); |
1795 | 1780 | ||
1796 | rtnl_lock(); | 1781 | rtnl_lock(); |
1797 | 1782 | ||
1798 | BUG_ON(local->reg_state != IEEE80211_DEV_REGISTERED); | ||
1799 | |||
1800 | local->reg_state = IEEE80211_DEV_UNREGISTERED; | ||
1801 | |||
1802 | /* | 1783 | /* |
1803 | * At this point, interface list manipulations are fine | 1784 | * At this point, interface list manipulations are fine |
1804 | * because the driver cannot be handing us frames any | 1785 | * because the driver cannot be handing us frames any |
1805 | * more and the tasklet is killed. | 1786 | * more and the tasklet is killed. |
1806 | */ | 1787 | */ |
1807 | 1788 | ||
1808 | /* | 1789 | /* First, we remove all virtual interfaces. */ |
1809 | * First, we remove all non-master interfaces. Do this because they | 1790 | ieee80211_remove_interfaces(local); |
1810 | * may have bss pointer dependency on the master, and when we free | ||
1811 | * the master these would be freed as well, breaking our list | ||
1812 | * iteration completely. | ||
1813 | */ | ||
1814 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | ||
1815 | if (sdata->dev == local->mdev) | ||
1816 | continue; | ||
1817 | list_del(&sdata->list); | ||
1818 | __ieee80211_if_del(local, sdata); | ||
1819 | } | ||
1820 | 1791 | ||
1821 | /* then, finally, remove the master interface */ | 1792 | /* then, finally, remove the master interface */ |
1822 | __ieee80211_if_del(local, IEEE80211_DEV_TO_SUB_IF(local->mdev)); | 1793 | unregister_netdevice(local->mdev); |
1823 | 1794 | ||
1824 | rtnl_unlock(); | 1795 | rtnl_unlock(); |
1825 | 1796 | ||
1826 | ieee80211_rx_bss_list_deinit(local->mdev); | 1797 | ieee80211_rx_bss_list_deinit(local); |
1827 | ieee80211_clear_tx_pending(local); | 1798 | ieee80211_clear_tx_pending(local); |
1828 | sta_info_stop(local); | 1799 | sta_info_stop(local); |
1829 | rate_control_deinitialize(local); | 1800 | rate_control_deinitialize(local); |
@@ -1840,8 +1811,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1840 | wiphy_unregister(local->hw.wiphy); | 1811 | wiphy_unregister(local->hw.wiphy); |
1841 | ieee80211_wep_free(local); | 1812 | ieee80211_wep_free(local); |
1842 | ieee80211_led_exit(local); | 1813 | ieee80211_led_exit(local); |
1843 | ieee80211_if_free(local->mdev); | 1814 | free_netdev(local->mdev); |
1844 | local->mdev = NULL; | ||
1845 | } | 1815 | } |
1846 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1816 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1847 | 1817 | ||
@@ -1858,27 +1828,17 @@ static int __init ieee80211_init(void) | |||
1858 | struct sk_buff *skb; | 1828 | struct sk_buff *skb; |
1859 | int ret; | 1829 | int ret; |
1860 | 1830 | ||
1861 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1831 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1832 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | ||
1833 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | ||
1862 | 1834 | ||
1863 | ret = rc80211_pid_init(); | 1835 | ret = rc80211_pid_init(); |
1864 | if (ret) | 1836 | if (ret) |
1865 | goto out; | 1837 | return ret; |
1866 | |||
1867 | ret = ieee80211_wme_register(); | ||
1868 | if (ret) { | ||
1869 | printk(KERN_DEBUG "ieee80211_init: failed to " | ||
1870 | "initialize WME (err=%d)\n", ret); | ||
1871 | goto out_cleanup_pid; | ||
1872 | } | ||
1873 | 1838 | ||
1874 | ieee80211_debugfs_netdev_init(); | 1839 | ieee80211_debugfs_netdev_init(); |
1875 | 1840 | ||
1876 | return 0; | 1841 | return 0; |
1877 | |||
1878 | out_cleanup_pid: | ||
1879 | rc80211_pid_exit(); | ||
1880 | out: | ||
1881 | return ret; | ||
1882 | } | 1842 | } |
1883 | 1843 | ||
1884 | static void __exit ieee80211_exit(void) | 1844 | static void __exit ieee80211_exit(void) |
@@ -1894,7 +1854,6 @@ static void __exit ieee80211_exit(void) | |||
1894 | if (mesh_allocated) | 1854 | if (mesh_allocated) |
1895 | ieee80211s_stop(); | 1855 | ieee80211s_stop(); |
1896 | 1856 | ||
1897 | ieee80211_wme_unregister(); | ||
1898 | ieee80211_debugfs_netdev_exit(); | 1857 | ieee80211_debugfs_netdev_exit(); |
1899 | } | 1858 | } |
1900 | 1859 | ||