aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c18
-rw-r--r--net/mac80211/mlme.c45
-rw-r--r--net/mac80211/rate.c9
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/mac80211/tkip.c4
-rw-r--r--net/mac80211/util.c7
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);
1267void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); 1267void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
1268void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, 1268void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
1269 __le16 fc, bool acked); 1269 __le16 fc, bool acked);
1270void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1270 1271
1271/* IBSS code */ 1272/* IBSS code */
1272void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1273void 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
3647void 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 */
3647void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) 3672void 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}
216EXPORT_SYMBOL(ieee80211_get_tkip_p2k); 216EXPORT_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);