diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-05-24 18:01:30 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-05-24 18:01:30 -0400 |
commit | dde7dc759b777f385fc5df2af691c82eb455c7f3 (patch) | |
tree | 5e8f1fcd10a6b264d60bc8a0503656c0611de222 /net/mac80211 | |
parent | b422c6cd7e93bb613030f14d7d8a0cc73f115629 (diff) | |
parent | 4c8a9d4bfaf7dbc7d2168494904d79d22cc01db7 (diff) |
Merge remote-tracking branch 'mac80211/master' into mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/iface.c | 18 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 45 | ||||
-rw-r--r-- | net/mac80211/rate.c | 9 | ||||
-rw-r--r-- | net/mac80211/rx.c | 3 | ||||
-rw-r--r-- | net/mac80211/tkip.c | 4 | ||||
-rw-r--r-- | net/mac80211/util.c | 7 |
7 files changed, 73 insertions, 14 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b7cbd4ebf0e0..ba3cd284d104 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1267,6 +1267,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); | |||
1267 | void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); | 1267 | void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); |
1268 | void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, | 1268 | void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, |
1269 | __le16 fc, bool acked); | 1269 | __le16 fc, bool acked); |
1270 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); | ||
1270 | 1271 | ||
1271 | /* IBSS code */ | 1272 | /* IBSS code */ |
1272 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 1273 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 60f1ce5e5e52..ceef64426a8d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -474,6 +474,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
474 | master->control_port_protocol; | 474 | master->control_port_protocol; |
475 | sdata->control_port_no_encrypt = | 475 | sdata->control_port_no_encrypt = |
476 | master->control_port_no_encrypt; | 476 | master->control_port_no_encrypt; |
477 | sdata->vif.cab_queue = master->vif.cab_queue; | ||
478 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, | ||
479 | sizeof(sdata->vif.hw_queue)); | ||
477 | break; | 480 | break; |
478 | } | 481 | } |
479 | case NL80211_IFTYPE_AP: | 482 | case NL80211_IFTYPE_AP: |
@@ -653,7 +656,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
653 | 656 | ||
654 | ieee80211_recalc_ps(local, -1); | 657 | ieee80211_recalc_ps(local, -1); |
655 | 658 | ||
656 | if (dev) { | 659 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
660 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
661 | /* XXX: for AP_VLAN, actually track AP queues */ | ||
662 | netif_tx_start_all_queues(dev); | ||
663 | } else if (dev) { | ||
657 | unsigned long flags; | 664 | unsigned long flags; |
658 | int n_acs = IEEE80211_NUM_ACS; | 665 | int n_acs = IEEE80211_NUM_ACS; |
659 | int ac; | 666 | int ac; |
@@ -1696,6 +1703,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1696 | 1703 | ||
1697 | ASSERT_RTNL(); | 1704 | ASSERT_RTNL(); |
1698 | 1705 | ||
1706 | /* | ||
1707 | * Close all AP_VLAN interfaces first, as otherwise they | ||
1708 | * might be closed while the AP interface they belong to | ||
1709 | * is closed, causing unregister_netdevice_many() to crash. | ||
1710 | */ | ||
1711 | list_for_each_entry(sdata, &local->interfaces, list) | ||
1712 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1713 | dev_close(sdata->dev); | ||
1714 | |||
1699 | mutex_lock(&local->iflist_mtx); | 1715 | mutex_lock(&local->iflist_mtx); |
1700 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | 1716 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
1701 | list_del(&sdata->list); | 1717 | list_del(&sdata->list); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ef378b9a32ec..1da3d6be8e11 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3325,10 +3325,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3325 | if (WARN_ON_ONCE(!auth_data)) | 3325 | if (WARN_ON_ONCE(!auth_data)) |
3326 | return -EINVAL; | 3326 | return -EINVAL; |
3327 | 3327 | ||
3328 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
3329 | tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
3330 | IEEE80211_TX_INTFL_MLME_CONN_TX; | ||
3331 | |||
3332 | auth_data->tries++; | 3328 | auth_data->tries++; |
3333 | 3329 | ||
3334 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 3330 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
@@ -3362,6 +3358,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3362 | auth_data->expected_transaction = trans; | 3358 | auth_data->expected_transaction = trans; |
3363 | } | 3359 | } |
3364 | 3360 | ||
3361 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
3362 | tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
3363 | IEEE80211_TX_INTFL_MLME_CONN_TX; | ||
3364 | |||
3365 | ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, | 3365 | ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, |
3366 | auth_data->data, auth_data->data_len, | 3366 | auth_data->data, auth_data->data_len, |
3367 | auth_data->bss->bssid, | 3367 | auth_data->bss->bssid, |
@@ -3385,12 +3385,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3385 | * will not answer to direct packet in unassociated state. | 3385 | * will not answer to direct packet in unassociated state. |
3386 | */ | 3386 | */ |
3387 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], | 3387 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], |
3388 | NULL, 0, (u32) -1, true, tx_flags, | 3388 | NULL, 0, (u32) -1, true, 0, |
3389 | auth_data->bss->channel, false); | 3389 | auth_data->bss->channel, false); |
3390 | rcu_read_unlock(); | 3390 | rcu_read_unlock(); |
3391 | } | 3391 | } |
3392 | 3392 | ||
3393 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 3393 | if (tx_flags == 0) { |
3394 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 3394 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
3395 | ifmgd->auth_data->timeout_started = true; | 3395 | ifmgd->auth_data->timeout_started = true; |
3396 | run_again(ifmgd, auth_data->timeout); | 3396 | run_again(ifmgd, auth_data->timeout); |
@@ -3643,6 +3643,31 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
3643 | } | 3643 | } |
3644 | } | 3644 | } |
3645 | 3645 | ||
3646 | #ifdef CONFIG_PM | ||
3647 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | ||
3648 | { | ||
3649 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
3650 | |||
3651 | mutex_lock(&ifmgd->mtx); | ||
3652 | if (!ifmgd->associated) { | ||
3653 | mutex_unlock(&ifmgd->mtx); | ||
3654 | return; | ||
3655 | } | ||
3656 | |||
3657 | if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) { | ||
3658 | sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; | ||
3659 | mlme_dbg(sdata, "driver requested disconnect after resume\n"); | ||
3660 | ieee80211_sta_connection_lost(sdata, | ||
3661 | ifmgd->associated->bssid, | ||
3662 | WLAN_REASON_UNSPECIFIED, | ||
3663 | true); | ||
3664 | mutex_unlock(&ifmgd->mtx); | ||
3665 | return; | ||
3666 | } | ||
3667 | mutex_unlock(&ifmgd->mtx); | ||
3668 | } | ||
3669 | #endif | ||
3670 | |||
3646 | /* interface setup */ | 3671 | /* interface setup */ |
3647 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | 3672 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) |
3648 | { | 3673 | { |
@@ -4349,7 +4374,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4349 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 4374 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
4350 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 4375 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
4351 | bool tx = !req->local_state_change; | 4376 | bool tx = !req->local_state_change; |
4352 | bool sent_frame = false; | 4377 | bool report_frame = false; |
4353 | 4378 | ||
4354 | mutex_lock(&ifmgd->mtx); | 4379 | mutex_lock(&ifmgd->mtx); |
4355 | 4380 | ||
@@ -4366,7 +4391,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4366 | ieee80211_destroy_auth_data(sdata, false); | 4391 | ieee80211_destroy_auth_data(sdata, false); |
4367 | mutex_unlock(&ifmgd->mtx); | 4392 | mutex_unlock(&ifmgd->mtx); |
4368 | 4393 | ||
4369 | sent_frame = tx; | 4394 | report_frame = true; |
4370 | goto out; | 4395 | goto out; |
4371 | } | 4396 | } |
4372 | 4397 | ||
@@ -4374,12 +4399,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4374 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { | 4399 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { |
4375 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 4400 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
4376 | req->reason_code, tx, frame_buf); | 4401 | req->reason_code, tx, frame_buf); |
4377 | sent_frame = tx; | 4402 | report_frame = true; |
4378 | } | 4403 | } |
4379 | mutex_unlock(&ifmgd->mtx); | 4404 | mutex_unlock(&ifmgd->mtx); |
4380 | 4405 | ||
4381 | out: | 4406 | out: |
4382 | if (sent_frame) | 4407 | if (report_frame) |
4383 | __cfg80211_send_deauth(sdata->dev, frame_buf, | 4408 | __cfg80211_send_deauth(sdata->dev, frame_buf, |
4384 | IEEE80211_DEAUTH_FRAME_LEN); | 4409 | IEEE80211_DEAUTH_FRAME_LEN); |
4385 | 4410 | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 0d51877efdb7..d3f414fe67e0 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -688,8 +688,15 @@ int rate_control_set_rates(struct ieee80211_hw *hw, | |||
688 | struct ieee80211_sta *pubsta, | 688 | struct ieee80211_sta *pubsta, |
689 | struct ieee80211_sta_rates *rates) | 689 | struct ieee80211_sta_rates *rates) |
690 | { | 690 | { |
691 | struct ieee80211_sta_rates *old = rcu_dereference(pubsta->rates); | 691 | struct ieee80211_sta_rates *old; |
692 | 692 | ||
693 | /* | ||
694 | * mac80211 guarantees that this function will not be called | ||
695 | * concurrently, so the following RCU access is safe, even without | ||
696 | * extra locking. This can not be checked easily, so we just set | ||
697 | * the condition to true. | ||
698 | */ | ||
699 | old = rcu_dereference_protected(pubsta->rates, true); | ||
693 | rcu_assign_pointer(pubsta->rates, rates); | 700 | rcu_assign_pointer(pubsta->rates, rates); |
694 | if (old) | 701 | if (old) |
695 | kfree_rcu(old, rcu_head); | 702 | kfree_rcu(old, rcu_head); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7507f7cdd68c..bdd7b4a719e9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3054,6 +3054,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
3054 | * and location updates. Note that mac80211 | 3054 | * and location updates. Note that mac80211 |
3055 | * itself never looks at these frames. | 3055 | * itself never looks at these frames. |
3056 | */ | 3056 | */ |
3057 | if (!multicast && | ||
3058 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) | ||
3059 | return 0; | ||
3057 | if (ieee80211_is_public_action(hdr, skb->len)) | 3060 | if (ieee80211_is_public_action(hdr, skb->len)) |
3058 | return 1; | 3061 | return 1; |
3059 | if (!ieee80211_is_beacon(hdr->frame_control)) | 3062 | if (!ieee80211_is_beacon(hdr->frame_control)) |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 3ed801d90f1e..124b1fdc20d0 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -208,10 +208,10 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, | |||
208 | u32 iv32 = get_unaligned_le32(&data[4]); | 208 | u32 iv32 = get_unaligned_le32(&data[4]); |
209 | u16 iv16 = data[2] | (data[0] << 8); | 209 | u16 iv16 = data[2] | (data[0] << 8); |
210 | 210 | ||
211 | spin_lock_bh(&key->u.tkip.txlock); | 211 | spin_lock(&key->u.tkip.txlock); |
212 | ieee80211_compute_tkip_p1k(key, iv32); | 212 | ieee80211_compute_tkip_p1k(key, iv32); |
213 | tkip_mixing_phase2(tk, ctx, iv16, p2k); | 213 | tkip_mixing_phase2(tk, ctx, iv16, p2k); |
214 | spin_unlock_bh(&key->u.tkip.txlock); | 214 | spin_unlock(&key->u.tkip.txlock); |
215 | } | 215 | } |
216 | EXPORT_SYMBOL(ieee80211_get_tkip_p2k); | 216 | EXPORT_SYMBOL(ieee80211_get_tkip_p2k); |
217 | 217 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 707953fd8324..ffdfe4bc89ad 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1714,6 +1714,13 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1714 | mb(); | 1714 | mb(); |
1715 | local->resuming = false; | 1715 | local->resuming = false; |
1716 | 1716 | ||
1717 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1718 | if (!ieee80211_sdata_running(sdata)) | ||
1719 | continue; | ||
1720 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
1721 | ieee80211_sta_restart(sdata); | ||
1722 | } | ||
1723 | |||
1717 | mod_timer(&local->sta_cleanup, jiffies + 1); | 1724 | mod_timer(&local->sta_cleanup, jiffies + 1); |
1718 | #else | 1725 | #else |
1719 | WARN_ON(1); | 1726 | WARN_ON(1); |