diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-02-24 15:03:32 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-24 15:03:32 -0500 |
commit | c77986c78aa941af8266272841567e78b72d54cc (patch) | |
tree | cb30e1bd7d5799bfce5a3837bcfddee059a81733 /net | |
parent | 9e4b4269ecee426f1647425a24186dd1566db554 (diff) | |
parent | 6658ab80fd4ef940fc2366ddb66690a15ea69c18 (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 13 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 12 | ||||
-rw-r--r-- | net/mac80211/ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 11 | ||||
-rw-r--r-- | net/mac80211/main.c | 12 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 72 | ||||
-rw-r--r-- | net/mac80211/rx.c | 5 | ||||
-rw-r--r-- | net/mac80211/scan.c | 9 | ||||
-rw-r--r-- | net/wireless/chan.c | 6 | ||||
-rw-r--r-- | net/wireless/genregdb.awk | 2 | ||||
-rw-r--r-- | net/wireless/ibss.c | 7 | ||||
-rw-r--r-- | net/wireless/mesh.c | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 33 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 9 | ||||
-rw-r--r-- | net/wireless/reg.c | 83 | ||||
-rw-r--r-- | net/wireless/trace.h | 12 | ||||
-rw-r--r-- | net/wireless/util.c | 31 |
20 files changed, 212 insertions, 127 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 363d19b5d5c8..1acb29109b45 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1347,9 +1347,6 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1347 | params->vht_capa, sta); | 1347 | params->vht_capa, sta); |
1348 | 1348 | ||
1349 | if (params->opmode_notif_used) { | 1349 | if (params->opmode_notif_used) { |
1350 | enum ieee80211_band band = | ||
1351 | ieee80211_get_sdata_band(sdata); | ||
1352 | |||
1353 | /* returned value is only needed for rc update, but the | 1350 | /* returned value is only needed for rc update, but the |
1354 | * rc isn't initialized here yet, so ignore it | 1351 | * rc isn't initialized here yet, so ignore it |
1355 | */ | 1352 | */ |
@@ -3647,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
3647 | 3644 | ||
3648 | static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | 3645 | static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, |
3649 | u8 *peer, u8 action_code, u8 dialog_token, | 3646 | u8 *peer, u8 action_code, u8 dialog_token, |
3650 | u16 status_code, const u8 *extra_ies, | 3647 | u16 status_code, u32 peer_capability, |
3651 | size_t extra_ies_len) | 3648 | const u8 *extra_ies, size_t extra_ies_len) |
3652 | { | 3649 | { |
3653 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3650 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3654 | struct ieee80211_local *local = sdata->local; | 3651 | struct ieee80211_local *local = sdata->local; |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ebf80f3abd83..40a648938985 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -358,6 +358,18 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
358 | } | 358 | } |
359 | IEEE80211_IF_FILE_W(tkip_mic_test); | 359 | IEEE80211_IF_FILE_W(tkip_mic_test); |
360 | 360 | ||
361 | static ssize_t ieee80211_if_parse_beacon_loss( | ||
362 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) | ||
363 | { | ||
364 | if (!ieee80211_sdata_running(sdata) || !sdata->vif.bss_conf.assoc) | ||
365 | return -ENOTCONN; | ||
366 | |||
367 | ieee80211_beacon_loss(&sdata->vif); | ||
368 | |||
369 | return buflen; | ||
370 | } | ||
371 | IEEE80211_IF_FILE_W(beacon_loss); | ||
372 | |||
361 | static ssize_t ieee80211_if_fmt_uapsd_queues( | 373 | static ssize_t ieee80211_if_fmt_uapsd_queues( |
362 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 374 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
363 | { | 375 | { |
@@ -569,6 +581,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
569 | DEBUGFS_ADD(beacon_timeout); | 581 | DEBUGFS_ADD(beacon_timeout); |
570 | DEBUGFS_ADD_MODE(smps, 0600); | 582 | DEBUGFS_ADD_MODE(smps, 0600); |
571 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); | 583 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); |
584 | DEBUGFS_ADD_MODE(beacon_loss, 0200); | ||
572 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); | 585 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); |
573 | DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); | 586 | DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); |
574 | } | 587 | } |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ef8b385eff04..fc689f5d971e 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -354,16 +354,20 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
354 | return ret; | 354 | return ret; |
355 | } | 355 | } |
356 | 356 | ||
357 | static inline void drv_sched_scan_stop(struct ieee80211_local *local, | 357 | static inline int drv_sched_scan_stop(struct ieee80211_local *local, |
358 | struct ieee80211_sub_if_data *sdata) | 358 | struct ieee80211_sub_if_data *sdata) |
359 | { | 359 | { |
360 | int ret; | ||
361 | |||
360 | might_sleep(); | 362 | might_sleep(); |
361 | 363 | ||
362 | check_sdata_in_driver(sdata); | 364 | check_sdata_in_driver(sdata); |
363 | 365 | ||
364 | trace_drv_sched_scan_stop(local, sdata); | 366 | trace_drv_sched_scan_stop(local, sdata); |
365 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 367 | ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
366 | trace_drv_return_void(local); | 368 | trace_drv_return_int(local, ret); |
369 | |||
370 | return ret; | ||
367 | } | 371 | } |
368 | 372 | ||
369 | static inline void drv_sw_scan_start(struct ieee80211_local *local) | 373 | static inline void drv_sw_scan_start(struct ieee80211_local *local) |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index afbe2b203c3e..c150b68436d7 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -482,8 +482,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, | |||
482 | return; | 482 | return; |
483 | 483 | ||
484 | if (vif->type == NL80211_IFTYPE_STATION) { | 484 | if (vif->type == NL80211_IFTYPE_STATION) { |
485 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
486 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
487 | if (sdata->u.mgd.driver_smps_mode == smps_mode) | 485 | if (sdata->u.mgd.driver_smps_mode == smps_mode) |
488 | return; | 486 | return; |
489 | sdata->u.mgd.driver_smps_mode = smps_mode; | 487 | sdata->u.mgd.driver_smps_mode = smps_mode; |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 4453e2725e40..e458ca0dffec 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -283,6 +283,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
283 | 283 | ||
284 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, | 284 | err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy, |
285 | &chandef); | 285 | &chandef); |
286 | if (err < 0) { | ||
287 | sdata_info(sdata, | ||
288 | "Failed to join IBSS, invalid chandef\n"); | ||
289 | return; | ||
290 | } | ||
286 | if (err > 0) { | 291 | if (err > 0) { |
287 | if (!ifibss->userspace_handles_dfs) { | 292 | if (!ifibss->userspace_handles_dfs) { |
288 | sdata_info(sdata, | 293 | sdata_info(sdata, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0014b5396ce5..8603dfb52b3a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1242,6 +1242,8 @@ struct ieee80211_local { | |||
1242 | 1242 | ||
1243 | struct ieee80211_sub_if_data __rcu *p2p_sdata; | 1243 | struct ieee80211_sub_if_data __rcu *p2p_sdata; |
1244 | 1244 | ||
1245 | struct napi_struct *napi; | ||
1246 | |||
1245 | /* virtual monitor interface */ | 1247 | /* virtual monitor interface */ |
1246 | struct ieee80211_sub_if_data __rcu *monitor_sdata; | 1248 | struct ieee80211_sub_if_data __rcu *monitor_sdata; |
1247 | struct cfg80211_chan_def monitor_chandef; | 1249 | struct cfg80211_chan_def monitor_chandef; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 96518ad200c4..be198f42f1f7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -101,9 +101,8 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local) | |||
101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, | 101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, |
102 | bool force_active) | 102 | bool force_active) |
103 | { | 103 | { |
104 | bool working = false, scanning, active; | 104 | bool working, scanning, active; |
105 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 105 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
106 | struct ieee80211_roc_work *roc; | ||
107 | 106 | ||
108 | lockdep_assert_held(&local->mtx); | 107 | lockdep_assert_held(&local->mtx); |
109 | 108 | ||
@@ -111,12 +110,8 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, | |||
111 | !list_empty(&local->chanctx_list) || | 110 | !list_empty(&local->chanctx_list) || |
112 | local->monitors; | 111 | local->monitors; |
113 | 112 | ||
114 | if (!local->ops->remain_on_channel) { | 113 | working = !local->ops->remain_on_channel && |
115 | list_for_each_entry(roc, &local->roc_list, list) { | 114 | !list_empty(&local->roc_list); |
116 | working = true; | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | 115 | ||
121 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || | 116 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || |
122 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); | 117 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1f7d8422d62d..b055f6a55c68 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1076,6 +1076,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1076 | } | 1076 | } |
1077 | EXPORT_SYMBOL(ieee80211_register_hw); | 1077 | EXPORT_SYMBOL(ieee80211_register_hw); |
1078 | 1078 | ||
1079 | void ieee80211_napi_add(struct ieee80211_hw *hw, struct napi_struct *napi, | ||
1080 | struct net_device *napi_dev, | ||
1081 | int (*poll)(struct napi_struct *, int), | ||
1082 | int weight) | ||
1083 | { | ||
1084 | struct ieee80211_local *local = hw_to_local(hw); | ||
1085 | |||
1086 | netif_napi_add(napi_dev, napi, poll, weight); | ||
1087 | local->napi = napi; | ||
1088 | } | ||
1089 | EXPORT_SYMBOL_GPL(ieee80211_napi_add); | ||
1090 | |||
1079 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1091 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1080 | { | 1092 | { |
1081 | struct ieee80211_local *local = hw_to_local(hw); | 1093 | struct ieee80211_local *local = hw_to_local(hw); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 61604834b914..46b62bb3677c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -131,13 +131,13 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) | |||
131 | if (unlikely(!sdata->u.mgd.associated)) | 131 | if (unlikely(!sdata->u.mgd.associated)) |
132 | return; | 132 | return; |
133 | 133 | ||
134 | ifmgd->probe_send_count = 0; | ||
135 | |||
134 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 136 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
135 | return; | 137 | return; |
136 | 138 | ||
137 | mod_timer(&sdata->u.mgd.conn_mon_timer, | 139 | mod_timer(&sdata->u.mgd.conn_mon_timer, |
138 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 140 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
139 | |||
140 | ifmgd->probe_send_count = 0; | ||
141 | } | 141 | } |
142 | 142 | ||
143 | static int ecw2cw(int ecw) | 143 | static int ecw2cw(int ecw) |
@@ -2249,6 +2249,62 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2249 | /* ignore frame -- wait for timeout */ | 2249 | /* ignore frame -- wait for timeout */ |
2250 | } | 2250 | } |
2251 | 2251 | ||
2252 | #define case_WLAN(type) \ | ||
2253 | case WLAN_REASON_##type: return #type | ||
2254 | |||
2255 | static const char *ieee80211_get_reason_code_string(u16 reason_code) | ||
2256 | { | ||
2257 | switch (reason_code) { | ||
2258 | case_WLAN(UNSPECIFIED); | ||
2259 | case_WLAN(PREV_AUTH_NOT_VALID); | ||
2260 | case_WLAN(DEAUTH_LEAVING); | ||
2261 | case_WLAN(DISASSOC_DUE_TO_INACTIVITY); | ||
2262 | case_WLAN(DISASSOC_AP_BUSY); | ||
2263 | case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA); | ||
2264 | case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA); | ||
2265 | case_WLAN(DISASSOC_STA_HAS_LEFT); | ||
2266 | case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH); | ||
2267 | case_WLAN(DISASSOC_BAD_POWER); | ||
2268 | case_WLAN(DISASSOC_BAD_SUPP_CHAN); | ||
2269 | case_WLAN(INVALID_IE); | ||
2270 | case_WLAN(MIC_FAILURE); | ||
2271 | case_WLAN(4WAY_HANDSHAKE_TIMEOUT); | ||
2272 | case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT); | ||
2273 | case_WLAN(IE_DIFFERENT); | ||
2274 | case_WLAN(INVALID_GROUP_CIPHER); | ||
2275 | case_WLAN(INVALID_PAIRWISE_CIPHER); | ||
2276 | case_WLAN(INVALID_AKMP); | ||
2277 | case_WLAN(UNSUPP_RSN_VERSION); | ||
2278 | case_WLAN(INVALID_RSN_IE_CAP); | ||
2279 | case_WLAN(IEEE8021X_FAILED); | ||
2280 | case_WLAN(CIPHER_SUITE_REJECTED); | ||
2281 | case_WLAN(DISASSOC_UNSPECIFIED_QOS); | ||
2282 | case_WLAN(DISASSOC_QAP_NO_BANDWIDTH); | ||
2283 | case_WLAN(DISASSOC_LOW_ACK); | ||
2284 | case_WLAN(DISASSOC_QAP_EXCEED_TXOP); | ||
2285 | case_WLAN(QSTA_LEAVE_QBSS); | ||
2286 | case_WLAN(QSTA_NOT_USE); | ||
2287 | case_WLAN(QSTA_REQUIRE_SETUP); | ||
2288 | case_WLAN(QSTA_TIMEOUT); | ||
2289 | case_WLAN(QSTA_CIPHER_NOT_SUPP); | ||
2290 | case_WLAN(MESH_PEER_CANCELED); | ||
2291 | case_WLAN(MESH_MAX_PEERS); | ||
2292 | case_WLAN(MESH_CONFIG); | ||
2293 | case_WLAN(MESH_CLOSE); | ||
2294 | case_WLAN(MESH_MAX_RETRIES); | ||
2295 | case_WLAN(MESH_CONFIRM_TIMEOUT); | ||
2296 | case_WLAN(MESH_INVALID_GTK); | ||
2297 | case_WLAN(MESH_INCONSISTENT_PARAM); | ||
2298 | case_WLAN(MESH_INVALID_SECURITY); | ||
2299 | case_WLAN(MESH_PATH_ERROR); | ||
2300 | case_WLAN(MESH_PATH_NOFORWARD); | ||
2301 | case_WLAN(MESH_PATH_DEST_UNREACHABLE); | ||
2302 | case_WLAN(MAC_EXISTS_IN_MBSS); | ||
2303 | case_WLAN(MESH_CHAN_REGULATORY); | ||
2304 | case_WLAN(MESH_CHAN); | ||
2305 | default: return "<unknown>"; | ||
2306 | } | ||
2307 | } | ||
2252 | 2308 | ||
2253 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | 2309 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
2254 | struct ieee80211_mgmt *mgmt, size_t len) | 2310 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -2270,8 +2326,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2270 | 2326 | ||
2271 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 2327 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
2272 | 2328 | ||
2273 | sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", | 2329 | sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n", |
2274 | bssid, reason_code); | 2330 | bssid, reason_code, ieee80211_get_reason_code_string(reason_code)); |
2275 | 2331 | ||
2276 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2332 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2277 | 2333 | ||
@@ -4340,8 +4396,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4340 | bool report_frame = false; | 4396 | bool report_frame = false; |
4341 | 4397 | ||
4342 | sdata_info(sdata, | 4398 | sdata_info(sdata, |
4343 | "deauthenticating from %pM by local choice (reason=%d)\n", | 4399 | "deauthenticating from %pM by local choice (Reason: %u=%s)\n", |
4344 | req->bssid, req->reason_code); | 4400 | req->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code)); |
4345 | 4401 | ||
4346 | if (ifmgd->auth_data) { | 4402 | if (ifmgd->auth_data) { |
4347 | drv_mgd_prepare_tx(sdata->local, sdata); | 4403 | drv_mgd_prepare_tx(sdata->local, sdata); |
@@ -4387,8 +4443,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4387 | return -ENOLINK; | 4443 | return -ENOLINK; |
4388 | 4444 | ||
4389 | sdata_info(sdata, | 4445 | sdata_info(sdata, |
4390 | "disassociating from %pM by local choice (reason=%d)\n", | 4446 | "disassociating from %pM by local choice (Reason: %u=%s)\n", |
4391 | req->bss->bssid, req->reason_code); | 4447 | req->bss->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code)); |
4392 | 4448 | ||
4393 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 4449 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
4394 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, | 4450 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 593062109c50..58e4b7052d17 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1954,7 +1954,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1954 | /* deliver to local stack */ | 1954 | /* deliver to local stack */ |
1955 | skb->protocol = eth_type_trans(skb, dev); | 1955 | skb->protocol = eth_type_trans(skb, dev); |
1956 | memset(skb->cb, 0, sizeof(skb->cb)); | 1956 | memset(skb->cb, 0, sizeof(skb->cb)); |
1957 | netif_receive_skb(skb); | 1957 | if (rx->local->napi) |
1958 | napi_gro_receive(rx->local->napi, skb); | ||
1959 | else | ||
1960 | netif_receive_skb(skb); | ||
1958 | } | 1961 | } |
1959 | 1962 | ||
1960 | if (xmit_skb) { | 1963 | if (xmit_skb) { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 88c81616f8f7..836f500dfbf3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -472,9 +472,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
472 | if (local->ops->hw_scan) { | 472 | if (local->ops->hw_scan) { |
473 | u8 *ies; | 473 | u8 *ies; |
474 | 474 | ||
475 | local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN + | 475 | local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len; |
476 | local->scan_ies_len + | ||
477 | req->ie_len; | ||
478 | local->hw_scan_req = kmalloc( | 476 | local->hw_scan_req = kmalloc( |
479 | sizeof(*local->hw_scan_req) + | 477 | sizeof(*local->hw_scan_req) + |
480 | req->n_channels * sizeof(req->channels[0]) + | 478 | req->n_channels * sizeof(req->channels[0]) + |
@@ -979,8 +977,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
979 | struct cfg80211_chan_def chandef; | 977 | struct cfg80211_chan_def chandef; |
980 | int ret, i, iebufsz; | 978 | int ret, i, iebufsz; |
981 | 979 | ||
982 | iebufsz = 2 + IEEE80211_MAX_SSID_LEN + | 980 | iebufsz = local->scan_ies_len + req->ie_len; |
983 | local->scan_ies_len + req->ie_len; | ||
984 | 981 | ||
985 | lockdep_assert_held(&local->mtx); | 982 | lockdep_assert_held(&local->mtx); |
986 | 983 | ||
@@ -1059,7 +1056,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) | |||
1059 | local->sched_scan_req = NULL; | 1056 | local->sched_scan_req = NULL; |
1060 | 1057 | ||
1061 | if (rcu_access_pointer(local->sched_scan_sdata)) | 1058 | if (rcu_access_pointer(local->sched_scan_sdata)) |
1062 | drv_sched_scan_stop(local, sdata); | 1059 | ret = drv_sched_scan_stop(local, sdata); |
1063 | 1060 | ||
1064 | out: | 1061 | out: |
1065 | mutex_unlock(&local->mtx); | 1062 | mutex_unlock(&local->mtx); |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index f8ab7df1ab0d..5946450c5406 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -705,12 +705,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
705 | case NL80211_IFTYPE_MONITOR: | 705 | case NL80211_IFTYPE_MONITOR: |
706 | case NL80211_IFTYPE_AP_VLAN: | 706 | case NL80211_IFTYPE_AP_VLAN: |
707 | case NL80211_IFTYPE_WDS: | 707 | case NL80211_IFTYPE_WDS: |
708 | /* these interface types don't really have a channel */ | ||
709 | return; | ||
710 | case NL80211_IFTYPE_P2P_DEVICE: | 708 | case NL80211_IFTYPE_P2P_DEVICE: |
711 | if (wdev->wiphy->features & | 709 | /* these interface types don't really have a channel */ |
712 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) | ||
713 | *chanmode = CHAN_MODE_EXCLUSIVE; | ||
714 | return; | 710 | return; |
715 | case NL80211_IFTYPE_UNSPECIFIED: | 711 | case NL80211_IFTYPE_UNSPECIFIED: |
716 | case NUM_NL80211_IFTYPES: | 712 | case NUM_NL80211_IFTYPES: |
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk index 9a8217d2a908..fdfd3f063a9b 100644 --- a/net/wireless/genregdb.awk +++ b/net/wireless/genregdb.awk | |||
@@ -105,6 +105,8 @@ function parse_reg_rule() | |||
105 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " | 105 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " |
106 | } else if (flagarray[arg] == "NO-IR") { | 106 | } else if (flagarray[arg] == "NO-IR") { |
107 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " | 107 | flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " |
108 | } else if (flagarray[arg] == "AUTO-BW") { | ||
109 | flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | " | ||
108 | } | 110 | } |
109 | 111 | ||
110 | } | 112 | } |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 1470b90e438f..349db9ddc0d1 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -128,12 +128,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
128 | #endif | 128 | #endif |
129 | check_chan = params->chandef.chan; | 129 | check_chan = params->chandef.chan; |
130 | if (params->userspace_handles_dfs) { | 130 | if (params->userspace_handles_dfs) { |
131 | /* use channel NULL to check for radar even if the current | 131 | /* Check for radar even if the current channel is not |
132 | * channel is not a radar channel - it might decide to change | 132 | * a radar channel - it might decide to change to DFS |
133 | * to DFS channel later. | 133 | * channel later. |
134 | */ | 134 | */ |
135 | radar_detect_width = BIT(params->chandef.width); | 135 | radar_detect_width = BIT(params->chandef.width); |
136 | check_chan = NULL; | ||
137 | } | 136 | } |
138 | 137 | ||
139 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | 138 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index d42a3fcb2f67..5af5cc6b2c4c 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -236,6 +236,12 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
236 | if (!netif_running(wdev->netdev)) | 236 | if (!netif_running(wdev->netdev)) |
237 | return -ENETDOWN; | 237 | return -ENETDOWN; |
238 | 238 | ||
239 | /* cfg80211_can_use_chan() calls | ||
240 | * cfg80211_can_use_iftype_chan() with no radar | ||
241 | * detection, so if we're trying to use a radar | ||
242 | * channel here, something is wrong. | ||
243 | */ | ||
244 | WARN_ON_ONCE(chandef->chan->flags & IEEE80211_CHAN_RADAR); | ||
239 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, | 245 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, |
240 | CHAN_MODE_SHARED); | 246 | CHAN_MODE_SHARED); |
241 | if (err) | 247 | if (err) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8e6b6a2d35cb..2c38b28a85b9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
384 | .len = IEEE80211_QOS_MAP_LEN_MAX }, | 384 | .len = IEEE80211_QOS_MAP_LEN_MAX }, |
385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, | 385 | [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN }, |
386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, | 386 | [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, |
387 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, | ||
387 | }; | 388 | }; |
388 | 389 | ||
389 | /* policy for the key attributes */ | 390 | /* policy for the key attributes */ |
@@ -4627,6 +4628,8 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4627 | return -EINVAL; | 4628 | return -EINVAL; |
4628 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) | 4629 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) |
4629 | return -EINVAL; | 4630 | return -EINVAL; |
4631 | if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) | ||
4632 | return -EINVAL; | ||
4630 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) | 4633 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) |
4631 | return -EINVAL; | 4634 | return -EINVAL; |
4632 | 4635 | ||
@@ -4636,9 +4639,8 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4636 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); | 4639 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); |
4637 | freq_range->end_freq_khz = | 4640 | freq_range->end_freq_khz = |
4638 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); | 4641 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); |
4639 | if (tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) | 4642 | freq_range->max_bandwidth_khz = |
4640 | freq_range->max_bandwidth_khz = | 4643 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); |
4641 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); | ||
4642 | 4644 | ||
4643 | power_rule->max_eirp = | 4645 | power_rule->max_eirp = |
4644 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); | 4646 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); |
@@ -5710,8 +5712,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
5710 | request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; | 5712 | request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF; |
5711 | } | 5713 | } |
5712 | 5714 | ||
5713 | if (info->attrs[NL80211_ATTR_IE]) { | 5715 | if (ie_len) { |
5714 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5716 | request->ie_len = ie_len; |
5715 | memcpy((void *)request->ie, | 5717 | memcpy((void *)request->ie, |
5716 | nla_data(info->attrs[NL80211_ATTR_IE]), | 5718 | nla_data(info->attrs[NL80211_ATTR_IE]), |
5717 | request->ie_len); | 5719 | request->ie_len); |
@@ -5911,17 +5913,22 @@ skip_beacons: | |||
5911 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 5913 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) |
5912 | return -EINVAL; | 5914 | return -EINVAL; |
5913 | 5915 | ||
5914 | if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP || | 5916 | switch (dev->ieee80211_ptr->iftype) { |
5915 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO || | 5917 | case NL80211_IFTYPE_AP: |
5916 | dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) { | 5918 | case NL80211_IFTYPE_P2P_GO: |
5919 | case NL80211_IFTYPE_ADHOC: | ||
5920 | case NL80211_IFTYPE_MESH_POINT: | ||
5917 | err = cfg80211_chandef_dfs_required(wdev->wiphy, | 5921 | err = cfg80211_chandef_dfs_required(wdev->wiphy, |
5918 | ¶ms.chandef); | 5922 | ¶ms.chandef); |
5919 | if (err < 0) { | 5923 | if (err < 0) |
5920 | return err; | 5924 | return err; |
5921 | } else if (err) { | 5925 | if (err) { |
5922 | radar_detect_width = BIT(params.chandef.width); | 5926 | radar_detect_width = BIT(params.chandef.width); |
5923 | params.radar_required = true; | 5927 | params.radar_required = true; |
5924 | } | 5928 | } |
5929 | break; | ||
5930 | default: | ||
5931 | break; | ||
5925 | } | 5932 | } |
5926 | 5933 | ||
5927 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, | 5934 | err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, |
@@ -7269,6 +7276,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7269 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7276 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7270 | struct net_device *dev = info->user_ptr[1]; | 7277 | struct net_device *dev = info->user_ptr[1]; |
7271 | u8 action_code, dialog_token; | 7278 | u8 action_code, dialog_token; |
7279 | u32 peer_capability = 0; | ||
7272 | u16 status_code; | 7280 | u16 status_code; |
7273 | u8 *peer; | 7281 | u8 *peer; |
7274 | 7282 | ||
@@ -7287,9 +7295,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
7287 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); | 7295 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); |
7288 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); | 7296 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); |
7289 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); | 7297 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); |
7298 | if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]) | ||
7299 | peer_capability = | ||
7300 | nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]); | ||
7290 | 7301 | ||
7291 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, | 7302 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, |
7292 | dialog_token, status_code, | 7303 | dialog_token, status_code, peer_capability, |
7293 | nla_data(info->attrs[NL80211_ATTR_IE]), | 7304 | nla_data(info->attrs[NL80211_ATTR_IE]), |
7294 | nla_len(info->attrs[NL80211_ATTR_IE])); | 7305 | nla_len(info->attrs[NL80211_ATTR_IE])); |
7295 | } | 7306 | } |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index c8e225947adb..74d97d33c938 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev, | |||
769 | static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, | 769 | static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, |
770 | struct net_device *dev, u8 *peer, | 770 | struct net_device *dev, u8 *peer, |
771 | u8 action_code, u8 dialog_token, | 771 | u8 action_code, u8 dialog_token, |
772 | u16 status_code, const u8 *buf, size_t len) | 772 | u16 status_code, u32 peer_capability, |
773 | const u8 *buf, size_t len) | ||
773 | { | 774 | { |
774 | int ret; | 775 | int ret; |
775 | trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | 776 | trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, |
776 | dialog_token, status_code, buf, len); | 777 | dialog_token, status_code, peer_capability, |
778 | buf, len); | ||
777 | ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, | 779 | ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, |
778 | dialog_token, status_code, buf, len); | 780 | dialog_token, status_code, peer_capability, |
781 | buf, len); | ||
779 | trace_rdev_return_int(&rdev->wiphy, ret); | 782 | trace_rdev_return_int(&rdev->wiphy, ret); |
780 | return ret; | 783 | return ret; |
781 | } | 784 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 27c5253e7a61..6b6f33ad78f2 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -563,9 +563,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, | |||
563 | if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) | 563 | if (freq_range_tmp->end_freq_khz < freq_range->start_freq_khz) |
564 | break; | 564 | break; |
565 | 565 | ||
566 | if (freq_range_tmp->max_bandwidth_khz) | ||
567 | break; | ||
568 | |||
569 | freq_range = freq_range_tmp; | 566 | freq_range = freq_range_tmp; |
570 | } | 567 | } |
571 | 568 | ||
@@ -582,9 +579,6 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd, | |||
582 | if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) | 579 | if (freq_range_tmp->start_freq_khz > freq_range->end_freq_khz) |
583 | break; | 580 | break; |
584 | 581 | ||
585 | if (freq_range_tmp->max_bandwidth_khz) | ||
586 | break; | ||
587 | |||
588 | freq_range = freq_range_tmp; | 582 | freq_range = freq_range_tmp; |
589 | } | 583 | } |
590 | 584 | ||
@@ -729,21 +723,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
729 | max_bandwidth1 = freq_range1->max_bandwidth_khz; | 723 | max_bandwidth1 = freq_range1->max_bandwidth_khz; |
730 | max_bandwidth2 = freq_range2->max_bandwidth_khz; | 724 | max_bandwidth2 = freq_range2->max_bandwidth_khz; |
731 | 725 | ||
732 | /* | 726 | if (rule1->flags & NL80211_RRF_AUTO_BW) |
733 | * In case max_bandwidth1 == 0 and max_bandwith2 == 0 set | 727 | max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); |
734 | * output bandwidth as 0 (auto calculation). Next we will | 728 | if (rule2->flags & NL80211_RRF_AUTO_BW) |
735 | * calculate this correctly in handle_channel function. | 729 | max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); |
736 | * In other case calculate output bandwidth here. | ||
737 | */ | ||
738 | if (max_bandwidth1 || max_bandwidth2) { | ||
739 | if (!max_bandwidth1) | ||
740 | max_bandwidth1 = reg_get_max_bandwidth(rd1, rule1); | ||
741 | if (!max_bandwidth2) | ||
742 | max_bandwidth2 = reg_get_max_bandwidth(rd2, rule2); | ||
743 | } | ||
744 | 730 | ||
745 | freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); | 731 | freq_range->max_bandwidth_khz = min(max_bandwidth1, max_bandwidth2); |
746 | 732 | ||
733 | intersected_rule->flags = rule1->flags | rule2->flags; | ||
734 | |||
735 | /* | ||
736 | * In case NL80211_RRF_AUTO_BW requested for both rules | ||
737 | * set AUTO_BW in intersected rule also. Next we will | ||
738 | * calculate BW correctly in handle_channel function. | ||
739 | * In other case remove AUTO_BW flag while we calculate | ||
740 | * maximum bandwidth correctly and auto calculation is | ||
741 | * not required. | ||
742 | */ | ||
743 | if ((rule1->flags & NL80211_RRF_AUTO_BW) && | ||
744 | (rule2->flags & NL80211_RRF_AUTO_BW)) | ||
745 | intersected_rule->flags |= NL80211_RRF_AUTO_BW; | ||
746 | else | ||
747 | intersected_rule->flags &= ~NL80211_RRF_AUTO_BW; | ||
748 | |||
747 | freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; | 749 | freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; |
748 | if (freq_range->max_bandwidth_khz > freq_diff) | 750 | if (freq_range->max_bandwidth_khz > freq_diff) |
749 | freq_range->max_bandwidth_khz = freq_diff; | 751 | freq_range->max_bandwidth_khz = freq_diff; |
@@ -753,8 +755,6 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
753 | power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, | 755 | power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain, |
754 | power_rule2->max_antenna_gain); | 756 | power_rule2->max_antenna_gain); |
755 | 757 | ||
756 | intersected_rule->flags = rule1->flags | rule2->flags; | ||
757 | |||
758 | if (!is_valid_reg_rule(intersected_rule)) | 758 | if (!is_valid_reg_rule(intersected_rule)) |
759 | return -EINVAL; | 759 | return -EINVAL; |
760 | 760 | ||
@@ -938,31 +938,42 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator) | |||
938 | EXPORT_SYMBOL(reg_initiator_name); | 938 | EXPORT_SYMBOL(reg_initiator_name); |
939 | 939 | ||
940 | #ifdef CONFIG_CFG80211_REG_DEBUG | 940 | #ifdef CONFIG_CFG80211_REG_DEBUG |
941 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, | 941 | static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
942 | struct ieee80211_channel *chan, | ||
942 | const struct ieee80211_reg_rule *reg_rule) | 943 | const struct ieee80211_reg_rule *reg_rule) |
943 | { | 944 | { |
944 | const struct ieee80211_power_rule *power_rule; | 945 | const struct ieee80211_power_rule *power_rule; |
945 | const struct ieee80211_freq_range *freq_range; | 946 | const struct ieee80211_freq_range *freq_range; |
946 | char max_antenna_gain[32]; | 947 | char max_antenna_gain[32], bw[32]; |
947 | 948 | ||
948 | power_rule = ®_rule->power_rule; | 949 | power_rule = ®_rule->power_rule; |
949 | freq_range = ®_rule->freq_range; | 950 | freq_range = ®_rule->freq_range; |
950 | 951 | ||
951 | if (!power_rule->max_antenna_gain) | 952 | if (!power_rule->max_antenna_gain) |
952 | snprintf(max_antenna_gain, 32, "N/A"); | 953 | snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A"); |
953 | else | 954 | else |
954 | snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain); | 955 | snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d", |
956 | power_rule->max_antenna_gain); | ||
957 | |||
958 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) | ||
959 | snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", | ||
960 | freq_range->max_bandwidth_khz, | ||
961 | reg_get_max_bandwidth(regd, reg_rule)); | ||
962 | else | ||
963 | snprintf(bw, sizeof(bw), "%d KHz", | ||
964 | freq_range->max_bandwidth_khz); | ||
955 | 965 | ||
956 | REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", | 966 | REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n", |
957 | chan->center_freq); | 967 | chan->center_freq); |
958 | 968 | ||
959 | REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", | 969 | REG_DBG_PRINT("%d KHz - %d KHz @ %s), (%s mBi, %d mBm)\n", |
960 | freq_range->start_freq_khz, freq_range->end_freq_khz, | 970 | freq_range->start_freq_khz, freq_range->end_freq_khz, |
961 | freq_range->max_bandwidth_khz, max_antenna_gain, | 971 | bw, max_antenna_gain, |
962 | power_rule->max_eirp); | 972 | power_rule->max_eirp); |
963 | } | 973 | } |
964 | #else | 974 | #else |
965 | static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, | 975 | static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd, |
976 | struct ieee80211_channel *chan, | ||
966 | const struct ieee80211_reg_rule *reg_rule) | 977 | const struct ieee80211_reg_rule *reg_rule) |
967 | { | 978 | { |
968 | return; | 979 | return; |
@@ -1022,17 +1033,16 @@ static void handle_channel(struct wiphy *wiphy, | |||
1022 | return; | 1033 | return; |
1023 | } | 1034 | } |
1024 | 1035 | ||
1025 | chan_reg_rule_print_dbg(chan, reg_rule); | 1036 | regd = reg_get_regdomain(wiphy); |
1037 | chan_reg_rule_print_dbg(regd, chan, reg_rule); | ||
1026 | 1038 | ||
1027 | power_rule = ®_rule->power_rule; | 1039 | power_rule = ®_rule->power_rule; |
1028 | freq_range = ®_rule->freq_range; | 1040 | freq_range = ®_rule->freq_range; |
1029 | 1041 | ||
1030 | max_bandwidth_khz = freq_range->max_bandwidth_khz; | 1042 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
1031 | /* Check if auto calculation requested */ | 1043 | /* Check if auto calculation requested */ |
1032 | if (!max_bandwidth_khz) { | 1044 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1033 | regd = reg_get_regdomain(wiphy); | ||
1034 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1045 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1035 | } | ||
1036 | 1046 | ||
1037 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1047 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
1038 | bw_flags = IEEE80211_CHAN_NO_HT40; | 1048 | bw_flags = IEEE80211_CHAN_NO_HT40; |
@@ -1437,14 +1447,14 @@ static void handle_channel_custom(struct wiphy *wiphy, | |||
1437 | return; | 1447 | return; |
1438 | } | 1448 | } |
1439 | 1449 | ||
1440 | chan_reg_rule_print_dbg(chan, reg_rule); | 1450 | chan_reg_rule_print_dbg(regd, chan, reg_rule); |
1441 | 1451 | ||
1442 | power_rule = ®_rule->power_rule; | 1452 | power_rule = ®_rule->power_rule; |
1443 | freq_range = ®_rule->freq_range; | 1453 | freq_range = ®_rule->freq_range; |
1444 | 1454 | ||
1445 | max_bandwidth_khz = freq_range->max_bandwidth_khz; | 1455 | max_bandwidth_khz = freq_range->max_bandwidth_khz; |
1446 | /* Check if auto calculation requested */ | 1456 | /* Check if auto calculation requested */ |
1447 | if (!max_bandwidth_khz) | 1457 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
1448 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); | 1458 | max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); |
1449 | 1459 | ||
1450 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) | 1460 | if (max_bandwidth_khz < MHZ_TO_KHZ(40)) |
@@ -2254,11 +2264,12 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) | |||
2254 | freq_range = ®_rule->freq_range; | 2264 | freq_range = ®_rule->freq_range; |
2255 | power_rule = ®_rule->power_rule; | 2265 | power_rule = ®_rule->power_rule; |
2256 | 2266 | ||
2257 | if (!freq_range->max_bandwidth_khz) | 2267 | if (reg_rule->flags & NL80211_RRF_AUTO_BW) |
2258 | snprintf(bw, 32, "%d KHz, AUTO", | 2268 | snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO", |
2269 | freq_range->max_bandwidth_khz, | ||
2259 | reg_get_max_bandwidth(rd, reg_rule)); | 2270 | reg_get_max_bandwidth(rd, reg_rule)); |
2260 | else | 2271 | else |
2261 | snprintf(bw, 32, "%d KHz", | 2272 | snprintf(bw, sizeof(bw), "%d KHz", |
2262 | freq_range->max_bandwidth_khz); | 2273 | freq_range->max_bandwidth_khz); |
2263 | 2274 | ||
2264 | /* | 2275 | /* |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 5eaeed59db07..aabccf13e07b 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start, | |||
1468 | TRACE_EVENT(rdev_tdls_mgmt, | 1468 | TRACE_EVENT(rdev_tdls_mgmt, |
1469 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | 1469 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, |
1470 | u8 *peer, u8 action_code, u8 dialog_token, | 1470 | u8 *peer, u8 action_code, u8 dialog_token, |
1471 | u16 status_code, const u8 *buf, size_t len), | 1471 | u16 status_code, u32 peer_capability, |
1472 | const u8 *buf, size_t len), | ||
1472 | TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, | 1473 | TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, |
1473 | buf, len), | 1474 | peer_capability, buf, len), |
1474 | TP_STRUCT__entry( | 1475 | TP_STRUCT__entry( |
1475 | WIPHY_ENTRY | 1476 | WIPHY_ENTRY |
1476 | NETDEV_ENTRY | 1477 | NETDEV_ENTRY |
@@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt, | |||
1478 | __field(u8, action_code) | 1479 | __field(u8, action_code) |
1479 | __field(u8, dialog_token) | 1480 | __field(u8, dialog_token) |
1480 | __field(u16, status_code) | 1481 | __field(u16, status_code) |
1482 | __field(u32, peer_capability) | ||
1481 | __dynamic_array(u8, buf, len) | 1483 | __dynamic_array(u8, buf, len) |
1482 | ), | 1484 | ), |
1483 | TP_fast_assign( | 1485 | TP_fast_assign( |
@@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt, | |||
1487 | __entry->action_code = action_code; | 1489 | __entry->action_code = action_code; |
1488 | __entry->dialog_token = dialog_token; | 1490 | __entry->dialog_token = dialog_token; |
1489 | __entry->status_code = status_code; | 1491 | __entry->status_code = status_code; |
1492 | __entry->peer_capability = peer_capability; | ||
1490 | memcpy(__get_dynamic_array(buf), buf, len); | 1493 | memcpy(__get_dynamic_array(buf), buf, len); |
1491 | ), | 1494 | ), |
1492 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " | 1495 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " |
1493 | "dialog_token: %u, status_code: %u, buf: %#.2x ", | 1496 | "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ", |
1494 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), | 1497 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), |
1495 | __entry->action_code, __entry->dialog_token, | 1498 | __entry->action_code, __entry->dialog_token, |
1496 | __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) | 1499 | __entry->status_code, __entry->peer_capability, |
1500 | ((u8 *)__get_dynamic_array(buf))[0]) | ||
1497 | ); | 1501 | ); |
1498 | 1502 | ||
1499 | TRACE_EVENT(rdev_dump_survey, | 1503 | TRACE_EVENT(rdev_dump_survey, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 780b4546c9c7..57b3ce7a6b92 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1269,7 +1269,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1269 | enum cfg80211_chan_mode chmode; | 1269 | enum cfg80211_chan_mode chmode; |
1270 | int num_different_channels = 0; | 1270 | int num_different_channels = 0; |
1271 | int total = 1; | 1271 | int total = 1; |
1272 | bool radar_required = false; | ||
1273 | int i, j; | 1272 | int i, j; |
1274 | 1273 | ||
1275 | ASSERT_RTNL(); | 1274 | ASSERT_RTNL(); |
@@ -1277,35 +1276,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1277 | if (WARN_ON(hweight32(radar_detect) > 1)) | 1276 | if (WARN_ON(hweight32(radar_detect) > 1)) |
1278 | return -EINVAL; | 1277 | return -EINVAL; |
1279 | 1278 | ||
1280 | switch (iftype) { | 1279 | if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) |
1281 | case NL80211_IFTYPE_ADHOC: | ||
1282 | case NL80211_IFTYPE_AP: | ||
1283 | case NL80211_IFTYPE_AP_VLAN: | ||
1284 | case NL80211_IFTYPE_MESH_POINT: | ||
1285 | case NL80211_IFTYPE_P2P_GO: | ||
1286 | case NL80211_IFTYPE_WDS: | ||
1287 | /* if the interface could potentially choose a DFS channel, | ||
1288 | * then mark DFS as required. | ||
1289 | */ | ||
1290 | if (!chan) { | ||
1291 | if (chanmode != CHAN_MODE_UNDEFINED && radar_detect) | ||
1292 | radar_required = true; | ||
1293 | break; | ||
1294 | } | ||
1295 | radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR); | ||
1296 | break; | ||
1297 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1298 | case NL80211_IFTYPE_STATION: | ||
1299 | case NL80211_IFTYPE_P2P_DEVICE: | ||
1300 | case NL80211_IFTYPE_MONITOR: | ||
1301 | break; | ||
1302 | case NUM_NL80211_IFTYPES: | ||
1303 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1304 | default: | ||
1305 | return -EINVAL; | ||
1306 | } | ||
1307 | |||
1308 | if (radar_required && !radar_detect) | ||
1309 | return -EINVAL; | 1280 | return -EINVAL; |
1310 | 1281 | ||
1311 | /* Always allow software iftypes */ | 1282 | /* Always allow software iftypes */ |