diff options
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r-- | net/mac80211/ieee80211.c | 984 |
1 files changed, 726 insertions, 258 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 28bcdf9fc3df..8c0f782d21e3 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include "ieee80211_i.h" | 27 | #include "ieee80211_i.h" |
28 | #include "ieee80211_rate.h" | 28 | #include "ieee80211_rate.h" |
29 | #include "mesh.h" | ||
29 | #include "wep.h" | 30 | #include "wep.h" |
30 | #include "wme.h" | 31 | #include "wme.h" |
31 | #include "aes_ccm.h" | 32 | #include "aes_ccm.h" |
@@ -67,9 +68,19 @@ static void ieee80211_configure_filter(struct ieee80211_local *local) | |||
67 | new_flags |= FIF_ALLMULTI; | 68 | new_flags |= FIF_ALLMULTI; |
68 | 69 | ||
69 | if (local->monitors) | 70 | if (local->monitors) |
70 | new_flags |= FIF_CONTROL | | 71 | new_flags |= FIF_BCN_PRBRESP_PROMISC; |
71 | FIF_OTHER_BSS | | 72 | |
72 | FIF_BCN_PRBRESP_PROMISC; | 73 | if (local->fif_fcsfail) |
74 | new_flags |= FIF_FCSFAIL; | ||
75 | |||
76 | if (local->fif_plcpfail) | ||
77 | new_flags |= FIF_PLCPFAIL; | ||
78 | |||
79 | if (local->fif_control) | ||
80 | new_flags |= FIF_CONTROL; | ||
81 | |||
82 | if (local->fif_other_bss) | ||
83 | new_flags |= FIF_OTHER_BSS; | ||
73 | 84 | ||
74 | changed_flags = local->filter_flags ^ new_flags; | 85 | changed_flags = local->filter_flags ^ new_flags; |
75 | 86 | ||
@@ -128,9 +139,15 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev) | |||
128 | 139 | ||
129 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | 140 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) |
130 | { | 141 | { |
142 | int meshhdrlen; | ||
143 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
144 | |||
145 | meshhdrlen = (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) ? 5 : 0; | ||
146 | |||
131 | /* FIX: what would be proper limits for MTU? | 147 | /* FIX: what would be proper limits for MTU? |
132 | * This interface uses 802.3 frames. */ | 148 | * This interface uses 802.3 frames. */ |
133 | if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6) { | 149 | if (new_mtu < 256 || |
150 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | ||
134 | printk(KERN_WARNING "%s: invalid MTU %d\n", | 151 | printk(KERN_WARNING "%s: invalid MTU %d\n", |
135 | dev->name, new_mtu); | 152 | dev->name, new_mtu); |
136 | return -EINVAL; | 153 | return -EINVAL; |
@@ -166,6 +183,7 @@ static int ieee80211_open(struct net_device *dev) | |||
166 | struct ieee80211_if_init_conf conf; | 183 | struct ieee80211_if_init_conf conf; |
167 | int res; | 184 | int res; |
168 | bool need_hw_reconfig = 0; | 185 | bool need_hw_reconfig = 0; |
186 | struct sta_info *sta; | ||
169 | 187 | ||
170 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 188 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
171 | 189 | ||
@@ -173,8 +191,52 @@ static int ieee80211_open(struct net_device *dev) | |||
173 | list_for_each_entry(nsdata, &local->interfaces, list) { | 191 | list_for_each_entry(nsdata, &local->interfaces, list) { |
174 | struct net_device *ndev = nsdata->dev; | 192 | struct net_device *ndev = nsdata->dev; |
175 | 193 | ||
176 | if (ndev != dev && ndev != local->mdev && netif_running(ndev) && | 194 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { |
177 | compare_ether_addr(dev->dev_addr, ndev->dev_addr) == 0) { | 195 | /* |
196 | * Allow only a single IBSS interface to be up at any | ||
197 | * time. This is restricted because beacon distribution | ||
198 | * cannot work properly if both are in the same IBSS. | ||
199 | * | ||
200 | * To remove this restriction we'd have to disallow them | ||
201 | * from setting the same SSID on different IBSS interfaces | ||
202 | * belonging to the same hardware. Then, however, we're | ||
203 | * faced with having to adopt two different TSF timers... | ||
204 | */ | ||
205 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | ||
206 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS) | ||
207 | return -EBUSY; | ||
208 | |||
209 | /* | ||
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 | ||
235 | * with the same MAC address. | ||
236 | */ | ||
237 | if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) | ||
238 | continue; | ||
239 | |||
178 | /* | 240 | /* |
179 | * check whether it may have the same address | 241 | * check whether it may have the same address |
180 | */ | 242 | */ |
@@ -186,8 +248,7 @@ static int ieee80211_open(struct net_device *dev) | |||
186 | * can only add VLANs to enabled APs | 248 | * can only add VLANs to enabled APs |
187 | */ | 249 | */ |
188 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 250 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
189 | nsdata->vif.type == IEEE80211_IF_TYPE_AP && | 251 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
190 | netif_running(nsdata->dev)) | ||
191 | sdata->u.vlan.ap = nsdata; | 252 | sdata->u.vlan.ap = nsdata; |
192 | } | 253 | } |
193 | } | 254 | } |
@@ -196,6 +257,20 @@ static int ieee80211_open(struct net_device *dev) | |||
196 | case IEEE80211_IF_TYPE_WDS: | 257 | case IEEE80211_IF_TYPE_WDS: |
197 | if (is_zero_ether_addr(sdata->u.wds.remote_addr)) | 258 | if (is_zero_ether_addr(sdata->u.wds.remote_addr)) |
198 | return -ENOLINK; | 259 | return -ENOLINK; |
260 | |||
261 | /* Create STA entry for the WDS peer */ | ||
262 | sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, | ||
263 | GFP_KERNEL); | ||
264 | if (!sta) | ||
265 | return -ENOMEM; | ||
266 | |||
267 | sta->flags |= WLAN_STA_AUTHORIZED; | ||
268 | |||
269 | res = sta_info_insert(sta); | ||
270 | if (res) { | ||
271 | sta_info_destroy(sta); | ||
272 | return res; | ||
273 | } | ||
199 | break; | 274 | break; |
200 | case IEEE80211_IF_TYPE_VLAN: | 275 | case IEEE80211_IF_TYPE_VLAN: |
201 | if (!sdata->u.vlan.ap) | 276 | if (!sdata->u.vlan.ap) |
@@ -205,6 +280,7 @@ static int ieee80211_open(struct net_device *dev) | |||
205 | case IEEE80211_IF_TYPE_STA: | 280 | case IEEE80211_IF_TYPE_STA: |
206 | case IEEE80211_IF_TYPE_MNTR: | 281 | case IEEE80211_IF_TYPE_MNTR: |
207 | case IEEE80211_IF_TYPE_IBSS: | 282 | case IEEE80211_IF_TYPE_IBSS: |
283 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
208 | /* no special treatment */ | 284 | /* no special treatment */ |
209 | break; | 285 | break; |
210 | case IEEE80211_IF_TYPE_INVALID: | 286 | case IEEE80211_IF_TYPE_INVALID: |
@@ -229,15 +305,28 @@ static int ieee80211_open(struct net_device *dev) | |||
229 | /* no need to tell driver */ | 305 | /* no need to tell driver */ |
230 | break; | 306 | break; |
231 | case IEEE80211_IF_TYPE_MNTR: | 307 | case IEEE80211_IF_TYPE_MNTR: |
308 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
309 | local->cooked_mntrs++; | ||
310 | break; | ||
311 | } | ||
312 | |||
232 | /* must be before the call to ieee80211_configure_filter */ | 313 | /* must be before the call to ieee80211_configure_filter */ |
233 | local->monitors++; | 314 | local->monitors++; |
234 | if (local->monitors == 1) { | 315 | if (local->monitors == 1) |
235 | netif_tx_lock_bh(local->mdev); | ||
236 | ieee80211_configure_filter(local); | ||
237 | netif_tx_unlock_bh(local->mdev); | ||
238 | |||
239 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 316 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; |
240 | } | 317 | |
318 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
319 | local->fif_fcsfail++; | ||
320 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
321 | local->fif_plcpfail++; | ||
322 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
323 | local->fif_control++; | ||
324 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
325 | local->fif_other_bss++; | ||
326 | |||
327 | netif_tx_lock_bh(local->mdev); | ||
328 | ieee80211_configure_filter(local); | ||
329 | netif_tx_unlock_bh(local->mdev); | ||
241 | break; | 330 | break; |
242 | case IEEE80211_IF_TYPE_STA: | 331 | case IEEE80211_IF_TYPE_STA: |
243 | case IEEE80211_IF_TYPE_IBSS: | 332 | case IEEE80211_IF_TYPE_IBSS: |
@@ -293,24 +382,46 @@ static int ieee80211_open(struct net_device *dev) | |||
293 | 382 | ||
294 | static int ieee80211_stop(struct net_device *dev) | 383 | static int ieee80211_stop(struct net_device *dev) |
295 | { | 384 | { |
296 | struct ieee80211_sub_if_data *sdata; | 385 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
297 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 386 | struct ieee80211_local *local = sdata->local; |
298 | struct ieee80211_if_init_conf conf; | 387 | struct ieee80211_if_init_conf conf; |
299 | struct sta_info *sta; | 388 | struct sta_info *sta; |
300 | int i; | ||
301 | 389 | ||
302 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 390 | /* |
391 | * Stop TX on this interface first. | ||
392 | */ | ||
393 | netif_stop_queue(dev); | ||
303 | 394 | ||
304 | list_for_each_entry(sta, &local->sta_list, list) { | 395 | /* |
305 | if (sta->dev == dev) | 396 | * Now delete all active aggregation sessions. |
306 | for (i = 0; i < STA_TID_NUM; i++) | 397 | */ |
307 | ieee80211_sta_stop_rx_ba_session(sta->dev, | 398 | rcu_read_lock(); |
308 | sta->addr, i, | 399 | |
309 | WLAN_BACK_RECIPIENT, | 400 | list_for_each_entry_rcu(sta, &local->sta_list, list) { |
310 | WLAN_REASON_QSTA_LEAVE_QBSS); | 401 | if (sta->sdata == sdata) |
402 | ieee80211_sta_tear_down_BA_sessions(dev, sta->addr); | ||
311 | } | 403 | } |
312 | 404 | ||
313 | netif_stop_queue(dev); | 405 | rcu_read_unlock(); |
406 | |||
407 | /* | ||
408 | * Remove all stations associated with this interface. | ||
409 | * | ||
410 | * This must be done before calling ops->remove_interface() | ||
411 | * because otherwise we can later invoke ops->sta_notify() | ||
412 | * whenever the STAs are removed, and that invalidates driver | ||
413 | * assumptions about always getting a vif pointer that is valid | ||
414 | * (because if we remove a STA after ops->remove_interface() | ||
415 | * the driver will have removed the vif info already!) | ||
416 | * | ||
417 | * We could relax this and only unlink the stations from the | ||
418 | * hash table and list but keep them on a per-sdata list that | ||
419 | * will be inserted back again when the interface is brought | ||
420 | * up again, but I don't currently see a use case for that, | ||
421 | * except with WDS which gets a STA entry created when it is | ||
422 | * brought up. | ||
423 | */ | ||
424 | sta_info_flush(local, sdata); | ||
314 | 425 | ||
315 | /* | 426 | /* |
316 | * Don't count this interface for promisc/allmulti while it | 427 | * Don't count this interface for promisc/allmulti while it |
@@ -352,15 +463,29 @@ static int ieee80211_stop(struct net_device *dev) | |||
352 | /* no need to tell driver */ | 463 | /* no need to tell driver */ |
353 | break; | 464 | break; |
354 | case IEEE80211_IF_TYPE_MNTR: | 465 | case IEEE80211_IF_TYPE_MNTR: |
355 | local->monitors--; | 466 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { |
356 | if (local->monitors == 0) { | 467 | local->cooked_mntrs--; |
357 | netif_tx_lock_bh(local->mdev); | 468 | break; |
358 | ieee80211_configure_filter(local); | 469 | } |
359 | netif_tx_unlock_bh(local->mdev); | ||
360 | 470 | ||
471 | local->monitors--; | ||
472 | if (local->monitors == 0) | ||
361 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 473 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; |
362 | } | 474 | |
475 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
476 | local->fif_fcsfail--; | ||
477 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
478 | local->fif_plcpfail--; | ||
479 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
480 | local->fif_control--; | ||
481 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
482 | local->fif_other_bss--; | ||
483 | |||
484 | netif_tx_lock_bh(local->mdev); | ||
485 | ieee80211_configure_filter(local); | ||
486 | netif_tx_unlock_bh(local->mdev); | ||
363 | break; | 487 | break; |
488 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
364 | case IEEE80211_IF_TYPE_STA: | 489 | case IEEE80211_IF_TYPE_STA: |
365 | case IEEE80211_IF_TYPE_IBSS: | 490 | case IEEE80211_IF_TYPE_IBSS: |
366 | sdata->u.sta.state = IEEE80211_DISABLED; | 491 | sdata->u.sta.state = IEEE80211_DISABLED; |
@@ -414,6 +539,359 @@ static int ieee80211_stop(struct net_device *dev) | |||
414 | return 0; | 539 | return 0; |
415 | } | 540 | } |
416 | 541 | ||
542 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
543 | { | ||
544 | struct ieee80211_local *local = hw_to_local(hw); | ||
545 | struct sta_info *sta; | ||
546 | struct ieee80211_sub_if_data *sdata; | ||
547 | u16 start_seq_num = 0; | ||
548 | u8 *state; | ||
549 | int ret; | ||
550 | DECLARE_MAC_BUF(mac); | ||
551 | |||
552 | if (tid >= STA_TID_NUM) | ||
553 | return -EINVAL; | ||
554 | |||
555 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
556 | printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", | ||
557 | print_mac(mac, ra), tid); | ||
558 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
559 | |||
560 | rcu_read_lock(); | ||
561 | |||
562 | sta = sta_info_get(local, ra); | ||
563 | if (!sta) { | ||
564 | printk(KERN_DEBUG "Could not find the station\n"); | ||
565 | rcu_read_unlock(); | ||
566 | return -ENOENT; | ||
567 | } | ||
568 | |||
569 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
570 | |||
571 | /* we have tried too many times, receiver does not want A-MPDU */ | ||
572 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | ||
573 | ret = -EBUSY; | ||
574 | goto start_ba_exit; | ||
575 | } | ||
576 | |||
577 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
578 | /* check if the TID is not in aggregation flow already */ | ||
579 | if (*state != HT_AGG_STATE_IDLE) { | ||
580 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
581 | printk(KERN_DEBUG "BA request denied - session is not " | ||
582 | "idle on tid %u\n", tid); | ||
583 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
584 | ret = -EAGAIN; | ||
585 | goto start_ba_exit; | ||
586 | } | ||
587 | |||
588 | /* prepare A-MPDU MLME for Tx aggregation */ | ||
589 | sta->ampdu_mlme.tid_tx[tid] = | ||
590 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | ||
591 | if (!sta->ampdu_mlme.tid_tx[tid]) { | ||
592 | if (net_ratelimit()) | ||
593 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | ||
594 | tid); | ||
595 | ret = -ENOMEM; | ||
596 | goto start_ba_exit; | ||
597 | } | ||
598 | /* Tx timer */ | ||
599 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | ||
600 | sta_addba_resp_timer_expired; | ||
601 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data = | ||
602 | (unsigned long)&sta->timer_to_tid[tid]; | ||
603 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
604 | |||
605 | /* ensure that TX flow won't interrupt us | ||
606 | * until the end of the call to requeue function */ | ||
607 | spin_lock_bh(&local->mdev->queue_lock); | ||
608 | |||
609 | /* create a new queue for this aggregation */ | ||
610 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | ||
611 | |||
612 | /* case no queue is available to aggregation | ||
613 | * don't switch to aggregation */ | ||
614 | if (ret) { | ||
615 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
616 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | ||
617 | " tid %d\n", tid); | ||
618 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
619 | goto start_ba_err; | ||
620 | } | ||
621 | sdata = sta->sdata; | ||
622 | |||
623 | /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the | ||
624 | * call back right away, it must see that the flow has begun */ | ||
625 | *state |= HT_ADDBA_REQUESTED_MSK; | ||
626 | |||
627 | if (local->ops->ampdu_action) | ||
628 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, | ||
629 | ra, tid, &start_seq_num); | ||
630 | |||
631 | if (ret) { | ||
632 | /* No need to requeue the packets in the agg queue, since we | ||
633 | * held the tx lock: no packet could be enqueued to the newly | ||
634 | * allocated queue */ | ||
635 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | ||
636 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
637 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | ||
638 | " tid %d\n", tid); | ||
639 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
640 | *state = HT_AGG_STATE_IDLE; | ||
641 | goto start_ba_err; | ||
642 | } | ||
643 | |||
644 | /* Will put all the packets in the new SW queue */ | ||
645 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | ||
646 | spin_unlock_bh(&local->mdev->queue_lock); | ||
647 | |||
648 | /* send an addBA request */ | ||
649 | sta->ampdu_mlme.dialog_token_allocator++; | ||
650 | sta->ampdu_mlme.tid_tx[tid]->dialog_token = | ||
651 | sta->ampdu_mlme.dialog_token_allocator; | ||
652 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | ||
653 | |||
654 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | ||
655 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | ||
656 | sta->ampdu_mlme.tid_tx[tid]->ssn, | ||
657 | 0x40, 5000); | ||
658 | |||
659 | /* activate the timer for the recipient's addBA response */ | ||
660 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | ||
661 | jiffies + ADDBA_RESP_INTERVAL; | ||
662 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
663 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | ||
664 | goto start_ba_exit; | ||
665 | |||
666 | start_ba_err: | ||
667 | kfree(sta->ampdu_mlme.tid_tx[tid]); | ||
668 | sta->ampdu_mlme.tid_tx[tid] = NULL; | ||
669 | spin_unlock_bh(&local->mdev->queue_lock); | ||
670 | ret = -EBUSY; | ||
671 | start_ba_exit: | ||
672 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
673 | rcu_read_unlock(); | ||
674 | return ret; | ||
675 | } | ||
676 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | ||
677 | |||
678 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | ||
679 | u8 *ra, u16 tid, | ||
680 | enum ieee80211_back_parties initiator) | ||
681 | { | ||
682 | struct ieee80211_local *local = hw_to_local(hw); | ||
683 | struct sta_info *sta; | ||
684 | u8 *state; | ||
685 | int ret = 0; | ||
686 | DECLARE_MAC_BUF(mac); | ||
687 | |||
688 | if (tid >= STA_TID_NUM) | ||
689 | return -EINVAL; | ||
690 | |||
691 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
692 | printk(KERN_DEBUG "Stop a BA session requested for %s tid %u\n", | ||
693 | print_mac(mac, ra), tid); | ||
694 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
695 | |||
696 | rcu_read_lock(); | ||
697 | sta = sta_info_get(local, ra); | ||
698 | if (!sta) { | ||
699 | rcu_read_unlock(); | ||
700 | return -ENOENT; | ||
701 | } | ||
702 | |||
703 | /* check if the TID is in aggregation */ | ||
704 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
705 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
706 | |||
707 | if (*state != HT_AGG_STATE_OPERATIONAL) { | ||
708 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
709 | printk(KERN_DEBUG "Try to stop Tx aggregation on" | ||
710 | " non active TID\n"); | ||
711 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
712 | ret = -ENOENT; | ||
713 | goto stop_BA_exit; | ||
714 | } | ||
715 | |||
716 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | ||
717 | |||
718 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | ||
719 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | ||
720 | |||
721 | if (local->ops->ampdu_action) | ||
722 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP, | ||
723 | ra, tid, NULL); | ||
724 | |||
725 | /* case HW denied going back to legacy */ | ||
726 | if (ret) { | ||
727 | WARN_ON(ret != -EBUSY); | ||
728 | *state = HT_AGG_STATE_OPERATIONAL; | ||
729 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
730 | goto stop_BA_exit; | ||
731 | } | ||
732 | |||
733 | stop_BA_exit: | ||
734 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
735 | rcu_read_unlock(); | ||
736 | return ret; | ||
737 | } | ||
738 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | ||
739 | |||
740 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
741 | { | ||
742 | struct ieee80211_local *local = hw_to_local(hw); | ||
743 | struct sta_info *sta; | ||
744 | u8 *state; | ||
745 | DECLARE_MAC_BUF(mac); | ||
746 | |||
747 | if (tid >= STA_TID_NUM) { | ||
748 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
749 | tid, STA_TID_NUM); | ||
750 | return; | ||
751 | } | ||
752 | |||
753 | rcu_read_lock(); | ||
754 | sta = sta_info_get(local, ra); | ||
755 | if (!sta) { | ||
756 | rcu_read_unlock(); | ||
757 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
758 | print_mac(mac, ra)); | ||
759 | return; | ||
760 | } | ||
761 | |||
762 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
763 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
764 | |||
765 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | ||
766 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | ||
767 | *state); | ||
768 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
769 | rcu_read_unlock(); | ||
770 | return; | ||
771 | } | ||
772 | |||
773 | WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK); | ||
774 | |||
775 | *state |= HT_ADDBA_DRV_READY_MSK; | ||
776 | |||
777 | if (*state == HT_AGG_STATE_OPERATIONAL) { | ||
778 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | ||
779 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
780 | } | ||
781 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
782 | rcu_read_unlock(); | ||
783 | } | ||
784 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | ||
785 | |||
786 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | ||
787 | { | ||
788 | struct ieee80211_local *local = hw_to_local(hw); | ||
789 | struct sta_info *sta; | ||
790 | u8 *state; | ||
791 | int agg_queue; | ||
792 | DECLARE_MAC_BUF(mac); | ||
793 | |||
794 | if (tid >= STA_TID_NUM) { | ||
795 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
796 | tid, STA_TID_NUM); | ||
797 | return; | ||
798 | } | ||
799 | |||
800 | printk(KERN_DEBUG "Stop a BA session requested on DA %s tid %d\n", | ||
801 | print_mac(mac, ra), tid); | ||
802 | |||
803 | rcu_read_lock(); | ||
804 | sta = sta_info_get(local, ra); | ||
805 | if (!sta) { | ||
806 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
807 | print_mac(mac, ra)); | ||
808 | rcu_read_unlock(); | ||
809 | return; | ||
810 | } | ||
811 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | ||
812 | |||
813 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
814 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | ||
815 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | ||
816 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
817 | rcu_read_unlock(); | ||
818 | return; | ||
819 | } | ||
820 | |||
821 | if (*state & HT_AGG_STATE_INITIATOR_MSK) | ||
822 | ieee80211_send_delba(sta->sdata->dev, ra, tid, | ||
823 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | ||
824 | |||
825 | agg_queue = sta->tid_to_tx_q[tid]; | ||
826 | |||
827 | /* avoid ordering issues: we are the only one that can modify | ||
828 | * the content of the qdiscs */ | ||
829 | spin_lock_bh(&local->mdev->queue_lock); | ||
830 | /* remove the queue for this aggregation */ | ||
831 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | ||
832 | spin_unlock_bh(&local->mdev->queue_lock); | ||
833 | |||
834 | /* we just requeued the all the frames that were in the removed | ||
835 | * queue, and since we might miss a softirq we do netif_schedule. | ||
836 | * ieee80211_wake_queue is not used here as this queue is not | ||
837 | * necessarily stopped */ | ||
838 | netif_schedule(local->mdev); | ||
839 | *state = HT_AGG_STATE_IDLE; | ||
840 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
841 | kfree(sta->ampdu_mlme.tid_tx[tid]); | ||
842 | sta->ampdu_mlme.tid_tx[tid] = NULL; | ||
843 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
844 | |||
845 | rcu_read_unlock(); | ||
846 | } | ||
847 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | ||
848 | |||
849 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
850 | const u8 *ra, u16 tid) | ||
851 | { | ||
852 | struct ieee80211_local *local = hw_to_local(hw); | ||
853 | struct ieee80211_ra_tid *ra_tid; | ||
854 | struct sk_buff *skb = dev_alloc_skb(0); | ||
855 | |||
856 | if (unlikely(!skb)) { | ||
857 | if (net_ratelimit()) | ||
858 | printk(KERN_WARNING "%s: Not enough memory, " | ||
859 | "dropping start BA session", skb->dev->name); | ||
860 | return; | ||
861 | } | ||
862 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
863 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
864 | ra_tid->tid = tid; | ||
865 | |||
866 | skb->pkt_type = IEEE80211_ADDBA_MSG; | ||
867 | skb_queue_tail(&local->skb_queue, skb); | ||
868 | tasklet_schedule(&local->tasklet); | ||
869 | } | ||
870 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | ||
871 | |||
872 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
873 | const u8 *ra, u16 tid) | ||
874 | { | ||
875 | struct ieee80211_local *local = hw_to_local(hw); | ||
876 | struct ieee80211_ra_tid *ra_tid; | ||
877 | struct sk_buff *skb = dev_alloc_skb(0); | ||
878 | |||
879 | if (unlikely(!skb)) { | ||
880 | if (net_ratelimit()) | ||
881 | printk(KERN_WARNING "%s: Not enough memory, " | ||
882 | "dropping stop BA session", skb->dev->name); | ||
883 | return; | ||
884 | } | ||
885 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
886 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
887 | ra_tid->tid = tid; | ||
888 | |||
889 | skb->pkt_type = IEEE80211_DELBA_MSG; | ||
890 | skb_queue_tail(&local->skb_queue, skb); | ||
891 | tasklet_schedule(&local->tasklet); | ||
892 | } | ||
893 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); | ||
894 | |||
417 | static void ieee80211_set_multicast_list(struct net_device *dev) | 895 | static void ieee80211_set_multicast_list(struct net_device *dev) |
418 | { | 896 | { |
419 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 897 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -465,41 +943,6 @@ void ieee80211_if_setup(struct net_device *dev) | |||
465 | dev->destructor = ieee80211_if_free; | 943 | dev->destructor = ieee80211_if_free; |
466 | } | 944 | } |
467 | 945 | ||
468 | /* WDS specialties */ | ||
469 | |||
470 | int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr) | ||
471 | { | ||
472 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
473 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
474 | struct sta_info *sta; | ||
475 | DECLARE_MAC_BUF(mac); | ||
476 | |||
477 | if (compare_ether_addr(remote_addr, sdata->u.wds.remote_addr) == 0) | ||
478 | return 0; | ||
479 | |||
480 | /* Create STA entry for the new peer */ | ||
481 | sta = sta_info_add(local, dev, remote_addr, GFP_KERNEL); | ||
482 | if (!sta) | ||
483 | return -ENOMEM; | ||
484 | sta_info_put(sta); | ||
485 | |||
486 | /* Remove STA entry for the old peer */ | ||
487 | sta = sta_info_get(local, sdata->u.wds.remote_addr); | ||
488 | if (sta) { | ||
489 | sta_info_free(sta); | ||
490 | sta_info_put(sta); | ||
491 | } else { | ||
492 | printk(KERN_DEBUG "%s: could not find STA entry for WDS link " | ||
493 | "peer %s\n", | ||
494 | dev->name, print_mac(mac, sdata->u.wds.remote_addr)); | ||
495 | } | ||
496 | |||
497 | /* Update WDS link data */ | ||
498 | memcpy(&sdata->u.wds.remote_addr, remote_addr, ETH_ALEN); | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | /* everything else */ | 946 | /* everything else */ |
504 | 947 | ||
505 | static int __ieee80211_if_config(struct net_device *dev, | 948 | static int __ieee80211_if_config(struct net_device *dev, |
@@ -520,6 +963,9 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
520 | conf.bssid = sdata->u.sta.bssid; | 963 | conf.bssid = sdata->u.sta.bssid; |
521 | conf.ssid = sdata->u.sta.ssid; | 964 | conf.ssid = sdata->u.sta.ssid; |
522 | conf.ssid_len = sdata->u.sta.ssid_len; | 965 | conf.ssid_len = sdata->u.sta.ssid_len; |
966 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
967 | conf.beacon = beacon; | ||
968 | ieee80211_start_mesh(dev); | ||
523 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 969 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
524 | conf.ssid = sdata->u.ap.ssid; | 970 | conf.ssid = sdata->u.ap.ssid; |
525 | conf.ssid_len = sdata->u.ap.ssid_len; | 971 | conf.ssid_len = sdata->u.ap.ssid_len; |
@@ -532,6 +978,11 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
532 | 978 | ||
533 | int ieee80211_if_config(struct net_device *dev) | 979 | int ieee80211_if_config(struct net_device *dev) |
534 | { | 980 | { |
981 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
982 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
983 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | ||
984 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | ||
985 | return ieee80211_if_config_beacon(dev); | ||
535 | return __ieee80211_if_config(dev, NULL, NULL); | 986 | return __ieee80211_if_config(dev, NULL, NULL); |
536 | } | 987 | } |
537 | 988 | ||
@@ -553,37 +1004,28 @@ int ieee80211_if_config_beacon(struct net_device *dev) | |||
553 | 1004 | ||
554 | int ieee80211_hw_config(struct ieee80211_local *local) | 1005 | int ieee80211_hw_config(struct ieee80211_local *local) |
555 | { | 1006 | { |
556 | struct ieee80211_hw_mode *mode; | ||
557 | struct ieee80211_channel *chan; | 1007 | struct ieee80211_channel *chan; |
558 | int ret = 0; | 1008 | int ret = 0; |
559 | 1009 | ||
560 | if (local->sta_sw_scanning) { | 1010 | if (local->sta_sw_scanning) |
561 | chan = local->scan_channel; | 1011 | chan = local->scan_channel; |
562 | mode = local->scan_hw_mode; | 1012 | else |
563 | } else { | ||
564 | chan = local->oper_channel; | 1013 | chan = local->oper_channel; |
565 | mode = local->oper_hw_mode; | ||
566 | } | ||
567 | 1014 | ||
568 | local->hw.conf.channel = chan->chan; | 1015 | local->hw.conf.channel = chan; |
569 | local->hw.conf.channel_val = chan->val; | 1016 | |
570 | if (!local->hw.conf.power_level) { | 1017 | if (!local->hw.conf.power_level) |
571 | local->hw.conf.power_level = chan->power_level; | 1018 | local->hw.conf.power_level = chan->max_power; |
572 | } else { | 1019 | else |
573 | local->hw.conf.power_level = min(chan->power_level, | 1020 | local->hw.conf.power_level = min(chan->max_power, |
574 | local->hw.conf.power_level); | 1021 | local->hw.conf.power_level); |
575 | } | 1022 | |
576 | local->hw.conf.freq = chan->freq; | 1023 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; |
577 | local->hw.conf.phymode = mode->mode; | ||
578 | local->hw.conf.antenna_max = chan->antenna_max; | ||
579 | local->hw.conf.chan = chan; | ||
580 | local->hw.conf.mode = mode; | ||
581 | 1024 | ||
582 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1025 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
583 | printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d " | 1026 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", |
584 | "phymode=%d\n", local->hw.conf.channel, local->hw.conf.freq, | 1027 | wiphy_name(local->hw.wiphy), chan->center_freq); |
585 | local->hw.conf.phymode); | 1028 | #endif |
586 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
587 | 1029 | ||
588 | if (local->open_count) | 1030 | if (local->open_count) |
589 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | 1031 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); |
@@ -601,11 +1043,13 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
601 | struct ieee80211_ht_bss_info *req_bss_cap) | 1043 | struct ieee80211_ht_bss_info *req_bss_cap) |
602 | { | 1044 | { |
603 | struct ieee80211_conf *conf = &local->hw.conf; | 1045 | struct ieee80211_conf *conf = &local->hw.conf; |
604 | struct ieee80211_hw_mode *mode = conf->mode; | 1046 | struct ieee80211_supported_band *sband; |
605 | int i; | 1047 | int i; |
606 | 1048 | ||
1049 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
1050 | |||
607 | /* HT is not supported */ | 1051 | /* HT is not supported */ |
608 | if (!mode->ht_info.ht_supported) { | 1052 | if (!sband->ht_info.ht_supported) { |
609 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1053 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
610 | return -EOPNOTSUPP; | 1054 | return -EOPNOTSUPP; |
611 | } | 1055 | } |
@@ -615,17 +1059,17 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
615 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1059 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
616 | } else { | 1060 | } else { |
617 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | 1061 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
618 | conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap; | 1062 | conf->ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
619 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1063 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
620 | conf->ht_conf.cap |= | 1064 | conf->ht_conf.cap |= |
621 | mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 1065 | sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
622 | conf->ht_bss_conf.primary_channel = | 1066 | conf->ht_bss_conf.primary_channel = |
623 | req_bss_cap->primary_channel; | 1067 | req_bss_cap->primary_channel; |
624 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1068 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
625 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1069 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
626 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1070 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) |
627 | conf->ht_conf.supp_mcs_set[i] = | 1071 | conf->ht_conf.supp_mcs_set[i] = |
628 | mode->ht_info.supp_mcs_set[i] & | 1072 | sband->ht_info.supp_mcs_set[i] & |
629 | req_ht_cap->supp_mcs_set[i]; | 1073 | req_ht_cap->supp_mcs_set[i]; |
630 | 1074 | ||
631 | /* In STA mode, this gives us indication | 1075 | /* In STA mode, this gives us indication |
@@ -713,6 +1157,7 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
713 | struct sk_buff *skb; | 1157 | struct sk_buff *skb; |
714 | struct ieee80211_rx_status rx_status; | 1158 | struct ieee80211_rx_status rx_status; |
715 | struct ieee80211_tx_status *tx_status; | 1159 | struct ieee80211_tx_status *tx_status; |
1160 | struct ieee80211_ra_tid *ra_tid; | ||
716 | 1161 | ||
717 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1162 | while ((skb = skb_dequeue(&local->skb_queue)) || |
718 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1163 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
@@ -733,6 +1178,18 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
733 | skb, tx_status); | 1178 | skb, tx_status); |
734 | kfree(tx_status); | 1179 | kfree(tx_status); |
735 | break; | 1180 | break; |
1181 | case IEEE80211_DELBA_MSG: | ||
1182 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
1183 | ieee80211_stop_tx_ba_cb(local_to_hw(local), | ||
1184 | ra_tid->ra, ra_tid->tid); | ||
1185 | dev_kfree_skb(skb); | ||
1186 | break; | ||
1187 | case IEEE80211_ADDBA_MSG: | ||
1188 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
1189 | ieee80211_start_tx_ba_cb(local_to_hw(local), | ||
1190 | ra_tid->ra, ra_tid->tid); | ||
1191 | dev_kfree_skb(skb); | ||
1192 | break ; | ||
736 | default: /* should never get here! */ | 1193 | default: /* should never get here! */ |
737 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1194 | printk(KERN_ERR "%s: Unknown message type (%d)\n", |
738 | wiphy_name(local->hw.wiphy), skb->pkt_type); | 1195 | wiphy_name(local->hw.wiphy), skb->pkt_type); |
@@ -810,6 +1267,77 @@ no_key: | |||
810 | } | 1267 | } |
811 | } | 1268 | } |
812 | 1269 | ||
1270 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | ||
1271 | struct sta_info *sta, | ||
1272 | struct sk_buff *skb, | ||
1273 | struct ieee80211_tx_status *status) | ||
1274 | { | ||
1275 | sta->tx_filtered_count++; | ||
1276 | |||
1277 | /* | ||
1278 | * Clear the TX filter mask for this STA when sending the next | ||
1279 | * packet. If the STA went to power save mode, this will happen | ||
1280 | * happen when it wakes up for the next time. | ||
1281 | */ | ||
1282 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | ||
1283 | |||
1284 | /* | ||
1285 | * This code races in the following way: | ||
1286 | * | ||
1287 | * (1) STA sends frame indicating it will go to sleep and does so | ||
1288 | * (2) hardware/firmware adds STA to filter list, passes frame up | ||
1289 | * (3) hardware/firmware processes TX fifo and suppresses a frame | ||
1290 | * (4) we get TX status before having processed the frame and | ||
1291 | * knowing that the STA has gone to sleep. | ||
1292 | * | ||
1293 | * This is actually quite unlikely even when both those events are | ||
1294 | * processed from interrupts coming in quickly after one another or | ||
1295 | * even at the same time because we queue both TX status events and | ||
1296 | * RX frames to be processed by a tasklet and process them in the | ||
1297 | * same order that they were received or TX status last. Hence, there | ||
1298 | * is no race as long as the frame RX is processed before the next TX | ||
1299 | * status, which drivers can ensure, see below. | ||
1300 | * | ||
1301 | * Note that this can only happen if the hardware or firmware can | ||
1302 | * actually add STAs to the filter list, if this is done by the | ||
1303 | * driver in response to set_tim() (which will only reduce the race | ||
1304 | * this whole filtering tries to solve, not completely solve it) | ||
1305 | * this situation cannot happen. | ||
1306 | * | ||
1307 | * To completely solve this race drivers need to make sure that they | ||
1308 | * (a) don't mix the irq-safe/not irq-safe TX status/RX processing | ||
1309 | * functions and | ||
1310 | * (b) always process RX events before TX status events if ordering | ||
1311 | * can be unknown, for example with different interrupt status | ||
1312 | * bits. | ||
1313 | */ | ||
1314 | if (sta->flags & WLAN_STA_PS && | ||
1315 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | ||
1316 | ieee80211_remove_tx_extra(local, sta->key, skb, | ||
1317 | &status->control); | ||
1318 | skb_queue_tail(&sta->tx_filtered, skb); | ||
1319 | return; | ||
1320 | } | ||
1321 | |||
1322 | if (!(sta->flags & WLAN_STA_PS) && | ||
1323 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | ||
1324 | /* Software retry the packet once */ | ||
1325 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
1326 | ieee80211_remove_tx_extra(local, sta->key, skb, | ||
1327 | &status->control); | ||
1328 | dev_queue_xmit(skb); | ||
1329 | return; | ||
1330 | } | ||
1331 | |||
1332 | if (net_ratelimit()) | ||
1333 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | ||
1334 | "queue_len=%d PS=%d @%lu\n", | ||
1335 | wiphy_name(local->hw.wiphy), | ||
1336 | skb_queue_len(&sta->tx_filtered), | ||
1337 | !!(sta->flags & WLAN_STA_PS), jiffies); | ||
1338 | dev_kfree_skb(skb); | ||
1339 | } | ||
1340 | |||
813 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1341 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
814 | struct ieee80211_tx_status *status) | 1342 | struct ieee80211_tx_status *status) |
815 | { | 1343 | { |
@@ -819,7 +1347,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
819 | u16 frag, type; | 1347 | u16 frag, type; |
820 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1348 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
821 | struct ieee80211_sub_if_data *sdata; | 1349 | struct ieee80211_sub_if_data *sdata; |
822 | int monitors; | 1350 | struct net_device *prev_dev = NULL; |
823 | 1351 | ||
824 | if (!status) { | 1352 | if (!status) { |
825 | printk(KERN_ERR | 1353 | printk(KERN_ERR |
@@ -829,18 +1357,24 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
829 | return; | 1357 | return; |
830 | } | 1358 | } |
831 | 1359 | ||
1360 | rcu_read_lock(); | ||
1361 | |||
832 | if (status->excessive_retries) { | 1362 | if (status->excessive_retries) { |
833 | struct sta_info *sta; | 1363 | struct sta_info *sta; |
834 | sta = sta_info_get(local, hdr->addr1); | 1364 | sta = sta_info_get(local, hdr->addr1); |
835 | if (sta) { | 1365 | if (sta) { |
836 | if (sta->flags & WLAN_STA_PS) { | 1366 | if (sta->flags & WLAN_STA_PS) { |
837 | /* The STA is in power save mode, so assume | 1367 | /* |
1368 | * The STA is in power save mode, so assume | ||
838 | * that this TX packet failed because of that. | 1369 | * that this TX packet failed because of that. |
839 | */ | 1370 | */ |
840 | status->excessive_retries = 0; | 1371 | status->excessive_retries = 0; |
841 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | 1372 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; |
1373 | ieee80211_handle_filtered_frame(local, sta, | ||
1374 | skb, status); | ||
1375 | rcu_read_unlock(); | ||
1376 | return; | ||
842 | } | 1377 | } |
843 | sta_info_put(sta); | ||
844 | } | 1378 | } |
845 | } | 1379 | } |
846 | 1380 | ||
@@ -848,53 +1382,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
848 | struct sta_info *sta; | 1382 | struct sta_info *sta; |
849 | sta = sta_info_get(local, hdr->addr1); | 1383 | sta = sta_info_get(local, hdr->addr1); |
850 | if (sta) { | 1384 | if (sta) { |
851 | sta->tx_filtered_count++; | 1385 | ieee80211_handle_filtered_frame(local, sta, skb, |
852 | 1386 | status); | |
853 | /* Clear the TX filter mask for this STA when sending | 1387 | rcu_read_unlock(); |
854 | * the next packet. If the STA went to power save mode, | ||
855 | * this will happen when it is waking up for the next | ||
856 | * time. */ | ||
857 | sta->clear_dst_mask = 1; | ||
858 | |||
859 | /* TODO: Is the WLAN_STA_PS flag always set here or is | ||
860 | * the race between RX and TX status causing some | ||
861 | * packets to be filtered out before 80211.o gets an | ||
862 | * update for PS status? This seems to be the case, so | ||
863 | * no changes are likely to be needed. */ | ||
864 | if (sta->flags & WLAN_STA_PS && | ||
865 | skb_queue_len(&sta->tx_filtered) < | ||
866 | STA_MAX_TX_BUFFER) { | ||
867 | ieee80211_remove_tx_extra(local, sta->key, | ||
868 | skb, | ||
869 | &status->control); | ||
870 | skb_queue_tail(&sta->tx_filtered, skb); | ||
871 | } else if (!(sta->flags & WLAN_STA_PS) && | ||
872 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | ||
873 | /* Software retry the packet once */ | ||
874 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
875 | ieee80211_remove_tx_extra(local, sta->key, | ||
876 | skb, | ||
877 | &status->control); | ||
878 | dev_queue_xmit(skb); | ||
879 | } else { | ||
880 | if (net_ratelimit()) { | ||
881 | printk(KERN_DEBUG "%s: dropped TX " | ||
882 | "filtered frame queue_len=%d " | ||
883 | "PS=%d @%lu\n", | ||
884 | wiphy_name(local->hw.wiphy), | ||
885 | skb_queue_len( | ||
886 | &sta->tx_filtered), | ||
887 | !!(sta->flags & WLAN_STA_PS), | ||
888 | jiffies); | ||
889 | } | ||
890 | dev_kfree_skb(skb); | ||
891 | } | ||
892 | sta_info_put(sta); | ||
893 | return; | 1388 | return; |
894 | } | 1389 | } |
895 | } else | 1390 | } else |
896 | rate_control_tx_status(local->mdev, skb, status); | 1391 | rate_control_tx_status(local->mdev, skb, status); |
897 | 1392 | ||
1393 | rcu_read_unlock(); | ||
1394 | |||
898 | ieee80211_led_tx(local, 0); | 1395 | ieee80211_led_tx(local, 0); |
899 | 1396 | ||
900 | /* SNMP counters | 1397 | /* SNMP counters |
@@ -932,7 +1429,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
932 | /* this was a transmitted frame, but now we want to reuse it */ | 1429 | /* this was a transmitted frame, but now we want to reuse it */ |
933 | skb_orphan(skb); | 1430 | skb_orphan(skb); |
934 | 1431 | ||
935 | if (!local->monitors) { | 1432 | /* |
1433 | * This is a bit racy but we can avoid a lot of work | ||
1434 | * with this test... | ||
1435 | */ | ||
1436 | if (!local->monitors && !local->cooked_mntrs) { | ||
936 | dev_kfree_skb(skb); | 1437 | dev_kfree_skb(skb); |
937 | return; | 1438 | return; |
938 | } | 1439 | } |
@@ -966,51 +1467,44 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
966 | 1467 | ||
967 | rthdr->data_retries = status->retry_count; | 1468 | rthdr->data_retries = status->retry_count; |
968 | 1469 | ||
1470 | /* XXX: is this sufficient for BPF? */ | ||
1471 | skb_set_mac_header(skb, 0); | ||
1472 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1473 | skb->pkt_type = PACKET_OTHERHOST; | ||
1474 | skb->protocol = htons(ETH_P_802_2); | ||
1475 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
1476 | |||
969 | rcu_read_lock(); | 1477 | rcu_read_lock(); |
970 | monitors = local->monitors; | ||
971 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 1478 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
972 | /* | ||
973 | * Using the monitors counter is possibly racy, but | ||
974 | * if the value is wrong we simply either clone the skb | ||
975 | * once too much or forget sending it to one monitor iface | ||
976 | * The latter case isn't nice but fixing the race is much | ||
977 | * more complicated. | ||
978 | */ | ||
979 | if (!monitors || !skb) | ||
980 | goto out; | ||
981 | |||
982 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { | 1479 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { |
983 | if (!netif_running(sdata->dev)) | 1480 | if (!netif_running(sdata->dev)) |
984 | continue; | 1481 | continue; |
985 | monitors--; | 1482 | |
986 | if (monitors) | 1483 | if (prev_dev) { |
987 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1484 | skb2 = skb_clone(skb, GFP_ATOMIC); |
988 | else | 1485 | if (skb2) { |
989 | skb2 = NULL; | 1486 | skb2->dev = prev_dev; |
990 | skb->dev = sdata->dev; | 1487 | netif_rx(skb2); |
991 | /* XXX: is this sufficient for BPF? */ | 1488 | } |
992 | skb_set_mac_header(skb, 0); | 1489 | } |
993 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1490 | |
994 | skb->pkt_type = PACKET_OTHERHOST; | 1491 | prev_dev = sdata->dev; |
995 | skb->protocol = htons(ETH_P_802_2); | ||
996 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
997 | netif_rx(skb); | ||
998 | skb = skb2; | ||
999 | } | 1492 | } |
1000 | } | 1493 | } |
1001 | out: | 1494 | if (prev_dev) { |
1495 | skb->dev = prev_dev; | ||
1496 | netif_rx(skb); | ||
1497 | skb = NULL; | ||
1498 | } | ||
1002 | rcu_read_unlock(); | 1499 | rcu_read_unlock(); |
1003 | if (skb) | 1500 | dev_kfree_skb(skb); |
1004 | dev_kfree_skb(skb); | ||
1005 | } | 1501 | } |
1006 | EXPORT_SYMBOL(ieee80211_tx_status); | 1502 | EXPORT_SYMBOL(ieee80211_tx_status); |
1007 | 1503 | ||
1008 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 1504 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
1009 | const struct ieee80211_ops *ops) | 1505 | const struct ieee80211_ops *ops) |
1010 | { | 1506 | { |
1011 | struct net_device *mdev; | ||
1012 | struct ieee80211_local *local; | 1507 | struct ieee80211_local *local; |
1013 | struct ieee80211_sub_if_data *sdata; | ||
1014 | int priv_size; | 1508 | int priv_size; |
1015 | struct wiphy *wiphy; | 1509 | struct wiphy *wiphy; |
1016 | 1510 | ||
@@ -1056,25 +1550,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1056 | BUG_ON(!ops->configure_filter); | 1550 | BUG_ON(!ops->configure_filter); |
1057 | local->ops = ops; | 1551 | local->ops = ops; |
1058 | 1552 | ||
1059 | /* for now, mdev needs sub_if_data :/ */ | ||
1060 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | ||
1061 | "wmaster%d", ether_setup); | ||
1062 | if (!mdev) { | ||
1063 | wiphy_free(wiphy); | ||
1064 | return NULL; | ||
1065 | } | ||
1066 | |||
1067 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | ||
1068 | mdev->ieee80211_ptr = &sdata->wdev; | ||
1069 | sdata->wdev.wiphy = wiphy; | ||
1070 | |||
1071 | local->hw.queues = 1; /* default */ | 1553 | local->hw.queues = 1; /* default */ |
1072 | 1554 | ||
1073 | local->mdev = mdev; | ||
1074 | local->rx_pre_handlers = ieee80211_rx_pre_handlers; | ||
1075 | local->rx_handlers = ieee80211_rx_handlers; | ||
1076 | local->tx_handlers = ieee80211_tx_handlers; | ||
1077 | |||
1078 | local->bridge_packets = 1; | 1555 | local->bridge_packets = 1; |
1079 | 1556 | ||
1080 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 1557 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
@@ -1083,33 +1560,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1083 | local->long_retry_limit = 4; | 1560 | local->long_retry_limit = 4; |
1084 | local->hw.conf.radio_enabled = 1; | 1561 | local->hw.conf.radio_enabled = 1; |
1085 | 1562 | ||
1086 | local->enabled_modes = ~0; | ||
1087 | |||
1088 | INIT_LIST_HEAD(&local->modes_list); | ||
1089 | |||
1090 | INIT_LIST_HEAD(&local->interfaces); | 1563 | INIT_LIST_HEAD(&local->interfaces); |
1091 | 1564 | ||
1092 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 1565 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); |
1093 | ieee80211_rx_bss_list_init(mdev); | ||
1094 | 1566 | ||
1095 | sta_info_init(local); | 1567 | sta_info_init(local); |
1096 | 1568 | ||
1097 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | ||
1098 | mdev->open = ieee80211_master_open; | ||
1099 | mdev->stop = ieee80211_master_stop; | ||
1100 | mdev->type = ARPHRD_IEEE80211; | ||
1101 | mdev->header_ops = &ieee80211_header_ops; | ||
1102 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | ||
1103 | |||
1104 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1105 | sdata->dev = mdev; | ||
1106 | sdata->local = local; | ||
1107 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1108 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1109 | ieee80211_if_sdata_init(sdata); | ||
1110 | /* no RCU needed since we're still during init phase */ | ||
1111 | list_add_tail(&sdata->list, &local->interfaces); | ||
1112 | |||
1113 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, | 1569 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, |
1114 | (unsigned long)local); | 1570 | (unsigned long)local); |
1115 | tasklet_disable(&local->tx_pending_tasklet); | 1571 | tasklet_disable(&local->tx_pending_tasklet); |
@@ -1131,11 +1587,63 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1131 | struct ieee80211_local *local = hw_to_local(hw); | 1587 | struct ieee80211_local *local = hw_to_local(hw); |
1132 | const char *name; | 1588 | const char *name; |
1133 | int result; | 1589 | int result; |
1590 | enum ieee80211_band band; | ||
1591 | struct net_device *mdev; | ||
1592 | struct ieee80211_sub_if_data *sdata; | ||
1593 | |||
1594 | /* | ||
1595 | * generic code guarantees at least one band, | ||
1596 | * set this very early because much code assumes | ||
1597 | * that hw.conf.channel is assigned | ||
1598 | */ | ||
1599 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
1600 | struct ieee80211_supported_band *sband; | ||
1601 | |||
1602 | sband = local->hw.wiphy->bands[band]; | ||
1603 | if (sband) { | ||
1604 | /* init channel we're on */ | ||
1605 | local->hw.conf.channel = | ||
1606 | local->oper_channel = | ||
1607 | local->scan_channel = &sband->channels[0]; | ||
1608 | break; | ||
1609 | } | ||
1610 | } | ||
1134 | 1611 | ||
1135 | result = wiphy_register(local->hw.wiphy); | 1612 | result = wiphy_register(local->hw.wiphy); |
1136 | if (result < 0) | 1613 | if (result < 0) |
1137 | return result; | 1614 | return result; |
1138 | 1615 | ||
1616 | /* for now, mdev needs sub_if_data :/ */ | ||
1617 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | ||
1618 | "wmaster%d", ether_setup); | ||
1619 | if (!mdev) | ||
1620 | goto fail_mdev_alloc; | ||
1621 | |||
1622 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | ||
1623 | mdev->ieee80211_ptr = &sdata->wdev; | ||
1624 | sdata->wdev.wiphy = local->hw.wiphy; | ||
1625 | |||
1626 | local->mdev = mdev; | ||
1627 | |||
1628 | ieee80211_rx_bss_list_init(mdev); | ||
1629 | |||
1630 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | ||
1631 | mdev->open = ieee80211_master_open; | ||
1632 | mdev->stop = ieee80211_master_stop; | ||
1633 | mdev->type = ARPHRD_IEEE80211; | ||
1634 | mdev->header_ops = &ieee80211_header_ops; | ||
1635 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | ||
1636 | |||
1637 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1638 | sdata->dev = mdev; | ||
1639 | sdata->local = local; | ||
1640 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1641 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1642 | ieee80211_if_sdata_init(sdata); | ||
1643 | |||
1644 | /* no RCU needed since we're still during init phase */ | ||
1645 | list_add_tail(&sdata->list, &local->interfaces); | ||
1646 | |||
1139 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1647 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
1140 | local->hw.workqueue = create_singlethread_workqueue(name); | 1648 | local->hw.workqueue = create_singlethread_workqueue(name); |
1141 | if (!local->hw.workqueue) { | 1649 | if (!local->hw.workqueue) { |
@@ -1203,7 +1711,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1203 | 1711 | ||
1204 | /* add one default STA interface */ | 1712 | /* add one default STA interface */ |
1205 | result = ieee80211_if_add(local->mdev, "wlan%d", NULL, | 1713 | result = ieee80211_if_add(local->mdev, "wlan%d", NULL, |
1206 | IEEE80211_IF_TYPE_STA); | 1714 | IEEE80211_IF_TYPE_STA, NULL); |
1207 | if (result) | 1715 | if (result) |
1208 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 1716 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
1209 | wiphy_name(local->hw.wiphy)); | 1717 | wiphy_name(local->hw.wiphy)); |
@@ -1227,49 +1735,18 @@ fail_sta_info: | |||
1227 | debugfs_hw_del(local); | 1735 | debugfs_hw_del(local); |
1228 | destroy_workqueue(local->hw.workqueue); | 1736 | destroy_workqueue(local->hw.workqueue); |
1229 | fail_workqueue: | 1737 | fail_workqueue: |
1738 | ieee80211_if_free(local->mdev); | ||
1739 | local->mdev = NULL; | ||
1740 | fail_mdev_alloc: | ||
1230 | wiphy_unregister(local->hw.wiphy); | 1741 | wiphy_unregister(local->hw.wiphy); |
1231 | return result; | 1742 | return result; |
1232 | } | 1743 | } |
1233 | EXPORT_SYMBOL(ieee80211_register_hw); | 1744 | EXPORT_SYMBOL(ieee80211_register_hw); |
1234 | 1745 | ||
1235 | int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||
1236 | struct ieee80211_hw_mode *mode) | ||
1237 | { | ||
1238 | struct ieee80211_local *local = hw_to_local(hw); | ||
1239 | struct ieee80211_rate *rate; | ||
1240 | int i; | ||
1241 | |||
1242 | INIT_LIST_HEAD(&mode->list); | ||
1243 | list_add_tail(&mode->list, &local->modes_list); | ||
1244 | |||
1245 | local->hw_modes |= (1 << mode->mode); | ||
1246 | for (i = 0; i < mode->num_rates; i++) { | ||
1247 | rate = &(mode->rates[i]); | ||
1248 | rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; | ||
1249 | } | ||
1250 | ieee80211_prepare_rates(local, mode); | ||
1251 | |||
1252 | if (!local->oper_hw_mode) { | ||
1253 | /* Default to this mode */ | ||
1254 | local->hw.conf.phymode = mode->mode; | ||
1255 | local->oper_hw_mode = local->scan_hw_mode = mode; | ||
1256 | local->oper_channel = local->scan_channel = &mode->channels[0]; | ||
1257 | local->hw.conf.mode = local->oper_hw_mode; | ||
1258 | local->hw.conf.chan = local->oper_channel; | ||
1259 | } | ||
1260 | |||
1261 | if (!(hw->flags & IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED)) | ||
1262 | ieee80211_set_default_regdomain(mode); | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | EXPORT_SYMBOL(ieee80211_register_hwmode); | ||
1267 | |||
1268 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1746 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1269 | { | 1747 | { |
1270 | struct ieee80211_local *local = hw_to_local(hw); | 1748 | struct ieee80211_local *local = hw_to_local(hw); |
1271 | struct ieee80211_sub_if_data *sdata, *tmp; | 1749 | struct ieee80211_sub_if_data *sdata, *tmp; |
1272 | int i; | ||
1273 | 1750 | ||
1274 | tasklet_kill(&local->tx_pending_tasklet); | 1751 | tasklet_kill(&local->tx_pending_tasklet); |
1275 | tasklet_kill(&local->tasklet); | 1752 | tasklet_kill(&local->tasklet); |
@@ -1310,11 +1787,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1310 | rate_control_deinitialize(local); | 1787 | rate_control_deinitialize(local); |
1311 | debugfs_hw_del(local); | 1788 | debugfs_hw_del(local); |
1312 | 1789 | ||
1313 | for (i = 0; i < NUM_IEEE80211_MODES; i++) { | ||
1314 | kfree(local->supp_rates[i]); | ||
1315 | kfree(local->basic_rates[i]); | ||
1316 | } | ||
1317 | |||
1318 | if (skb_queue_len(&local->skb_queue) | 1790 | if (skb_queue_len(&local->skb_queue) |
1319 | || skb_queue_len(&local->skb_queue_unreliable)) | 1791 | || skb_queue_len(&local->skb_queue_unreliable)) |
1320 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 1792 | printk(KERN_WARNING "%s: skb_queue not empty\n", |
@@ -1326,6 +1798,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1326 | wiphy_unregister(local->hw.wiphy); | 1798 | wiphy_unregister(local->hw.wiphy); |
1327 | ieee80211_wep_free(local); | 1799 | ieee80211_wep_free(local); |
1328 | ieee80211_led_exit(local); | 1800 | ieee80211_led_exit(local); |
1801 | ieee80211_if_free(local->mdev); | ||
1802 | local->mdev = NULL; | ||
1329 | } | 1803 | } |
1330 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1804 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1331 | 1805 | ||
@@ -1333,7 +1807,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1333 | { | 1807 | { |
1334 | struct ieee80211_local *local = hw_to_local(hw); | 1808 | struct ieee80211_local *local = hw_to_local(hw); |
1335 | 1809 | ||
1336 | ieee80211_if_free(local->mdev); | ||
1337 | wiphy_free(local->hw.wiphy); | 1810 | wiphy_free(local->hw.wiphy); |
1338 | } | 1811 | } |
1339 | EXPORT_SYMBOL(ieee80211_free_hw); | 1812 | EXPORT_SYMBOL(ieee80211_free_hw); |
@@ -1345,13 +1818,9 @@ static int __init ieee80211_init(void) | |||
1345 | 1818 | ||
1346 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1819 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); |
1347 | 1820 | ||
1348 | ret = rc80211_simple_init(); | ||
1349 | if (ret) | ||
1350 | goto out; | ||
1351 | |||
1352 | ret = rc80211_pid_init(); | 1821 | ret = rc80211_pid_init(); |
1353 | if (ret) | 1822 | if (ret) |
1354 | goto out_cleanup_simple; | 1823 | goto out; |
1355 | 1824 | ||
1356 | ret = ieee80211_wme_register(); | 1825 | ret = ieee80211_wme_register(); |
1357 | if (ret) { | 1826 | if (ret) { |
@@ -1361,23 +1830,22 @@ static int __init ieee80211_init(void) | |||
1361 | } | 1830 | } |
1362 | 1831 | ||
1363 | ieee80211_debugfs_netdev_init(); | 1832 | ieee80211_debugfs_netdev_init(); |
1364 | ieee80211_regdomain_init(); | ||
1365 | 1833 | ||
1366 | return 0; | 1834 | return 0; |
1367 | 1835 | ||
1368 | out_cleanup_pid: | 1836 | out_cleanup_pid: |
1369 | rc80211_pid_exit(); | 1837 | rc80211_pid_exit(); |
1370 | out_cleanup_simple: | ||
1371 | rc80211_simple_exit(); | ||
1372 | out: | 1838 | out: |
1373 | return ret; | 1839 | return ret; |
1374 | } | 1840 | } |
1375 | 1841 | ||
1376 | static void __exit ieee80211_exit(void) | 1842 | static void __exit ieee80211_exit(void) |
1377 | { | 1843 | { |
1378 | rc80211_simple_exit(); | ||
1379 | rc80211_pid_exit(); | 1844 | rc80211_pid_exit(); |
1380 | 1845 | ||
1846 | if (mesh_allocated) | ||
1847 | ieee80211s_stop(); | ||
1848 | |||
1381 | ieee80211_wme_unregister(); | 1849 | ieee80211_wme_unregister(); |
1382 | ieee80211_debugfs_netdev_exit(); | 1850 | ieee80211_debugfs_netdev_exit(); |
1383 | } | 1851 | } |