aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h46
-rw-r--r--include/net/mac80211.h2
-rw-r--r--include/uapi/linux/nl80211.h4
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c65
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mesh.c57
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_plink.c8
-rw-r--r--net/mac80211/mlme.c35
-rw-r--r--net/mac80211/rate.c8
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/sta_info.h1
-rw-r--r--net/mac80211/vht.c2
-rw-r--r--net/wireless/chan.c57
-rw-r--r--net/wireless/core.c6
-rw-r--r--net/wireless/mlme.c12
-rw-r--r--net/wireless/nl80211.c277
-rw-r--r--net/wireless/scan.c4
-rw-r--r--net/wireless/sme.c23
-rw-r--r--net/wireless/sysfs.c2
23 files changed, 415 insertions, 231 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6a43c34ce96f..7b0730aeb892 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -188,6 +188,8 @@ struct ieee80211_channel {
188 * when used with 802.11g (on the 2.4 GHz band); filled by the 188 * when used with 802.11g (on the 2.4 GHz band); filled by the
189 * core code when registering the wiphy. 189 * core code when registering the wiphy.
190 * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. 190 * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
191 * @IEEE80211_RATE_SUPPORTS_5MHZ: Rate can be used in 5 MHz mode
192 * @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode
191 */ 193 */
192enum ieee80211_rate_flags { 194enum ieee80211_rate_flags {
193 IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, 195 IEEE80211_RATE_SHORT_PREAMBLE = 1<<0,
@@ -195,6 +197,8 @@ enum ieee80211_rate_flags {
195 IEEE80211_RATE_MANDATORY_B = 1<<2, 197 IEEE80211_RATE_MANDATORY_B = 1<<2,
196 IEEE80211_RATE_MANDATORY_G = 1<<3, 198 IEEE80211_RATE_MANDATORY_G = 1<<3,
197 IEEE80211_RATE_ERP_G = 1<<4, 199 IEEE80211_RATE_ERP_G = 1<<4,
200 IEEE80211_RATE_SUPPORTS_5MHZ = 1<<5,
201 IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6,
198}; 202};
199 203
200/** 204/**
@@ -433,6 +437,30 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
433 u32 prohibited_flags); 437 u32 prohibited_flags);
434 438
435/** 439/**
440 * ieee80211_chandef_rate_flags - returns rate flags for a channel
441 *
442 * In some channel types, not all rates may be used - for example CCK
443 * rates may not be used in 5/10 MHz channels.
444 *
445 * @chandef: channel definition for the channel
446 *
447 * Returns: rate flags which apply for this channel
448 */
449static inline enum ieee80211_rate_flags
450ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef)
451{
452 switch (chandef->width) {
453 case NL80211_CHAN_WIDTH_5:
454 return IEEE80211_RATE_SUPPORTS_5MHZ;
455 case NL80211_CHAN_WIDTH_10:
456 return IEEE80211_RATE_SUPPORTS_10MHZ;
457 default:
458 break;
459 }
460 return 0;
461}
462
463/**
436 * enum survey_info_flags - survey information flags 464 * enum survey_info_flags - survey information flags
437 * 465 *
438 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 466 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -1431,7 +1459,8 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
1431 * This structure provides information needed to complete IEEE 802.11 1459 * This structure provides information needed to complete IEEE 802.11
1432 * authentication. 1460 * authentication.
1433 * 1461 *
1434 * @bss: The BSS to authenticate with. 1462 * @bss: The BSS to authenticate with, the callee must obtain a reference
1463 * to it if it needs to keep it.
1435 * @auth_type: Authentication type (algorithm) 1464 * @auth_type: Authentication type (algorithm)
1436 * @ie: Extra IEs to add to Authentication frame or %NULL 1465 * @ie: Extra IEs to add to Authentication frame or %NULL
1437 * @ie_len: Length of ie buffer in octets 1466 * @ie_len: Length of ie buffer in octets
@@ -1469,11 +1498,10 @@ enum cfg80211_assoc_req_flags {
1469 * 1498 *
1470 * This structure provides information needed to complete IEEE 802.11 1499 * This structure provides information needed to complete IEEE 802.11
1471 * (re)association. 1500 * (re)association.
1472 * @bss: The BSS to associate with. If the call is successful the driver 1501 * @bss: The BSS to associate with. If the call is successful the driver is
1473 * is given a reference that it must release, normally via a call to 1502 * given a reference that it must give back to cfg80211_send_rx_assoc()
1474 * cfg80211_send_rx_assoc(), or, if association timed out, with a 1503 * or to cfg80211_assoc_timeout(). To ensure proper refcounting, new
1475 * call to cfg80211_put_bss() (in addition to calling 1504 * association requests while already associating must be rejected.
1476 * cfg80211_send_assoc_timeout())
1477 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL 1505 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
1478 * @ie_len: Length of ie buffer in octets 1506 * @ie_len: Length of ie buffer in octets
1479 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association 1507 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
@@ -2342,6 +2370,7 @@ struct cfg80211_ops {
2342 * responds to probe-requests in hardware. 2370 * responds to probe-requests in hardware.
2343 * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. 2371 * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
2344 * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. 2372 * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
2373 * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels.
2345 */ 2374 */
2346enum wiphy_flags { 2375enum wiphy_flags {
2347 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 2376 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -2365,6 +2394,7 @@ enum wiphy_flags {
2365 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), 2394 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19),
2366 WIPHY_FLAG_OFFCHAN_TX = BIT(20), 2395 WIPHY_FLAG_OFFCHAN_TX = BIT(20),
2367 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), 2396 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
2397 WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
2368}; 2398};
2369 2399
2370/** 2400/**
@@ -3492,11 +3522,11 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
3492/** 3522/**
3493 * cfg80211_assoc_timeout - notification of timed out association 3523 * cfg80211_assoc_timeout - notification of timed out association
3494 * @dev: network device 3524 * @dev: network device
3495 * @addr: The MAC address of the device with which the association timed out 3525 * @bss: The BSS entry with which association timed out.
3496 * 3526 *
3497 * This function may sleep. The caller must hold the corresponding wdev's mutex. 3527 * This function may sleep. The caller must hold the corresponding wdev's mutex.
3498 */ 3528 */
3499void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr); 3529void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
3500 3530
3501/** 3531/**
3502 * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame 3532 * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a405a7a9775c..5b7a3dadadde 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -305,6 +305,7 @@ enum ieee80211_rssi_event {
305 * @basic_rates: bitmap of basic rates, each bit stands for an 305 * @basic_rates: bitmap of basic rates, each bit stands for an
306 * index into the rate table configured by the driver in 306 * index into the rate table configured by the driver in
307 * the current band. 307 * the current band.
308 * @beacon_rate: associated AP's beacon TX rate
308 * @mcast_rate: per-band multicast rate index + 1 (0: disabled) 309 * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
309 * @bssid: The BSSID for this BSS 310 * @bssid: The BSSID for this BSS
310 * @enable_beacon: whether beaconing should be enabled or not 311 * @enable_beacon: whether beaconing should be enabled or not
@@ -352,6 +353,7 @@ struct ieee80211_bss_conf {
352 u32 sync_device_ts; 353 u32 sync_device_ts;
353 u8 sync_dtim_count; 354 u8 sync_dtim_count;
354 u32 basic_rates; 355 u32 basic_rates;
356 struct ieee80211_rate *beacon_rate;
355 int mcast_rate[IEEE80211_NUM_BANDS]; 357 int mcast_rate[IEEE80211_NUM_BANDS];
356 u16 ht_operation_mode; 358 u16 ht_operation_mode;
357 s32 cqm_rssi_thold; 359 s32 cqm_rssi_thold;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ca6facf4df0c..861e5eba3953 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2758,6 +2758,8 @@ enum nl80211_channel_type {
2758 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well 2758 * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
2759 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 2759 * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
2760 * attribute must be provided as well 2760 * attribute must be provided as well
2761 * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
2762 * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
2761 */ 2763 */
2762enum nl80211_chan_width { 2764enum nl80211_chan_width {
2763 NL80211_CHAN_WIDTH_20_NOHT, 2765 NL80211_CHAN_WIDTH_20_NOHT,
@@ -2766,6 +2768,8 @@ enum nl80211_chan_width {
2766 NL80211_CHAN_WIDTH_80, 2768 NL80211_CHAN_WIDTH_80,
2767 NL80211_CHAN_WIDTH_80P80, 2769 NL80211_CHAN_WIDTH_80P80,
2768 NL80211_CHAN_WIDTH_160, 2770 NL80211_CHAN_WIDTH_160,
2771 NL80211_CHAN_WIDTH_5,
2772 NL80211_CHAN_WIDTH_10,
2769}; 2773};
2770 2774
2771/** 2775/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 082f270b5912..8184d121ff09 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2827,7 +2827,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2827 !rcu_access_pointer(sdata->bss->beacon)) 2827 !rcu_access_pointer(sdata->bss->beacon))
2828 need_offchan = true; 2828 need_offchan = true;
2829 if (!ieee80211_is_action(mgmt->frame_control) || 2829 if (!ieee80211_is_action(mgmt->frame_control) ||
2830 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 2830 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
2831 mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED)
2831 break; 2832 break;
2832 rcu_read_lock(); 2833 rcu_read_lock();
2833 sta = sta_info_get(sdata, mgmt->da); 2834 sta = sta_info_get(sdata, mgmt->da);
@@ -2930,19 +2931,8 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
2930 u16 frame_type, bool reg) 2931 u16 frame_type, bool reg)
2931{ 2932{
2932 struct ieee80211_local *local = wiphy_priv(wiphy); 2933 struct ieee80211_local *local = wiphy_priv(wiphy);
2933 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2934 2934
2935 switch (frame_type) { 2935 switch (frame_type) {
2936 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
2937 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2938 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2939
2940 if (reg)
2941 ifibss->auth_frame_registrations++;
2942 else
2943 ifibss->auth_frame_registrations--;
2944 }
2945 break;
2946 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 2936 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
2947 if (reg) 2937 if (reg)
2948 local->probe_req_reg++; 2938 local->probe_req_reg++;
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 75dff338f581..f83534f6a2ee 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct work_struct *work)
281 sta, tid, WLAN_BACK_RECIPIENT, 281 sta, tid, WLAN_BACK_RECIPIENT,
282 WLAN_REASON_UNSPECIFIED, true); 282 WLAN_REASON_UNSPECIFIED, true);
283 283
284 spin_lock_bh(&sta->lock);
285
284 tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; 286 tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
285 if (tid_tx) { 287 if (tid_tx) {
286 /* 288 /*
287 * Assign it over to the normal tid_tx array 289 * Assign it over to the normal tid_tx array
288 * where it "goes live". 290 * where it "goes live".
289 */ 291 */
290 spin_lock_bh(&sta->lock);
291 292
292 sta->ampdu_mlme.tid_start_tx[tid] = NULL; 293 sta->ampdu_mlme.tid_start_tx[tid] = NULL;
293 /* could there be a race? */ 294 /* could there be a race? */
@@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
300 ieee80211_tx_ba_session_handle_start(sta, tid); 301 ieee80211_tx_ba_session_handle_start(sta, tid);
301 continue; 302 continue;
302 } 303 }
304 spin_unlock_bh(&sta->lock);
303 305
304 tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 306 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
305 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 307 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index caa4b4f7f6e4..ea7b9c2c7e66 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -81,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
81 81
82 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 82 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
83 83
84 cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); 84 chandef = ifibss->chandef;
85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { 85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
86 chandef.width = NL80211_CHAN_WIDTH_20; 86 chandef.width = NL80211_CHAN_WIDTH_20;
87 chandef.center_freq1 = chan->center_freq; 87 chandef.center_freq1 = chan->center_freq;
@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
176 176
177 /* add HT capability and information IEs */ 177 /* add HT capability and information IEs */
178 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 178 if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
179 chandef.width != NL80211_CHAN_WIDTH_5 &&
180 chandef.width != NL80211_CHAN_WIDTH_10 &&
179 sband->ht_cap.ht_supported) { 181 sband->ht_cap.ht_supported) {
180 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 182 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
181 sband->ht_cap.cap); 183 sband->ht_cap.cap);
@@ -298,8 +300,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
298 tsf, false); 300 tsf, false);
299} 301}
300 302
301static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, 303static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
302 bool auth)
303 __acquires(RCU) 304 __acquires(RCU)
304{ 305{
305 struct ieee80211_sub_if_data *sdata = sta->sdata; 306 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -321,20 +322,12 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
321 /* If it fails, maybe we raced another insertion? */ 322 /* If it fails, maybe we raced another insertion? */
322 if (sta_info_insert_rcu(sta)) 323 if (sta_info_insert_rcu(sta))
323 return sta_info_get(sdata, addr); 324 return sta_info_get(sdata, addr);
324 if (auth && !sdata->u.ibss.auth_frame_registrations) {
325 ibss_dbg(sdata,
326 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
327 sdata->vif.addr, addr, sdata->u.ibss.bssid);
328 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0,
329 addr, sdata->u.ibss.bssid, NULL, 0, 0, 0);
330 }
331 return sta; 325 return sta;
332} 326}
333 327
334static struct sta_info * 328static struct sta_info *
335ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 329ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
336 const u8 *bssid, const u8 *addr, 330 const u8 *addr, u32 supp_rates)
337 u32 supp_rates, bool auth)
338 __acquires(RCU) 331 __acquires(RCU)
339{ 332{
340 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 333 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -385,7 +378,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
385 sta->sta.supp_rates[band] = supp_rates | 378 sta->sta.supp_rates[band] = supp_rates |
386 ieee80211_mandatory_rates(sband); 379 ieee80211_mandatory_rates(sband);
387 380
388 return ieee80211_ibss_finish_sta(sta, auth); 381 return ieee80211_ibss_finish_sta(sta);
389} 382}
390 383
391static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, 384static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
@@ -407,8 +400,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
407 size_t len) 400 size_t len)
408{ 401{
409 u16 auth_alg, auth_transaction; 402 u16 auth_alg, auth_transaction;
410 struct sta_info *sta;
411 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
412 403
413 sdata_assert_lock(sdata); 404 sdata_assert_lock(sdata);
414 405
@@ -425,22 +416,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
425 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) 416 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
426 return; 417 return;
427 418
428 sta_info_destroy_addr(sdata, mgmt->sa);
429 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
430 rcu_read_unlock();
431
432 /*
433 * if we have any problem in allocating the new station, we reply with a
434 * DEAUTH frame to tell the other end that we had a problem
435 */
436 if (!sta) {
437 ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid,
438 IEEE80211_STYPE_DEAUTH,
439 WLAN_REASON_UNSPECIFIED, true,
440 deauth_frame_buf);
441 return;
442 }
443
444 /* 419 /*
445 * IEEE 802.11 standard does not require authentication in IBSS 420 * IEEE 802.11 standard does not require authentication in IBSS
446 * networks and most implementations do not seem to use it. 421 * networks and most implementations do not seem to use it.
@@ -506,7 +481,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
506 } else { 481 } else {
507 rcu_read_unlock(); 482 rcu_read_unlock();
508 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, 483 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
509 mgmt->sa, supp_rates, true); 484 mgmt->sa, supp_rates);
510 } 485 }
511 } 486 }
512 487
@@ -514,7 +489,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
514 set_sta_flag(sta, WLAN_STA_WME); 489 set_sta_flag(sta, WLAN_STA_WME);
515 490
516 if (sta && elems->ht_operation && elems->ht_cap_elem && 491 if (sta && elems->ht_operation && elems->ht_cap_elem &&
517 sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { 492 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
493 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
494 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
518 /* we both use HT */ 495 /* we both use HT */
519 struct ieee80211_ht_cap htcap_ie; 496 struct ieee80211_ht_cap htcap_ie;
520 struct cfg80211_chan_def chandef; 497 struct cfg80211_chan_def chandef;
@@ -529,8 +506,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
529 * fall back to HT20 if we don't use or use 506 * fall back to HT20 if we don't use or use
530 * the other extension channel 507 * the other extension channel
531 */ 508 */
532 if (cfg80211_get_chandef_type(&chandef) != 509 if (chandef.center_freq1 !=
533 sdata->u.ibss.channel_type) 510 sdata->u.ibss.chandef.center_freq1)
534 htcap_ie.cap_info &= 511 htcap_ie.cap_info &=
535 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); 512 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
536 513
@@ -569,7 +546,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
569 546
570 /* different channel */ 547 /* different channel */
571 if (sdata->u.ibss.fixed_channel && 548 if (sdata->u.ibss.fixed_channel &&
572 sdata->u.ibss.channel != cbss->channel) 549 sdata->u.ibss.chandef.chan != cbss->channel)
573 goto put_bss; 550 goto put_bss;
574 551
575 /* different SSID */ 552 /* different SSID */
@@ -610,7 +587,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
610 ieee80211_sta_join_ibss(sdata, bss); 587 ieee80211_sta_join_ibss(sdata, bss);
611 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); 588 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
612 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 589 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
613 supp_rates, true); 590 supp_rates);
614 rcu_read_unlock(); 591 rcu_read_unlock();
615 } 592 }
616 593
@@ -759,7 +736,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
759 sdata->drop_unencrypted = 0; 736 sdata->drop_unencrypted = 0;
760 737
761 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, 738 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
762 ifibss->channel, ifibss->basic_rates, 739 ifibss->chandef.chan, ifibss->basic_rates,
763 capability, 0, true); 740 capability, 0, true);
764} 741}
765 742
@@ -791,7 +768,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
791 if (ifibss->fixed_bssid) 768 if (ifibss->fixed_bssid)
792 bssid = ifibss->bssid; 769 bssid = ifibss->bssid;
793 if (ifibss->fixed_channel) 770 if (ifibss->fixed_channel)
794 chan = ifibss->channel; 771 chan = ifibss->chandef.chan;
795 if (!is_zero_ether_addr(ifibss->bssid)) 772 if (!is_zero_ether_addr(ifibss->bssid))
796 bssid = ifibss->bssid; 773 bssid = ifibss->bssid;
797 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, 774 cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
@@ -982,7 +959,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
982 list_del(&sta->list); 959 list_del(&sta->list);
983 spin_unlock_bh(&ifibss->incomplete_lock); 960 spin_unlock_bh(&ifibss->incomplete_lock);
984 961
985 ieee80211_ibss_finish_sta(sta, true); 962 ieee80211_ibss_finish_sta(sta);
986 rcu_read_unlock(); 963 rcu_read_unlock();
987 spin_lock_bh(&ifibss->incomplete_lock); 964 spin_lock_bh(&ifibss->incomplete_lock);
988 } 965 }
@@ -1058,9 +1035,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1058 1035
1059 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 1036 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
1060 1037
1061 sdata->u.ibss.channel = params->chandef.chan; 1038 sdata->u.ibss.chandef = params->chandef;
1062 sdata->u.ibss.channel_type =
1063 cfg80211_get_chandef_type(&params->chandef);
1064 sdata->u.ibss.fixed_channel = params->channel_fixed; 1039 sdata->u.ibss.fixed_channel = params->channel_fixed;
1065 1040
1066 if (params->ie) { 1041 if (params->ie) {
@@ -1119,7 +1094,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1119 if (ifibss->privacy) 1094 if (ifibss->privacy)
1120 capability |= WLAN_CAPABILITY_PRIVACY; 1095 capability |= WLAN_CAPABILITY_PRIVACY;
1121 1096
1122 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->channel, 1097 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
1123 ifibss->bssid, ifibss->ssid, 1098 ifibss->bssid, ifibss->ssid,
1124 ifibss->ssid_len, WLAN_CAPABILITY_IBSS | 1099 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
1125 WLAN_CAPABILITY_PRIVACY, 1100 WLAN_CAPABILITY_PRIVACY,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f97cd9d9105f..8412a303993a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -94,6 +94,7 @@ struct ieee80211_bss {
94#define IEEE80211_MAX_SUPP_RATES 32 94#define IEEE80211_MAX_SUPP_RATES 32
95 u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; 95 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
96 size_t supp_rates_len; 96 size_t supp_rates_len;
97 struct ieee80211_rate *beacon_rate;
97 98
98 /* 99 /*
99 * During association, we save an ERP value from a probe response so 100 * During association, we save an ERP value from a probe response so
@@ -497,14 +498,12 @@ struct ieee80211_if_ibss {
497 bool privacy; 498 bool privacy;
498 499
499 bool control_port; 500 bool control_port;
500 unsigned int auth_frame_registrations;
501 501
502 u8 bssid[ETH_ALEN] __aligned(2); 502 u8 bssid[ETH_ALEN] __aligned(2);
503 u8 ssid[IEEE80211_MAX_SSID_LEN]; 503 u8 ssid[IEEE80211_MAX_SSID_LEN];
504 u8 ssid_len, ie_len; 504 u8 ssid_len, ie_len;
505 u8 *ie; 505 u8 *ie;
506 struct ieee80211_channel *channel; 506 struct cfg80211_chan_def chandef;
507 enum nl80211_channel_type channel_type;
508 507
509 unsigned long ibss_join_req; 508 unsigned long ibss_join_req;
510 /* probe response/beacon for IBSS */ 509 /* probe response/beacon for IBSS */
@@ -543,6 +542,7 @@ struct ieee80211_if_mesh {
543 struct timer_list mesh_path_root_timer; 542 struct timer_list mesh_path_root_timer;
544 543
545 unsigned long wrkq_flags; 544 unsigned long wrkq_flags;
545 unsigned long mbss_changed;
546 546
547 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; 547 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
548 size_t mesh_id_len; 548 size_t mesh_id_len;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6c33af482df4..447f41bbe744 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,11 +161,8 @@ void mesh_sta_cleanup(struct sta_info *sta)
161 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
162 } 162 }
163 163
164 if (changed) { 164 if (changed)
165 sdata_lock(sdata);
166 ieee80211_mbss_info_change_notify(sdata, changed); 165 ieee80211_mbss_info_change_notify(sdata, changed);
167 sdata_unlock(sdata);
168 }
169} 166}
170 167
171int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 168int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -419,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
419 416
420 sband = local->hw.wiphy->bands[band]; 417 sband = local->hw.wiphy->bands[band];
421 if (!sband->ht_cap.ht_supported || 418 if (!sband->ht_cap.ht_supported ||
422 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) 419 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
420 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
421 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
423 return 0; 422 return 0;
424 423
425 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) 424 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -719,14 +718,18 @@ ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
719void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 718void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
720 u32 changed) 719 u32 changed)
721{ 720{
722 if (sdata->vif.bss_conf.enable_beacon && 721 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
723 (changed & (BSS_CHANGED_BEACON | 722 unsigned long bits = changed;
724 BSS_CHANGED_HT | 723 u32 bit;
725 BSS_CHANGED_BASIC_RATES | 724
726 BSS_CHANGED_BEACON_INT))) 725 if (!bits)
727 if (ieee80211_mesh_rebuild_beacon(sdata)) 726 return;
728 return; 727
729 ieee80211_bss_info_change_notify(sdata, changed); 728 /* if we race with running work, worst case this work becomes a noop */
729 for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
730 set_bit(bit, &ifmsh->mbss_changed);
731 set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
732 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
730} 733}
731 734
732int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) 735int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
@@ -799,6 +802,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
799 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 802 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
800 del_timer_sync(&sdata->u.mesh.mesh_path_timer); 803 del_timer_sync(&sdata->u.mesh.mesh_path_timer);
801 804
805 /* clear any mesh work (for next join) we may have accrued */
806 ifmsh->wrkq_flags = 0;
807 ifmsh->mbss_changed = 0;
808
802 local->fif_other_bss--; 809 local->fif_other_bss--;
803 atomic_dec(&local->iff_allmultis); 810 atomic_dec(&local->iff_allmultis);
804 ieee80211_configure_filter(local); 811 ieee80211_configure_filter(local);
@@ -965,6 +972,28 @@ out:
965 sdata_unlock(sdata); 972 sdata_unlock(sdata);
966} 973}
967 974
975static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata)
976{
977 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
978 u32 bit, changed = 0;
979
980 for_each_set_bit(bit, &ifmsh->mbss_changed,
981 sizeof(changed) * BITS_PER_BYTE) {
982 clear_bit(bit, &ifmsh->mbss_changed);
983 changed |= BIT(bit);
984 }
985
986 if (sdata->vif.bss_conf.enable_beacon &&
987 (changed & (BSS_CHANGED_BEACON |
988 BSS_CHANGED_HT |
989 BSS_CHANGED_BASIC_RATES |
990 BSS_CHANGED_BEACON_INT)))
991 if (ieee80211_mesh_rebuild_beacon(sdata))
992 return;
993
994 ieee80211_bss_info_change_notify(sdata, changed);
995}
996
968void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) 997void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
969{ 998{
970 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 999 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -995,6 +1024,8 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
995 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 1024 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
996 mesh_sync_adjust_tbtt(sdata); 1025 mesh_sync_adjust_tbtt(sdata);
997 1026
1027 if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags))
1028 mesh_bss_info_changed(sdata);
998out: 1029out:
999 sdata_unlock(sdata); 1030 sdata_unlock(sdata);
1000} 1031}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 01a28bca6e9b..2bc7fd2f787d 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -58,6 +58,7 @@ enum mesh_path_flags {
58 * @MESH_WORK_ROOT: the mesh root station needs to send a frame 58 * @MESH_WORK_ROOT: the mesh root station needs to send a frame
59 * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other 59 * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
60 * mesh nodes 60 * mesh nodes
61 * @MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes
61 */ 62 */
62enum mesh_deferred_task_flags { 63enum mesh_deferred_task_flags {
63 MESH_WORK_HOUSEKEEPING, 64 MESH_WORK_HOUSEKEEPING,
@@ -65,6 +66,7 @@ enum mesh_deferred_task_flags {
65 MESH_WORK_GROW_MPP_TABLE, 66 MESH_WORK_GROW_MPP_TABLE,
66 MESH_WORK_ROOT, 67 MESH_WORK_ROOT,
67 MESH_WORK_DRIFT_ADJUST, 68 MESH_WORK_DRIFT_ADJUST,
69 MESH_WORK_MBSS_CHANGED,
68}; 70};
69 71
70/** 72/**
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 09bebed99416..02c05fa15c20 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
154 u16 ht_opmode; 154 u16 ht_opmode;
155 bool non_ht_sta = false, ht20_sta = false; 155 bool non_ht_sta = false, ht20_sta = false;
156 156
157 if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) 157 switch (sdata->vif.bss_conf.chandef.width) {
158 case NL80211_CHAN_WIDTH_20_NOHT:
159 case NL80211_CHAN_WIDTH_5:
160 case NL80211_CHAN_WIDTH_10:
158 return 0; 161 return 0;
162 default:
163 break;
164 }
159 165
160 rcu_read_lock(); 166 rcu_read_lock();
161 list_for_each_entry_rcu(sta, &local->sta_list, list) { 167 list_for_each_entry_rcu(sta, &local->sta_list, list) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e49f557fa5c..ae31968d42d3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c)
190 c->width = NL80211_CHAN_WIDTH_20_NOHT; 190 c->width = NL80211_CHAN_WIDTH_20_NOHT;
191 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; 191 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
192 break; 192 break;
193 case NL80211_CHAN_WIDTH_5:
194 case NL80211_CHAN_WIDTH_10:
195 WARN_ON_ONCE(1);
196 /* keep c->width */
197 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
198 break;
193 } 199 }
194 200
195 WARN_ON_ONCE(!cfg80211_chandef_valid(c)); 201 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
@@ -1779,8 +1785,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1779 * probably just won't work at all. 1785 * probably just won't work at all.
1780 */ 1786 */
1781 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; 1787 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
1788 bss_conf->beacon_rate = bss->beacon_rate;
1782 bss_info_changed |= BSS_CHANGED_BEACON_INFO; 1789 bss_info_changed |= BSS_CHANGED_BEACON_INFO;
1783 } else { 1790 } else {
1791 bss_conf->beacon_rate = NULL;
1784 bss_conf->dtim_period = 0; 1792 bss_conf->dtim_period = 0;
1785 } 1793 }
1786 1794
@@ -1903,6 +1911,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1903 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1911 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1904 1912
1905 sdata->vif.bss_conf.dtim_period = 0; 1913 sdata->vif.bss_conf.dtim_period = 0;
1914 sdata->vif.bss_conf.beacon_rate = NULL;
1915
1906 ifmgd->have_beacon = false; 1916 ifmgd->have_beacon = false;
1907 1917
1908 ifmgd->flags = 0; 1918 ifmgd->flags = 0;
@@ -2785,8 +2795,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2785 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { 2795 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
2786 /* oops -- internal error -- send timeout for now */ 2796 /* oops -- internal error -- send timeout for now */
2787 ieee80211_destroy_assoc_data(sdata, false); 2797 ieee80211_destroy_assoc_data(sdata, false);
2788 cfg80211_put_bss(sdata->local->hw.wiphy, bss); 2798 cfg80211_assoc_timeout(sdata->dev, bss);
2789 cfg80211_assoc_timeout(sdata->dev, mgmt->bssid);
2790 return; 2799 return;
2791 } 2800 }
2792 sdata_info(sdata, "associated\n"); 2801 sdata_info(sdata, "associated\n");
@@ -2827,8 +2836,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2827 2836
2828 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 2837 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
2829 channel); 2838 channel);
2830 if (bss) 2839 if (bss) {
2831 ieee80211_rx_bss_put(local, bss); 2840 ieee80211_rx_bss_put(local, bss);
2841 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
2842 }
2832 2843
2833 if (!sdata->u.mgd.associated || 2844 if (!sdata->u.mgd.associated ||
2834 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) 2845 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
@@ -3501,13 +3512,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3501 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3512 time_after(jiffies, ifmgd->assoc_data->timeout)) {
3502 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || 3513 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
3503 ieee80211_do_assoc(sdata)) { 3514 ieee80211_do_assoc(sdata)) {
3504 u8 bssid[ETH_ALEN]; 3515 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
3505
3506 memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
3507 3516
3508 ieee80211_destroy_assoc_data(sdata, false); 3517 ieee80211_destroy_assoc_data(sdata, false);
3509 3518 cfg80211_assoc_timeout(sdata->dev, bss);
3510 cfg80211_assoc_timeout(sdata->dev, bssid);
3511 } 3519 }
3512 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3520 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3513 run_again(sdata, ifmgd->assoc_data->timeout); 3521 run_again(sdata, ifmgd->assoc_data->timeout);
@@ -3838,6 +3846,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3838 */ 3846 */
3839 ret = ieee80211_vif_use_channel(sdata, &chandef, 3847 ret = ieee80211_vif_use_channel(sdata, &chandef,
3840 IEEE80211_CHANCTX_SHARED); 3848 IEEE80211_CHANCTX_SHARED);
3849
3850 /* don't downgrade for 5 and 10 MHz channels, though. */
3851 if (chandef.width == NL80211_CHAN_WIDTH_5 ||
3852 chandef.width == NL80211_CHAN_WIDTH_10)
3853 return ret;
3854
3841 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { 3855 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
3842 ifmgd->flags |= chandef_downgrade(&chandef); 3856 ifmgd->flags |= chandef_downgrade(&chandef);
3843 ret = ieee80211_vif_use_channel(sdata, &chandef, 3857 ret = ieee80211_vif_use_channel(sdata, &chandef,
@@ -4427,8 +4441,11 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4427 cancel_work_sync(&ifmgd->chswitch_work); 4441 cancel_work_sync(&ifmgd->chswitch_work);
4428 4442
4429 sdata_lock(sdata); 4443 sdata_lock(sdata);
4430 if (ifmgd->assoc_data) 4444 if (ifmgd->assoc_data) {
4445 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
4431 ieee80211_destroy_assoc_data(sdata, false); 4446 ieee80211_destroy_assoc_data(sdata, false);
4447 cfg80211_assoc_timeout(sdata->dev, bss);
4448 }
4432 if (ifmgd->auth_data) 4449 if (ifmgd->auth_data)
4433 ieee80211_destroy_auth_data(sdata, false); 4450 ieee80211_destroy_auth_data(sdata, false);
4434 del_timer_sync(&ifmgd->timer); 4451 del_timer_sync(&ifmgd->timer);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index a02bef35b134..30d58d2d13e2 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
397 return; 397 return;
398 398
399 /* if HT BSS, and we handle a data frame, also try HT rates */ 399 /* if HT BSS, and we handle a data frame, also try HT rates */
400 if (chan_width == NL80211_CHAN_WIDTH_20_NOHT) 400 switch (chan_width) {
401 case NL80211_CHAN_WIDTH_20_NOHT:
402 case NL80211_CHAN_WIDTH_5:
403 case NL80211_CHAN_WIDTH_10:
401 return; 404 return;
405 default:
406 break;
407 }
402 408
403 alt_rate.idx = 0; 409 alt_rate.idx = 0;
404 /* keep protection flags */ 410 /* keep protection flags */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 99b103921a4b..1b122a79b0d8 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -140,6 +140,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
140 bss->valid_data |= IEEE80211_BSS_VALID_WMM; 140 bss->valid_data |= IEEE80211_BSS_VALID_WMM;
141 } 141 }
142 142
143 if (beacon) {
144 struct ieee80211_supported_band *sband =
145 local->hw.wiphy->bands[rx_status->band];
146 if (!(rx_status->flag & RX_FLAG_HT) &&
147 !(rx_status->flag & RX_FLAG_VHT))
148 bss->beacon_rate =
149 &sband->bitrates[rx_status->rate_idx];
150 }
151
143 return bss; 152 return bss;
144} 153}
145 154
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index b4297982d34a..aeb967a0aeed 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -149,6 +149,7 @@ static void cleanup_single_sta(struct sta_info *sta)
149 * directly by station destruction. 149 * directly by station destruction.
150 */ 150 */
151 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 151 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
152 kfree(sta->ampdu_mlme.tid_start_tx[i]);
152 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); 153 tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
153 if (!tid_tx) 154 if (!tid_tx)
154 continue; 155 continue;
@@ -346,6 +347,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
346 if (ieee80211_vif_is_mesh(&sdata->vif) && 347 if (ieee80211_vif_is_mesh(&sdata->vif) &&
347 !sdata->u.mesh.user_mpm) 348 !sdata->u.mesh.user_mpm)
348 init_timer(&sta->plink_timer); 349 init_timer(&sta->plink_timer);
350 sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
349#endif 351#endif
350 352
351 memcpy(sta->sta.addr, addr, ETH_ALEN); 353 memcpy(sta->sta.addr, addr, ETH_ALEN);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index bd12fc54266c..4208dbd5861f 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -203,6 +203,7 @@ struct tid_ampdu_rx {
203 * driver requested to close until the work for it runs 203 * driver requested to close until the work for it runs
204 * @mtx: mutex to protect all TX data (except non-NULL assignments 204 * @mtx: mutex to protect all TX data (except non-NULL assignments
205 * to tid_tx[idx], which are protected by the sta spinlock) 205 * to tid_tx[idx], which are protected by the sta spinlock)
206 * tid_start_tx is also protected by sta->lock.
206 */ 207 */
207struct sta_ampdu_mlme { 208struct sta_ampdu_mlme {
208 struct mutex mtx; 209 struct mutex mtx;
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 171344d4eb7c..97c289414e32 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -396,7 +396,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
396 new_bw = ieee80211_sta_cur_vht_bw(sta); 396 new_bw = ieee80211_sta_cur_vht_bw(sta);
397 if (new_bw != sta->sta.bandwidth) { 397 if (new_bw != sta->sta.bandwidth) {
398 sta->sta.bandwidth = new_bw; 398 sta->sta.bandwidth = new_bw;
399 changed |= IEEE80211_RC_NSS_CHANGED; 399 changed |= IEEE80211_RC_BW_CHANGED;
400 } 400 }
401 401
402 change: 402 change:
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index fd556ac05fdb..50f6195c8b70 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -54,6 +54,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
54 control_freq = chandef->chan->center_freq; 54 control_freq = chandef->chan->center_freq;
55 55
56 switch (chandef->width) { 56 switch (chandef->width) {
57 case NL80211_CHAN_WIDTH_5:
58 case NL80211_CHAN_WIDTH_10:
57 case NL80211_CHAN_WIDTH_20: 59 case NL80211_CHAN_WIDTH_20:
58 case NL80211_CHAN_WIDTH_20_NOHT: 60 case NL80211_CHAN_WIDTH_20_NOHT:
59 if (chandef->center_freq1 != control_freq) 61 if (chandef->center_freq1 != control_freq)
@@ -152,6 +154,12 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
152 int width; 154 int width;
153 155
154 switch (c->width) { 156 switch (c->width) {
157 case NL80211_CHAN_WIDTH_5:
158 width = 5;
159 break;
160 case NL80211_CHAN_WIDTH_10:
161 width = 10;
162 break;
155 case NL80211_CHAN_WIDTH_20: 163 case NL80211_CHAN_WIDTH_20:
156 case NL80211_CHAN_WIDTH_20_NOHT: 164 case NL80211_CHAN_WIDTH_20_NOHT:
157 width = 20; 165 width = 20;
@@ -194,6 +202,16 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
194 if (c1->width == c2->width) 202 if (c1->width == c2->width)
195 return NULL; 203 return NULL;
196 204
205 /*
206 * can't be compatible if one of them is 5 or 10 MHz,
207 * but they don't have the same width.
208 */
209 if (c1->width == NL80211_CHAN_WIDTH_5 ||
210 c1->width == NL80211_CHAN_WIDTH_10 ||
211 c2->width == NL80211_CHAN_WIDTH_5 ||
212 c2->width == NL80211_CHAN_WIDTH_10)
213 return NULL;
214
197 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT || 215 if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
198 c1->width == NL80211_CHAN_WIDTH_20) 216 c1->width == NL80211_CHAN_WIDTH_20)
199 return c2; 217 return c2;
@@ -264,11 +282,17 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
264 u32 bandwidth) 282 u32 bandwidth)
265{ 283{
266 struct ieee80211_channel *c; 284 struct ieee80211_channel *c;
267 u32 freq; 285 u32 freq, start_freq, end_freq;
286
287 if (bandwidth <= 20) {
288 start_freq = center_freq;
289 end_freq = center_freq;
290 } else {
291 start_freq = center_freq - bandwidth/2 + 10;
292 end_freq = center_freq + bandwidth/2 - 10;
293 }
268 294
269 for (freq = center_freq - bandwidth/2 + 10; 295 for (freq = start_freq; freq <= end_freq; freq += 20) {
270 freq <= center_freq + bandwidth/2 - 10;
271 freq += 20) {
272 c = ieee80211_get_channel(wiphy, freq); 296 c = ieee80211_get_channel(wiphy, freq);
273 if (!c) 297 if (!c)
274 return -EINVAL; 298 return -EINVAL;
@@ -310,11 +334,17 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
310 u32 prohibited_flags) 334 u32 prohibited_flags)
311{ 335{
312 struct ieee80211_channel *c; 336 struct ieee80211_channel *c;
313 u32 freq; 337 u32 freq, start_freq, end_freq;
338
339 if (bandwidth <= 20) {
340 start_freq = center_freq;
341 end_freq = center_freq;
342 } else {
343 start_freq = center_freq - bandwidth/2 + 10;
344 end_freq = center_freq + bandwidth/2 - 10;
345 }
314 346
315 for (freq = center_freq - bandwidth/2 + 10; 347 for (freq = start_freq; freq <= end_freq; freq += 20) {
316 freq <= center_freq + bandwidth/2 - 10;
317 freq += 20) {
318 c = ieee80211_get_channel(wiphy, freq); 348 c = ieee80211_get_channel(wiphy, freq);
319 if (!c) 349 if (!c)
320 return false; 350 return false;
@@ -349,6 +379,12 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
349 control_freq = chandef->chan->center_freq; 379 control_freq = chandef->chan->center_freq;
350 380
351 switch (chandef->width) { 381 switch (chandef->width) {
382 case NL80211_CHAN_WIDTH_5:
383 width = 5;
384 break;
385 case NL80211_CHAN_WIDTH_10:
386 width = 10;
387 break;
352 case NL80211_CHAN_WIDTH_20: 388 case NL80211_CHAN_WIDTH_20:
353 if (!ht_cap->ht_supported) 389 if (!ht_cap->ht_supported)
354 return false; 390 return false;
@@ -405,6 +441,11 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
405 if (width > 20) 441 if (width > 20)
406 prohibited_flags |= IEEE80211_CHAN_NO_OFDM; 442 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
407 443
444 /* 5 and 10 MHz are only defined for the OFDM PHY */
445 if (width < 20)
446 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
447
448
408 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, 449 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
409 width, prohibited_flags)) 450 width, prohibited_flags))
410 return false; 451 return false;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 4224e7554a76..672459b9483b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -934,6 +934,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
934 * freed. 934 * freed.
935 */ 935 */
936 cfg80211_process_wdev_events(wdev); 936 cfg80211_process_wdev_events(wdev);
937
938 if (WARN_ON(wdev->current_bss)) {
939 cfg80211_unhold_bss(wdev->current_bss);
940 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
941 wdev->current_bss = NULL;
942 }
937 break; 943 break;
938 case NETDEV_PRE_UP: 944 case NETDEV_PRE_UP:
939 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 945 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index a61a44bc6cf0..bfac5e186f57 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
38 * frame instead of reassoc. 38 * frame instead of reassoc.
39 */ 39 */
40 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { 40 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
41 cfg80211_unhold_bss(bss_from_pub(bss));
41 cfg80211_put_bss(wiphy, bss); 42 cfg80211_put_bss(wiphy, bss);
42 return; 43 return;
43 } 44 }
@@ -131,16 +132,19 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
131} 132}
132EXPORT_SYMBOL(cfg80211_auth_timeout); 133EXPORT_SYMBOL(cfg80211_auth_timeout);
133 134
134void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr) 135void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
135{ 136{
136 struct wireless_dev *wdev = dev->ieee80211_ptr; 137 struct wireless_dev *wdev = dev->ieee80211_ptr;
137 struct wiphy *wiphy = wdev->wiphy; 138 struct wiphy *wiphy = wdev->wiphy;
138 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 139 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
139 140
140 trace_cfg80211_send_assoc_timeout(dev, addr); 141 trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
141 142
142 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 143 nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
143 cfg80211_sme_assoc_timeout(wdev); 144 cfg80211_sme_assoc_timeout(wdev);
145
146 cfg80211_unhold_bss(bss_from_pub(bss));
147 cfg80211_put_bss(wiphy, bss);
144} 148}
145EXPORT_SYMBOL(cfg80211_assoc_timeout); 149EXPORT_SYMBOL(cfg80211_assoc_timeout);
146 150
@@ -307,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
307 goto out; 311 goto out;
308 312
309 err = rdev_assoc(rdev, dev, req); 313 err = rdev_assoc(rdev, dev, req);
314 if (!err)
315 cfg80211_hold_bss(bss_from_pub(req->bss));
310 316
311out: 317out:
312 if (err) 318 if (err)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e4028197b75d..7dc3343427c1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1111,10 +1111,16 @@ nl80211_send_mgmt_stypes(struct sk_buff *msg,
1111 return 0; 1111 return 0;
1112} 1112}
1113 1113
1114struct nl80211_dump_wiphy_state {
1115 s64 filter_wiphy;
1116 long start;
1117 long split_start, band_start, chan_start;
1118 bool split;
1119};
1120
1114static int nl80211_send_wiphy(struct cfg80211_registered_device *dev, 1121static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1115 struct sk_buff *msg, u32 portid, u32 seq, 1122 struct sk_buff *msg, u32 portid, u32 seq,
1116 int flags, bool split, long *split_start, 1123 int flags, struct nl80211_dump_wiphy_state *state)
1117 long *band_start, long *chan_start)
1118{ 1124{
1119 void *hdr; 1125 void *hdr;
1120 struct nlattr *nl_bands, *nl_band; 1126 struct nlattr *nl_bands, *nl_band;
@@ -1125,19 +1131,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1125 int i; 1131 int i;
1126 const struct ieee80211_txrx_stypes *mgmt_stypes = 1132 const struct ieee80211_txrx_stypes *mgmt_stypes =
1127 dev->wiphy.mgmt_stypes; 1133 dev->wiphy.mgmt_stypes;
1128 long start = 0, start_chan = 0, start_band = 0;
1129 u32 features; 1134 u32 features;
1130 1135
1131 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); 1136 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY);
1132 if (!hdr) 1137 if (!hdr)
1133 return -ENOBUFS; 1138 return -ENOBUFS;
1134 1139
1135 /* allow always using the variables */ 1140 if (WARN_ON(!state))
1136 if (!split) { 1141 return -EINVAL;
1137 split_start = &start;
1138 band_start = &start_band;
1139 chan_start = &start_chan;
1140 }
1141 1142
1142 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || 1143 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
1143 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, 1144 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
@@ -1146,7 +1147,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1146 cfg80211_rdev_list_generation)) 1147 cfg80211_rdev_list_generation))
1147 goto nla_put_failure; 1148 goto nla_put_failure;
1148 1149
1149 switch (*split_start) { 1150 switch (state->split_start) {
1150 case 0: 1151 case 0:
1151 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, 1152 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1152 dev->wiphy.retry_short) || 1153 dev->wiphy.retry_short) ||
@@ -1188,9 +1189,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1188 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && 1189 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
1189 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) 1190 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
1190 goto nla_put_failure; 1191 goto nla_put_failure;
1192 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
1193 nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1194 goto nla_put_failure;
1191 1195
1192 (*split_start)++; 1196 state->split_start++;
1193 if (split) 1197 if (state->split)
1194 break; 1198 break;
1195 case 1: 1199 case 1:
1196 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, 1200 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
@@ -1234,22 +1238,23 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1234 } 1238 }
1235 } 1239 }
1236 1240
1237 (*split_start)++; 1241 state->split_start++;
1238 if (split) 1242 if (state->split)
1239 break; 1243 break;
1240 case 2: 1244 case 2:
1241 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, 1245 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1242 dev->wiphy.interface_modes)) 1246 dev->wiphy.interface_modes))
1243 goto nla_put_failure; 1247 goto nla_put_failure;
1244 (*split_start)++; 1248 state->split_start++;
1245 if (split) 1249 if (state->split)
1246 break; 1250 break;
1247 case 3: 1251 case 3:
1248 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 1252 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
1249 if (!nl_bands) 1253 if (!nl_bands)
1250 goto nla_put_failure; 1254 goto nla_put_failure;
1251 1255
1252 for (band = *band_start; band < IEEE80211_NUM_BANDS; band++) { 1256 for (band = state->band_start;
1257 band < IEEE80211_NUM_BANDS; band++) {
1253 struct ieee80211_supported_band *sband; 1258 struct ieee80211_supported_band *sband;
1254 1259
1255 sband = dev->wiphy.bands[band]; 1260 sband = dev->wiphy.bands[band];
@@ -1261,12 +1266,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1261 if (!nl_band) 1266 if (!nl_band)
1262 goto nla_put_failure; 1267 goto nla_put_failure;
1263 1268
1264 switch (*chan_start) { 1269 switch (state->chan_start) {
1265 case 0: 1270 case 0:
1266 if (nl80211_send_band_rateinfo(msg, sband)) 1271 if (nl80211_send_band_rateinfo(msg, sband))
1267 goto nla_put_failure; 1272 goto nla_put_failure;
1268 (*chan_start)++; 1273 state->chan_start++;
1269 if (split) 1274 if (state->split)
1270 break; 1275 break;
1271 default: 1276 default:
1272 /* add frequencies */ 1277 /* add frequencies */
@@ -1275,7 +1280,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1275 if (!nl_freqs) 1280 if (!nl_freqs)
1276 goto nla_put_failure; 1281 goto nla_put_failure;
1277 1282
1278 for (i = *chan_start - 1; 1283 for (i = state->chan_start - 1;
1279 i < sband->n_channels; 1284 i < sband->n_channels;
1280 i++) { 1285 i++) {
1281 nl_freq = nla_nest_start(msg, i); 1286 nl_freq = nla_nest_start(msg, i);
@@ -1284,26 +1289,27 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1284 1289
1285 chan = &sband->channels[i]; 1290 chan = &sband->channels[i];
1286 1291
1287 if (nl80211_msg_put_channel(msg, chan, 1292 if (nl80211_msg_put_channel(
1288 split)) 1293 msg, chan,
1294 state->split))
1289 goto nla_put_failure; 1295 goto nla_put_failure;
1290 1296
1291 nla_nest_end(msg, nl_freq); 1297 nla_nest_end(msg, nl_freq);
1292 if (split) 1298 if (state->split)
1293 break; 1299 break;
1294 } 1300 }
1295 if (i < sband->n_channels) 1301 if (i < sband->n_channels)
1296 *chan_start = i + 2; 1302 state->chan_start = i + 2;
1297 else 1303 else
1298 *chan_start = 0; 1304 state->chan_start = 0;
1299 nla_nest_end(msg, nl_freqs); 1305 nla_nest_end(msg, nl_freqs);
1300 } 1306 }
1301 1307
1302 nla_nest_end(msg, nl_band); 1308 nla_nest_end(msg, nl_band);
1303 1309
1304 if (split) { 1310 if (state->split) {
1305 /* start again here */ 1311 /* start again here */
1306 if (*chan_start) 1312 if (state->chan_start)
1307 band--; 1313 band--;
1308 break; 1314 break;
1309 } 1315 }
@@ -1311,14 +1317,14 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1311 nla_nest_end(msg, nl_bands); 1317 nla_nest_end(msg, nl_bands);
1312 1318
1313 if (band < IEEE80211_NUM_BANDS) 1319 if (band < IEEE80211_NUM_BANDS)
1314 *band_start = band + 1; 1320 state->band_start = band + 1;
1315 else 1321 else
1316 *band_start = 0; 1322 state->band_start = 0;
1317 1323
1318 /* if bands & channels are done, continue outside */ 1324 /* if bands & channels are done, continue outside */
1319 if (*band_start == 0 && *chan_start == 0) 1325 if (state->band_start == 0 && state->chan_start == 0)
1320 (*split_start)++; 1326 state->split_start++;
1321 if (split) 1327 if (state->split)
1322 break; 1328 break;
1323 case 4: 1329 case 4:
1324 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); 1330 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
@@ -1384,7 +1390,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1384 } 1390 }
1385 CMD(start_p2p_device, START_P2P_DEVICE); 1391 CMD(start_p2p_device, START_P2P_DEVICE);
1386 CMD(set_mcast_rate, SET_MCAST_RATE); 1392 CMD(set_mcast_rate, SET_MCAST_RATE);
1387 if (split) { 1393 if (state->split) {
1388 CMD(crit_proto_start, CRIT_PROTOCOL_START); 1394 CMD(crit_proto_start, CRIT_PROTOCOL_START);
1389 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP); 1395 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1390 } 1396 }
@@ -1408,8 +1414,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1408 } 1414 }
1409 1415
1410 nla_nest_end(msg, nl_cmds); 1416 nla_nest_end(msg, nl_cmds);
1411 (*split_start)++; 1417 state->split_start++;
1412 if (split) 1418 if (state->split)
1413 break; 1419 break;
1414 case 5: 1420 case 5:
1415 if (dev->ops->remain_on_channel && 1421 if (dev->ops->remain_on_channel &&
@@ -1425,29 +1431,30 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1425 1431
1426 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes)) 1432 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
1427 goto nla_put_failure; 1433 goto nla_put_failure;
1428 (*split_start)++; 1434 state->split_start++;
1429 if (split) 1435 if (state->split)
1430 break; 1436 break;
1431 case 6: 1437 case 6:
1432#ifdef CONFIG_PM 1438#ifdef CONFIG_PM
1433 if (nl80211_send_wowlan(msg, dev, split)) 1439 if (nl80211_send_wowlan(msg, dev, state->split))
1434 goto nla_put_failure; 1440 goto nla_put_failure;
1435 (*split_start)++; 1441 state->split_start++;
1436 if (split) 1442 if (state->split)
1437 break; 1443 break;
1438#else 1444#else
1439 (*split_start)++; 1445 state->split_start++;
1440#endif 1446#endif
1441 case 7: 1447 case 7:
1442 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, 1448 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1443 dev->wiphy.software_iftypes)) 1449 dev->wiphy.software_iftypes))
1444 goto nla_put_failure; 1450 goto nla_put_failure;
1445 1451
1446 if (nl80211_put_iface_combinations(&dev->wiphy, msg, split)) 1452 if (nl80211_put_iface_combinations(&dev->wiphy, msg,
1453 state->split))
1447 goto nla_put_failure; 1454 goto nla_put_failure;
1448 1455
1449 (*split_start)++; 1456 state->split_start++;
1450 if (split) 1457 if (state->split)
1451 break; 1458 break;
1452 case 8: 1459 case 8:
1453 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && 1460 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
@@ -1461,7 +1468,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1461 * dump is split, otherwise it makes it too big. Therefore 1468 * dump is split, otherwise it makes it too big. Therefore
1462 * only advertise it in that case. 1469 * only advertise it in that case.
1463 */ 1470 */
1464 if (split) 1471 if (state->split)
1465 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS; 1472 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
1466 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features)) 1473 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
1467 goto nla_put_failure; 1474 goto nla_put_failure;
@@ -1488,7 +1495,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1488 * case we'll continue with more data in the next round, 1495 * case we'll continue with more data in the next round,
1489 * but break unconditionally so unsplit data stops here. 1496 * but break unconditionally so unsplit data stops here.
1490 */ 1497 */
1491 (*split_start)++; 1498 state->split_start++;
1492 break; 1499 break;
1493 case 9: 1500 case 9:
1494 if (dev->wiphy.extended_capabilities && 1501 if (dev->wiphy.extended_capabilities &&
@@ -1507,7 +1514,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1507 goto nla_put_failure; 1514 goto nla_put_failure;
1508 1515
1509 /* done */ 1516 /* done */
1510 *split_start = 0; 1517 state->split_start = 0;
1511 break; 1518 break;
1512 } 1519 }
1513 return genlmsg_end(msg, hdr); 1520 return genlmsg_end(msg, hdr);
@@ -1517,59 +1524,76 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1517 return -EMSGSIZE; 1524 return -EMSGSIZE;
1518} 1525}
1519 1526
1527static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
1528 struct netlink_callback *cb,
1529 struct nl80211_dump_wiphy_state *state)
1530{
1531 struct nlattr **tb = nl80211_fam.attrbuf;
1532 int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1533 tb, nl80211_fam.maxattr, nl80211_policy);
1534 /* ignore parse errors for backward compatibility */
1535 if (ret)
1536 return 0;
1537
1538 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
1539 if (tb[NL80211_ATTR_WIPHY])
1540 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1541 if (tb[NL80211_ATTR_WDEV])
1542 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
1543 if (tb[NL80211_ATTR_IFINDEX]) {
1544 struct net_device *netdev;
1545 struct cfg80211_registered_device *rdev;
1546 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1547
1548 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1549 if (!netdev)
1550 return -ENODEV;
1551 if (netdev->ieee80211_ptr) {
1552 rdev = wiphy_to_dev(
1553 netdev->ieee80211_ptr->wiphy);
1554 state->filter_wiphy = rdev->wiphy_idx;
1555 }
1556 dev_put(netdev);
1557 }
1558
1559 return 0;
1560}
1561
1520static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) 1562static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1521{ 1563{
1522 int idx = 0, ret; 1564 int idx = 0, ret;
1523 int start = cb->args[0]; 1565 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1524 struct cfg80211_registered_device *dev; 1566 struct cfg80211_registered_device *dev;
1525 s64 filter_wiphy = -1;
1526 bool split = false;
1527 struct nlattr **tb = nl80211_fam.attrbuf;
1528 int res;
1529 1567
1530 rtnl_lock(); 1568 rtnl_lock();
1531 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1569 if (!state) {
1532 tb, nl80211_fam.maxattr, nl80211_policy); 1570 state = kzalloc(sizeof(*state), GFP_KERNEL);
1533 if (res == 0) { 1571 if (!state)
1534 split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; 1572 return -ENOMEM;
1535 if (tb[NL80211_ATTR_WIPHY]) 1573 state->filter_wiphy = -1;
1536 filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); 1574 ret = nl80211_dump_wiphy_parse(skb, cb, state);
1537 if (tb[NL80211_ATTR_WDEV]) 1575 if (ret) {
1538 filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32; 1576 kfree(state);
1539 if (tb[NL80211_ATTR_IFINDEX]) { 1577 rtnl_unlock();
1540 struct net_device *netdev; 1578 return ret;
1541 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1542
1543 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1544 if (!netdev) {
1545 rtnl_unlock();
1546 return -ENODEV;
1547 }
1548 if (netdev->ieee80211_ptr) {
1549 dev = wiphy_to_dev(
1550 netdev->ieee80211_ptr->wiphy);
1551 filter_wiphy = dev->wiphy_idx;
1552 }
1553 dev_put(netdev);
1554 } 1579 }
1580 cb->args[0] = (long)state;
1555 } 1581 }
1556 1582
1557 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 1583 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
1558 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) 1584 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
1559 continue; 1585 continue;
1560 if (++idx <= start) 1586 if (++idx <= state->start)
1561 continue; 1587 continue;
1562 if (filter_wiphy != -1 && dev->wiphy_idx != filter_wiphy) 1588 if (state->filter_wiphy != -1 &&
1589 state->filter_wiphy != dev->wiphy_idx)
1563 continue; 1590 continue;
1564 /* attempt to fit multiple wiphy data chunks into the skb */ 1591 /* attempt to fit multiple wiphy data chunks into the skb */
1565 do { 1592 do {
1566 ret = nl80211_send_wiphy(dev, skb, 1593 ret = nl80211_send_wiphy(dev, skb,
1567 NETLINK_CB(cb->skb).portid, 1594 NETLINK_CB(cb->skb).portid,
1568 cb->nlh->nlmsg_seq, 1595 cb->nlh->nlmsg_seq,
1569 NLM_F_MULTI, 1596 NLM_F_MULTI, state);
1570 split, &cb->args[1],
1571 &cb->args[2],
1572 &cb->args[3]);
1573 if (ret < 0) { 1597 if (ret < 0) {
1574 /* 1598 /*
1575 * If sending the wiphy data didn't fit (ENOBUFS 1599 * If sending the wiphy data didn't fit (ENOBUFS
@@ -1594,27 +1618,34 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1594 idx--; 1618 idx--;
1595 break; 1619 break;
1596 } 1620 }
1597 } while (cb->args[1] > 0); 1621 } while (state->split_start > 0);
1598 break; 1622 break;
1599 } 1623 }
1600 rtnl_unlock(); 1624 rtnl_unlock();
1601 1625
1602 cb->args[0] = idx; 1626 state->start = idx;
1603 1627
1604 return skb->len; 1628 return skb->len;
1605} 1629}
1606 1630
1631static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
1632{
1633 kfree((void *)cb->args[0]);
1634 return 0;
1635}
1636
1607static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) 1637static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1608{ 1638{
1609 struct sk_buff *msg; 1639 struct sk_buff *msg;
1610 struct cfg80211_registered_device *dev = info->user_ptr[0]; 1640 struct cfg80211_registered_device *dev = info->user_ptr[0];
1641 struct nl80211_dump_wiphy_state state = {};
1611 1642
1612 msg = nlmsg_new(4096, GFP_KERNEL); 1643 msg = nlmsg_new(4096, GFP_KERNEL);
1613 if (!msg) 1644 if (!msg)
1614 return -ENOMEM; 1645 return -ENOMEM;
1615 1646
1616 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0, 1647 if (nl80211_send_wiphy(dev, msg, info->snd_portid, info->snd_seq, 0,
1617 false, NULL, NULL, NULL) < 0) { 1648 &state) < 0) {
1618 nlmsg_free(msg); 1649 nlmsg_free(msg);
1619 return -ENOBUFS; 1650 return -ENOBUFS;
1620 } 1651 }
@@ -1731,6 +1762,11 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1731 IEEE80211_CHAN_DISABLED)) 1762 IEEE80211_CHAN_DISABLED))
1732 return -EINVAL; 1763 return -EINVAL;
1733 1764
1765 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
1766 chandef->width == NL80211_CHAN_WIDTH_10) &&
1767 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1768 return -EINVAL;
1769
1734 return 0; 1770 return 0;
1735} 1771}
1736 1772
@@ -2882,61 +2918,58 @@ static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
2882 return err; 2918 return err;
2883} 2919}
2884 2920
2885static int nl80211_parse_beacon(struct genl_info *info, 2921static int nl80211_parse_beacon(struct nlattr *attrs[],
2886 struct cfg80211_beacon_data *bcn) 2922 struct cfg80211_beacon_data *bcn)
2887{ 2923{
2888 bool haveinfo = false; 2924 bool haveinfo = false;
2889 2925
2890 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || 2926 if (!is_valid_ie_attr(attrs[NL80211_ATTR_BEACON_TAIL]) ||
2891 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || 2927 !is_valid_ie_attr(attrs[NL80211_ATTR_IE]) ||
2892 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || 2928 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2893 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) 2929 !is_valid_ie_attr(attrs[NL80211_ATTR_IE_ASSOC_RESP]))
2894 return -EINVAL; 2930 return -EINVAL;
2895 2931
2896 memset(bcn, 0, sizeof(*bcn)); 2932 memset(bcn, 0, sizeof(*bcn));
2897 2933
2898 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 2934 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
2899 bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2935 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
2900 bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2936 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
2901 if (!bcn->head_len) 2937 if (!bcn->head_len)
2902 return -EINVAL; 2938 return -EINVAL;
2903 haveinfo = true; 2939 haveinfo = true;
2904 } 2940 }
2905 2941
2906 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { 2942 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
2907 bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); 2943 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
2908 bcn->tail_len = 2944 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
2909 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
2910 haveinfo = true; 2945 haveinfo = true;
2911 } 2946 }
2912 2947
2913 if (!haveinfo) 2948 if (!haveinfo)
2914 return -EINVAL; 2949 return -EINVAL;
2915 2950
2916 if (info->attrs[NL80211_ATTR_IE]) { 2951 if (attrs[NL80211_ATTR_IE]) {
2917 bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); 2952 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
2918 bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); 2953 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
2919 } 2954 }
2920 2955
2921 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { 2956 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
2922 bcn->proberesp_ies = 2957 bcn->proberesp_ies =
2923 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); 2958 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
2924 bcn->proberesp_ies_len = 2959 bcn->proberesp_ies_len =
2925 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); 2960 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
2926 } 2961 }
2927 2962
2928 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { 2963 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
2929 bcn->assocresp_ies = 2964 bcn->assocresp_ies =
2930 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); 2965 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2931 bcn->assocresp_ies_len = 2966 bcn->assocresp_ies_len =
2932 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); 2967 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2933 } 2968 }
2934 2969
2935 if (info->attrs[NL80211_ATTR_PROBE_RESP]) { 2970 if (attrs[NL80211_ATTR_PROBE_RESP]) {
2936 bcn->probe_resp = 2971 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
2937 nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); 2972 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
2938 bcn->probe_resp_len =
2939 nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
2940 } 2973 }
2941 2974
2942 return 0; 2975 return 0;
@@ -3015,7 +3048,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3015 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 3048 !info->attrs[NL80211_ATTR_BEACON_HEAD])
3016 return -EINVAL; 3049 return -EINVAL;
3017 3050
3018 err = nl80211_parse_beacon(info, &params.beacon); 3051 err = nl80211_parse_beacon(info->attrs, &params.beacon);
3019 if (err) 3052 if (err)
3020 return err; 3053 return err;
3021 3054
@@ -3167,7 +3200,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3167 if (!wdev->beacon_interval) 3200 if (!wdev->beacon_interval)
3168 return -EINVAL; 3201 return -EINVAL;
3169 3202
3170 err = nl80211_parse_beacon(info, &params); 3203 err = nl80211_parse_beacon(info->attrs, &params);
3171 if (err) 3204 if (err)
3172 return err; 3205 return err;
3173 3206
@@ -6283,11 +6316,16 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
6283 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) 6316 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
6284 return -EINVAL; 6317 return -EINVAL;
6285 6318
6286 if (ibss.chandef.width > NL80211_CHAN_WIDTH_40) 6319 switch (ibss.chandef.width) {
6287 return -EINVAL; 6320 case NL80211_CHAN_WIDTH_20_NOHT:
6288 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 6321 break;
6289 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) 6322 case NL80211_CHAN_WIDTH_20:
6323 case NL80211_CHAN_WIDTH_40:
6324 if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)
6325 break;
6326 default:
6290 return -EINVAL; 6327 return -EINVAL;
6328 }
6291 6329
6292 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 6330 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
6293 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 6331 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
@@ -8401,6 +8439,7 @@ static struct genl_ops nl80211_ops[] = {
8401 .cmd = NL80211_CMD_GET_WIPHY, 8439 .cmd = NL80211_CMD_GET_WIPHY,
8402 .doit = nl80211_get_wiphy, 8440 .doit = nl80211_get_wiphy,
8403 .dumpit = nl80211_dump_wiphy, 8441 .dumpit = nl80211_dump_wiphy,
8442 .done = nl80211_dump_wiphy_done,
8404 .policy = nl80211_policy, 8443 .policy = nl80211_policy,
8405 /* can be retrieved by unprivileged users */ 8444 /* can be retrieved by unprivileged users */
8406 .internal_flags = NL80211_FLAG_NEED_WIPHY | 8445 .internal_flags = NL80211_FLAG_NEED_WIPHY |
@@ -9021,13 +9060,13 @@ static struct genl_multicast_group nl80211_regulatory_mcgrp = {
9021void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) 9060void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
9022{ 9061{
9023 struct sk_buff *msg; 9062 struct sk_buff *msg;
9063 struct nl80211_dump_wiphy_state state = {};
9024 9064
9025 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 9065 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
9026 if (!msg) 9066 if (!msg)
9027 return; 9067 return;
9028 9068
9029 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, 9069 if (nl80211_send_wiphy(rdev, msg, 0, 0, 0, &state) < 0) {
9030 false, NULL, NULL, NULL) < 0) {
9031 nlmsg_free(msg); 9070 nlmsg_free(msg);
9032 return; 9071 return;
9033 } 9072 }
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index dd01b58fa78c..ae8c186b50d6 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -523,6 +523,7 @@ static int cmp_bss(struct cfg80211_bss *a,
523 } 523 }
524} 524}
525 525
526/* Returned bss is reference counted and must be cleaned up appropriately. */
526struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 527struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
527 struct ieee80211_channel *channel, 528 struct ieee80211_channel *channel,
528 const u8 *bssid, 529 const u8 *bssid,
@@ -678,6 +679,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
678 return true; 679 return true;
679} 680}
680 681
682/* Returned bss is reference counted and must be cleaned up appropriately. */
681static struct cfg80211_internal_bss * 683static struct cfg80211_internal_bss *
682cfg80211_bss_update(struct cfg80211_registered_device *dev, 684cfg80211_bss_update(struct cfg80211_registered_device *dev,
683 struct cfg80211_internal_bss *tmp) 685 struct cfg80211_internal_bss *tmp)
@@ -866,6 +868,7 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
866 return channel; 868 return channel;
867} 869}
868 870
871/* Returned bss is reference counted and must be cleaned up appropriately. */
869struct cfg80211_bss* 872struct cfg80211_bss*
870cfg80211_inform_bss(struct wiphy *wiphy, 873cfg80211_inform_bss(struct wiphy *wiphy,
871 struct ieee80211_channel *channel, 874 struct ieee80211_channel *channel,
@@ -923,6 +926,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
923} 926}
924EXPORT_SYMBOL(cfg80211_inform_bss); 927EXPORT_SYMBOL(cfg80211_inform_bss);
925 928
929/* Returned bss is reference counted and must be cleaned up appropriately. */
926struct cfg80211_bss * 930struct cfg80211_bss *
927cfg80211_inform_bss_frame(struct wiphy *wiphy, 931cfg80211_inform_bss_frame(struct wiphy *wiphy,
928 struct ieee80211_channel *channel, 932 struct ieee80211_channel *channel,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index ae7e2cbf45cb..1d3cfb1a3f28 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -239,6 +239,7 @@ void cfg80211_conn_work(struct work_struct *work)
239 rtnl_unlock(); 239 rtnl_unlock();
240} 240}
241 241
242/* Returned bss is reference counted and must be cleaned up appropriately. */
242static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) 243static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
243{ 244{
244 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 245 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -557,6 +558,7 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
557 * SME event handling 558 * SME event handling
558 */ 559 */
559 560
561/* This method must consume bss one way or another */
560void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 562void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
561 const u8 *req_ie, size_t req_ie_len, 563 const u8 *req_ie, size_t req_ie_len,
562 const u8 *resp_ie, size_t resp_ie_len, 564 const u8 *resp_ie, size_t resp_ie_len,
@@ -572,8 +574,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
572 ASSERT_WDEV_LOCK(wdev); 574 ASSERT_WDEV_LOCK(wdev);
573 575
574 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && 576 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
575 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 577 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
578 cfg80211_put_bss(wdev->wiphy, bss);
576 return; 579 return;
580 }
577 581
578 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, 582 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
579 bssid, req_ie, req_ie_len, 583 bssid, req_ie, req_ie_len,
@@ -615,19 +619,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
615 kfree(wdev->connect_keys); 619 kfree(wdev->connect_keys);
616 wdev->connect_keys = NULL; 620 wdev->connect_keys = NULL;
617 wdev->ssid_len = 0; 621 wdev->ssid_len = 0;
618 cfg80211_put_bss(wdev->wiphy, bss); 622 if (bss) {
623 cfg80211_unhold_bss(bss_from_pub(bss));
624 cfg80211_put_bss(wdev->wiphy, bss);
625 }
619 return; 626 return;
620 } 627 }
621 628
622 if (!bss) 629 if (!bss) {
630 WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect);
623 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 631 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
624 wdev->ssid, wdev->ssid_len, 632 wdev->ssid, wdev->ssid_len,
625 WLAN_CAPABILITY_ESS, 633 WLAN_CAPABILITY_ESS,
626 WLAN_CAPABILITY_ESS); 634 WLAN_CAPABILITY_ESS);
627 if (WARN_ON(!bss)) 635 if (WARN_ON(!bss))
628 return; 636 return;
637 cfg80211_hold_bss(bss_from_pub(bss));
638 }
629 639
630 cfg80211_hold_bss(bss_from_pub(bss));
631 wdev->current_bss = bss_from_pub(bss); 640 wdev->current_bss = bss_from_pub(bss);
632 641
633 cfg80211_upload_connect_keys(wdev); 642 cfg80211_upload_connect_keys(wdev);
@@ -691,6 +700,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
691} 700}
692EXPORT_SYMBOL(cfg80211_connect_result); 701EXPORT_SYMBOL(cfg80211_connect_result);
693 702
703/* Consumes bss object one way or another */
694void __cfg80211_roamed(struct wireless_dev *wdev, 704void __cfg80211_roamed(struct wireless_dev *wdev,
695 struct cfg80211_bss *bss, 705 struct cfg80211_bss *bss,
696 const u8 *req_ie, size_t req_ie_len, 706 const u8 *req_ie, size_t req_ie_len,
@@ -767,6 +777,7 @@ void cfg80211_roamed(struct net_device *dev,
767} 777}
768EXPORT_SYMBOL(cfg80211_roamed); 778EXPORT_SYMBOL(cfg80211_roamed);
769 779
780/* Consumes bss object one way or another */
770void cfg80211_roamed_bss(struct net_device *dev, 781void cfg80211_roamed_bss(struct net_device *dev,
771 struct cfg80211_bss *bss, const u8 *req_ie, 782 struct cfg80211_bss *bss, const u8 *req_ie,
772 size_t req_ie_len, const u8 *resp_ie, 783 size_t req_ie_len, const u8 *resp_ie,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 360a42c6f694..a23253e06358 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -83,6 +83,7 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
83 return 0; 83 return 0;
84} 84}
85 85
86#ifdef CONFIG_PM
86static void cfg80211_leave_all(struct cfg80211_registered_device *rdev) 87static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
87{ 88{
88 struct wireless_dev *wdev; 89 struct wireless_dev *wdev;
@@ -91,7 +92,6 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91 cfg80211_leave(rdev, wdev); 92 cfg80211_leave(rdev, wdev);
92} 93}
93 94
94#ifdef CONFIG_PM
95static int wiphy_suspend(struct device *dev, pm_message_t state) 95static int wiphy_suspend(struct device *dev, pm_message_t state)
96{ 96{
97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev); 97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);