aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-10-07 07:29:18 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-07 07:29:18 -0400
commit2579c98f0d04075ab8b041de7d5396393d2417f1 (patch)
tree094fb6486f5ede529cd772223d2fa0334a28f852 /net/mac80211
parent390a4bee5c2ade628565dd21fb5d8656a58f7804 (diff)
parent5edfcee5ed73eb9537987c4ddb6bf062b6943b73 (diff)
Merge tag 'mac80211-next-for-davem-2015-10-05' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== For the current cycle, we have the following right now: * many internal fixes, API improvements, cleanups, etc. * full AP client state tracking in cfg80211/mac80211 from Ayala * VHT support (in mac80211) for mesh * some A-MSDU in A-MPDU support from Emmanuel * show current TX power to userspace (from RafaƂ) * support for netlink dump in vendor commands (myself) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c15
-rw-r--r--net/mac80211/cfg.c56
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/debugfs_key.c51
-rw-r--r--net/mac80211/debugfs_netdev.c41
-rw-r--r--net/mac80211/driver-ops.c222
-rw-r--r--net/mac80211/driver-ops.h259
-rw-r--r--net/mac80211/ieee80211_i.h19
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c82
-rw-r--r--net/mac80211/mesh.h10
-rw-r--r--net/mac80211/mesh_plink.c9
-rw-r--r--net/mac80211/mlme.c155
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/pm.c3
-rw-r--r--net/mac80211/rate.c5
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c12
-rw-r--r--net/mac80211/rc80211_minstrel_ht_debugfs.c12
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/status.c108
-rw-r--r--net/mac80211/tdls.c8
-rw-r--r--net/mac80211/trace.h40
-rw-r--r--net/mac80211/tx.c22
-rw-r--r--net/mac80211/util.c11
26 files changed, 706 insertions, 457 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 5c564a68fb50..10ad4ac1fa0b 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -79,7 +79,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
79 (int)reason); 79 (int)reason);
80 80
81 if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, 81 if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
82 &sta->sta, tid, NULL, 0)) 82 &sta->sta, tid, NULL, 0, false))
83 sdata_info(sta->sdata, 83 sdata_info(sta->sdata,
84 "HW problem - can not stop rx aggregation for %pM tid %d\n", 84 "HW problem - can not stop rx aggregation for %pM tid %d\n",
85 sta->sta.addr, tid); 85 sta->sta.addr, tid);
@@ -189,6 +189,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
189 struct ieee80211_local *local = sdata->local; 189 struct ieee80211_local *local = sdata->local;
190 struct sk_buff *skb; 190 struct sk_buff *skb;
191 struct ieee80211_mgmt *mgmt; 191 struct ieee80211_mgmt *mgmt;
192 bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU);
192 u16 capab; 193 u16 capab;
193 194
194 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 195 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
@@ -217,7 +218,8 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
217 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; 218 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
218 mgmt->u.action.u.addba_resp.dialog_token = dialog_token; 219 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
219 220
220 capab = (u16)(policy << 1); /* bit 1 aggregation policy */ 221 capab = (u16)(amsdu << 0); /* bit 0 A-MSDU support */
222 capab |= (u16)(policy << 1); /* bit 1 aggregation policy */
221 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 223 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
222 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */ 224 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
223 225
@@ -321,7 +323,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
321 __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]); 323 __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
322 324
323 ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, 325 ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
324 &sta->sta, tid, &start_seq_num, 0); 326 &sta->sta, tid, &start_seq_num, 0, false);
325 ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n", 327 ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
326 sta->sta.addr, tid, ret); 328 sta->sta.addr, tid, ret);
327 if (ret) { 329 if (ret) {
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c8ba2e77737c..a758eb84e8f0 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -97,7 +97,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
97 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; 97 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
98 98
99 mgmt->u.action.u.addba_req.dialog_token = dialog_token; 99 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
100 capab = (u16)(1 << 1); /* bit 1 aggregation policy */ 100 capab = (u16)(1 << 0); /* bit 0 A-MSDU support */
101 capab |= (u16)(1 << 1); /* bit 1 aggregation policy */
101 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 102 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
102 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */ 103 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
103 104
@@ -331,7 +332,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
331 return -EALREADY; 332 return -EALREADY;
332 ret = drv_ampdu_action(local, sta->sdata, 333 ret = drv_ampdu_action(local, sta->sdata,
333 IEEE80211_AMPDU_TX_STOP_FLUSH_CONT, 334 IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,
334 &sta->sta, tid, NULL, 0); 335 &sta->sta, tid, NULL, 0, false);
335 WARN_ON_ONCE(ret); 336 WARN_ON_ONCE(ret);
336 return 0; 337 return 0;
337 } 338 }
@@ -381,7 +382,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
381 tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST; 382 tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
382 383
383 ret = drv_ampdu_action(local, sta->sdata, action, 384 ret = drv_ampdu_action(local, sta->sdata, action,
384 &sta->sta, tid, NULL, 0); 385 &sta->sta, tid, NULL, 0, false);
385 386
386 /* HW shall not deny going back to legacy */ 387 /* HW shall not deny going back to legacy */
387 if (WARN_ON(ret)) { 388 if (WARN_ON(ret)) {
@@ -469,7 +470,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
469 start_seq_num = sta->tid_seq[tid] >> 4; 470 start_seq_num = sta->tid_seq[tid] >> 4;
470 471
471 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, 472 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
472 &sta->sta, tid, &start_seq_num, 0); 473 &sta->sta, tid, &start_seq_num, 0, false);
473 if (ret) { 474 if (ret) {
474 ht_dbg(sdata, 475 ht_dbg(sdata,
475 "BA request denied - HW unavailable for %pM tid %d\n", 476 "BA request denied - HW unavailable for %pM tid %d\n",
@@ -693,7 +694,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
693 694
694 drv_ampdu_action(local, sta->sdata, 695 drv_ampdu_action(local, sta->sdata,
695 IEEE80211_AMPDU_TX_OPERATIONAL, 696 IEEE80211_AMPDU_TX_OPERATIONAL,
696 &sta->sta, tid, NULL, tid_tx->buf_size); 697 &sta->sta, tid, NULL, tid_tx->buf_size,
698 tid_tx->amsdu);
697 699
698 /* 700 /*
699 * synchronize with TX path, while splicing the TX path 701 * synchronize with TX path, while splicing the TX path
@@ -918,8 +920,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
918 struct tid_ampdu_tx *tid_tx; 920 struct tid_ampdu_tx *tid_tx;
919 u16 capab, tid; 921 u16 capab, tid;
920 u8 buf_size; 922 u8 buf_size;
923 bool amsdu;
921 924
922 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 925 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
926 amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
923 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 927 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
924 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; 928 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
925 929
@@ -968,6 +972,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
968 } 972 }
969 973
970 tid_tx->buf_size = buf_size; 974 tid_tx->buf_size = buf_size;
975 tid_tx->amsdu = amsdu;
971 976
972 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) 977 if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
973 ieee80211_agg_tx_operational(local, sta, tid); 978 ieee80211_agg_tx_operational(local, sta, tid);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7a77a1470f25..68e551e263c6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -981,7 +981,7 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
981 * well. Some drivers require rate control initialized 981 * well. Some drivers require rate control initialized
982 * before drv_sta_state() is called. 982 * before drv_sta_state() is called.
983 */ 983 */
984 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) 984 if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
985 rate_control_rate_init(sta); 985 rate_control_rate_init(sta);
986 986
987 ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); 987 ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
@@ -1120,8 +1120,11 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1120 local->hw.queues >= IEEE80211_NUM_ACS) 1120 local->hw.queues >= IEEE80211_NUM_ACS)
1121 sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); 1121 sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
1122 1122
1123 /* auth flags will be set later for TDLS stations */ 1123 /* auth flags will be set later for TDLS,
1124 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { 1124 * and for unassociated stations that move to assocaited */
1125 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
1126 !((mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) &&
1127 (set & BIT(NL80211_STA_FLAG_ASSOCIATED)))) {
1125 ret = sta_apply_auth_flags(local, sta, mask, set); 1128 ret = sta_apply_auth_flags(local, sta, mask, set);
1126 if (ret) 1129 if (ret)
1127 return ret; 1130 return ret;
@@ -1156,6 +1159,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1156 set_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH); 1159 set_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH);
1157 1160
1158 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && 1161 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
1162 !sdata->u.mgd.tdls_wider_bw_prohibited &&
1159 ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) && 1163 ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
1160 params->ext_capab_len >= 8 && 1164 params->ext_capab_len >= 8 &&
1161 params->ext_capab[7] & WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) 1165 params->ext_capab[7] & WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED)
@@ -1212,7 +1216,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1212 sta_apply_mesh_params(local, sta, params); 1216 sta_apply_mesh_params(local, sta, params);
1213 1217
1214 /* set the STA state after all sta info from usermode has been set */ 1218 /* set the STA state after all sta info from usermode has been set */
1215 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { 1219 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) ||
1220 set & BIT(NL80211_STA_FLAG_ASSOCIATED)) {
1216 ret = sta_apply_auth_flags(local, sta, mask, set); 1221 ret = sta_apply_auth_flags(local, sta, mask, set);
1217 if (ret) 1222 if (ret)
1218 return ret; 1223 return ret;
@@ -1254,12 +1259,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1254 * defaults -- if userspace wants something else we'll 1259 * defaults -- if userspace wants something else we'll
1255 * change it accordingly in sta_apply_parameters() 1260 * change it accordingly in sta_apply_parameters()
1256 */ 1261 */
1257 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) { 1262 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
1263 !(params->sta_flags_set & (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
1264 BIT(NL80211_STA_FLAG_ASSOCIATED)))) {
1258 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 1265 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
1259 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 1266 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
1260 } else {
1261 sta->sta.tdls = true;
1262 } 1267 }
1268 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
1269 sta->sta.tdls = true;
1263 1270
1264 err = sta_apply_parameters(local, sta, params); 1271 err = sta_apply_parameters(local, sta, params);
1265 if (err) { 1272 if (err) {
@@ -1268,10 +1275,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
1268 } 1275 }
1269 1276
1270 /* 1277 /*
1271 * for TDLS, rate control should be initialized only when 1278 * for TDLS and for unassociated station, rate control should be
1272 * rates are known and station is marked authorized 1279 * initialized only when rates are known and station is marked
1280 * authorized/associated
1273 */ 1281 */
1274 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) 1282 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
1283 test_sta_flag(sta, WLAN_STA_ASSOC))
1275 rate_control_rate_init(sta); 1284 rate_control_rate_init(sta);
1276 1285
1277 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 1286 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
@@ -1346,7 +1355,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1346 break; 1355 break;
1347 case NL80211_IFTYPE_AP: 1356 case NL80211_IFTYPE_AP:
1348 case NL80211_IFTYPE_AP_VLAN: 1357 case NL80211_IFTYPE_AP_VLAN:
1349 statype = CFG80211_STA_AP_CLIENT; 1358 if (test_sta_flag(sta, WLAN_STA_ASSOC))
1359 statype = CFG80211_STA_AP_CLIENT;
1360 else
1361 statype = CFG80211_STA_AP_CLIENT_UNASSOC;
1350 break; 1362 break;
1351 default: 1363 default:
1352 err = -EOPNOTSUPP; 1364 err = -EOPNOTSUPP;
@@ -3522,18 +3534,32 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
3522 u16 frame_type, bool reg) 3534 u16 frame_type, bool reg)
3523{ 3535{
3524 struct ieee80211_local *local = wiphy_priv(wiphy); 3536 struct ieee80211_local *local = wiphy_priv(wiphy);
3537 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3525 3538
3526 switch (frame_type) { 3539 switch (frame_type) {
3527 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 3540 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
3528 if (reg) 3541 if (reg) {
3529 local->probe_req_reg++; 3542 local->probe_req_reg++;
3530 else 3543 sdata->vif.probe_req_reg++;
3531 local->probe_req_reg--; 3544 } else {
3545 if (local->probe_req_reg)
3546 local->probe_req_reg--;
3547
3548 if (sdata->vif.probe_req_reg)
3549 sdata->vif.probe_req_reg--;
3550 }
3532 3551
3533 if (!local->open_count) 3552 if (!local->open_count)
3534 break; 3553 break;
3535 3554
3536 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 3555 if (sdata->vif.probe_req_reg == 1)
3556 drv_config_iface_filter(local, sdata, FIF_PROBE_REQ,
3557 FIF_PROBE_REQ);
3558 else if (sdata->vif.probe_req_reg == 0)
3559 drv_config_iface_filter(local, sdata, 0,
3560 FIF_PROBE_REQ);
3561
3562 ieee80211_configure_filter(local);
3537 break; 3563 break;
3538 default: 3564 default:
3539 break; 3565 break;
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index ced6bf3be8d6..3636b45440ab 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -123,6 +123,8 @@ static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
123 FLAG(SUPPORTS_CLONED_SKBS), 123 FLAG(SUPPORTS_CLONED_SKBS),
124 FLAG(SINGLE_SCAN_ON_ALL_BANDS), 124 FLAG(SINGLE_SCAN_ON_ALL_BANDS),
125 FLAG(TDLS_WIDER_BW), 125 FLAG(TDLS_WIDER_BW),
126 FLAG(SUPPORTS_AMSDU_IN_AMPDU),
127 FLAG(BEACON_TX_STATUS),
126 128
127 /* keep last for the build bug below */ 129 /* keep last for the build bug below */
128 (void *)0x1 130 (void *)0x1
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 702ca122c498..7961e7d0b61e 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -2,6 +2,7 @@
2 * Copyright 2003-2005 Devicescape Software, Inc. 2 * Copyright 2003-2005 Devicescape Software, Inc.
3 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> 3 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (C) 2015 Intel Deutschland GmbH
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -34,6 +35,14 @@ static const struct file_operations key_ ##name## _ops = { \
34 .llseek = generic_file_llseek, \ 35 .llseek = generic_file_llseek, \
35} 36}
36 37
38#define KEY_OPS_W(name) \
39static const struct file_operations key_ ##name## _ops = { \
40 .read = key_##name##_read, \
41 .write = key_##name##_write, \
42 .open = simple_open, \
43 .llseek = generic_file_llseek, \
44}
45
37#define KEY_FILE(name, format) \ 46#define KEY_FILE(name, format) \
38 KEY_READ_##format(name) \ 47 KEY_READ_##format(name) \
39 KEY_OPS(name) 48 KEY_OPS(name)
@@ -74,6 +83,41 @@ static ssize_t key_algorithm_read(struct file *file,
74} 83}
75KEY_OPS(algorithm); 84KEY_OPS(algorithm);
76 85
86static ssize_t key_tx_spec_write(struct file *file, const char __user *userbuf,
87 size_t count, loff_t *ppos)
88{
89 struct ieee80211_key *key = file->private_data;
90 u64 pn;
91 int ret;
92
93 switch (key->conf.cipher) {
94 case WLAN_CIPHER_SUITE_WEP40:
95 case WLAN_CIPHER_SUITE_WEP104:
96 return -EINVAL;
97 case WLAN_CIPHER_SUITE_TKIP:
98 /* not supported yet */
99 return -EOPNOTSUPP;
100 case WLAN_CIPHER_SUITE_CCMP:
101 case WLAN_CIPHER_SUITE_CCMP_256:
102 case WLAN_CIPHER_SUITE_AES_CMAC:
103 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
104 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
105 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
106 case WLAN_CIPHER_SUITE_GCMP:
107 case WLAN_CIPHER_SUITE_GCMP_256:
108 ret = kstrtou64_from_user(userbuf, count, 16, &pn);
109 if (ret)
110 return ret;
111 /* PN is a 48-bit counter */
112 if (pn >= (1ULL << 48))
113 return -ERANGE;
114 atomic64_set(&key->conf.tx_pn, pn);
115 return count;
116 default:
117 return 0;
118 }
119}
120
77static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, 121static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
78 size_t count, loff_t *ppos) 122 size_t count, loff_t *ppos)
79{ 123{
@@ -110,7 +154,7 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
110 } 154 }
111 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 155 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
112} 156}
113KEY_OPS(tx_spec); 157KEY_OPS_W(tx_spec);
114 158
115static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, 159static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
116 size_t count, loff_t *ppos) 160 size_t count, loff_t *ppos)
@@ -278,6 +322,9 @@ KEY_OPS(key);
278#define DEBUGFS_ADD(name) \ 322#define DEBUGFS_ADD(name) \
279 debugfs_create_file(#name, 0400, key->debugfs.dir, \ 323 debugfs_create_file(#name, 0400, key->debugfs.dir, \
280 key, &key_##name##_ops); 324 key, &key_##name##_ops);
325#define DEBUGFS_ADD_W(name) \
326 debugfs_create_file(#name, 0600, key->debugfs.dir, \
327 key, &key_##name##_ops);
281 328
282void ieee80211_debugfs_key_add(struct ieee80211_key *key) 329void ieee80211_debugfs_key_add(struct ieee80211_key *key)
283{ 330{
@@ -310,7 +357,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
310 DEBUGFS_ADD(keyidx); 357 DEBUGFS_ADD(keyidx);
311 DEBUGFS_ADD(hw_key_idx); 358 DEBUGFS_ADD(hw_key_idx);
312 DEBUGFS_ADD(algorithm); 359 DEBUGFS_ADD(algorithm);
313 DEBUGFS_ADD(tx_spec); 360 DEBUGFS_ADD_W(tx_spec);
314 DEBUGFS_ADD(rx_spec); 361 DEBUGFS_ADD(rx_spec);
315 DEBUGFS_ADD(replays); 362 DEBUGFS_ADD(replays);
316 DEBUGFS_ADD(icverrors); 363 DEBUGFS_ADD(icverrors);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 1021e87c051f..37ea30e0754c 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -114,14 +114,6 @@ static ssize_t ieee80211_if_fmt_##name( \
114 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 114 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
115} 115}
116 116
117#define IEEE80211_IF_FMT_DEC_DIV_16(name, field) \
118static ssize_t ieee80211_if_fmt_##name( \
119 const struct ieee80211_sub_if_data *sdata, \
120 char *buf, int buflen) \
121{ \
122 return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \
123}
124
125#define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field) \ 117#define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field) \
126static ssize_t ieee80211_if_fmt_##name( \ 118static ssize_t ieee80211_if_fmt_##name( \
127 const struct ieee80211_sub_if_data *sdata, \ 119 const struct ieee80211_sub_if_data *sdata, \
@@ -247,8 +239,6 @@ IEEE80211_IF_FILE_R(hw_queues);
247/* STA attributes */ 239/* STA attributes */
248IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 240IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
249IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 241IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
250IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
251IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
252IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS); 242IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS);
253 243
254static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 244static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
@@ -455,6 +445,34 @@ static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
455} 445}
456IEEE80211_IF_FILE_RW(uapsd_max_sp_len); 446IEEE80211_IF_FILE_RW(uapsd_max_sp_len);
457 447
448static ssize_t ieee80211_if_fmt_tdls_wider_bw(
449 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
450{
451 const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
452 bool tdls_wider_bw;
453
454 tdls_wider_bw = ieee80211_hw_check(&sdata->local->hw, TDLS_WIDER_BW) &&
455 !ifmgd->tdls_wider_bw_prohibited;
456
457 return snprintf(buf, buflen, "%d\n", tdls_wider_bw);
458}
459
460static ssize_t ieee80211_if_parse_tdls_wider_bw(
461 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
462{
463 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
464 u8 val;
465 int ret;
466
467 ret = kstrtou8(buf, 0, &val);
468 if (ret)
469 return ret;
470
471 ifmgd->tdls_wider_bw_prohibited = !val;
472 return buflen;
473}
474IEEE80211_IF_FILE_RW(tdls_wider_bw);
475
458/* AP attributes */ 476/* AP attributes */
459IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); 477IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
460IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC); 478IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC);
@@ -606,14 +624,13 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
606{ 624{
607 DEBUGFS_ADD(bssid); 625 DEBUGFS_ADD(bssid);
608 DEBUGFS_ADD(aid); 626 DEBUGFS_ADD(aid);
609 DEBUGFS_ADD(last_beacon);
610 DEBUGFS_ADD(ave_beacon);
611 DEBUGFS_ADD(beacon_timeout); 627 DEBUGFS_ADD(beacon_timeout);
612 DEBUGFS_ADD_MODE(smps, 0600); 628 DEBUGFS_ADD_MODE(smps, 0600);
613 DEBUGFS_ADD_MODE(tkip_mic_test, 0200); 629 DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
614 DEBUGFS_ADD_MODE(beacon_loss, 0200); 630 DEBUGFS_ADD_MODE(beacon_loss, 0200);
615 DEBUGFS_ADD_MODE(uapsd_queues, 0600); 631 DEBUGFS_ADD_MODE(uapsd_queues, 0600);
616 DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); 632 DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
633 DEBUGFS_ADD_MODE(tdls_wider_bw, 0600);
617} 634}
618 635
619static void add_ap_files(struct ieee80211_sub_if_data *sdata) 636static void add_ap_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
index 267c3b1ca047..a1d54318f16c 100644
--- a/net/mac80211/driver-ops.c
+++ b/net/mac80211/driver-ops.c
@@ -8,6 +8,60 @@
8#include "trace.h" 8#include "trace.h"
9#include "driver-ops.h" 9#include "driver-ops.h"
10 10
11int drv_add_interface(struct ieee80211_local *local,
12 struct ieee80211_sub_if_data *sdata)
13{
14 int ret;
15
16 might_sleep();
17
18 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
19 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
20 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
21 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
22 return -EINVAL;
23
24 trace_drv_add_interface(local, sdata);
25 ret = local->ops->add_interface(&local->hw, &sdata->vif);
26 trace_drv_return_int(local, ret);
27
28 if (ret == 0)
29 sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
30
31 return ret;
32}
33
34int drv_change_interface(struct ieee80211_local *local,
35 struct ieee80211_sub_if_data *sdata,
36 enum nl80211_iftype type, bool p2p)
37{
38 int ret;
39
40 might_sleep();
41
42 if (!check_sdata_in_driver(sdata))
43 return -EIO;
44
45 trace_drv_change_interface(local, sdata, type, p2p);
46 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
47 trace_drv_return_int(local, ret);
48 return ret;
49}
50
51void drv_remove_interface(struct ieee80211_local *local,
52 struct ieee80211_sub_if_data *sdata)
53{
54 might_sleep();
55
56 if (!check_sdata_in_driver(sdata))
57 return;
58
59 trace_drv_remove_interface(local, sdata);
60 local->ops->remove_interface(&local->hw, &sdata->vif);
61 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
62 trace_drv_return_void(local);
63}
64
11__must_check 65__must_check
12int drv_sta_state(struct ieee80211_local *local, 66int drv_sta_state(struct ieee80211_local *local,
13 struct ieee80211_sub_if_data *sdata, 67 struct ieee80211_sub_if_data *sdata,
@@ -39,3 +93,171 @@ int drv_sta_state(struct ieee80211_local *local,
39 trace_drv_return_int(local, ret); 93 trace_drv_return_int(local, ret);
40 return ret; 94 return ret;
41} 95}
96
97void drv_sta_rc_update(struct ieee80211_local *local,
98 struct ieee80211_sub_if_data *sdata,
99 struct ieee80211_sta *sta, u32 changed)
100{
101 sdata = get_bss_sdata(sdata);
102 if (!check_sdata_in_driver(sdata))
103 return;
104
105 WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
106 (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
107 sdata->vif.type != NL80211_IFTYPE_MESH_POINT));
108
109 trace_drv_sta_rc_update(local, sdata, sta, changed);
110 if (local->ops->sta_rc_update)
111 local->ops->sta_rc_update(&local->hw, &sdata->vif,
112 sta, changed);
113
114 trace_drv_return_void(local);
115}
116
117int drv_conf_tx(struct ieee80211_local *local,
118 struct ieee80211_sub_if_data *sdata, u16 ac,
119 const struct ieee80211_tx_queue_params *params)
120{
121 int ret = -EOPNOTSUPP;
122
123 might_sleep();
124
125 if (!check_sdata_in_driver(sdata))
126 return -EIO;
127
128 if (WARN_ONCE(params->cw_min == 0 ||
129 params->cw_min > params->cw_max,
130 "%s: invalid CW_min/CW_max: %d/%d\n",
131 sdata->name, params->cw_min, params->cw_max))
132 return -EINVAL;
133
134 trace_drv_conf_tx(local, sdata, ac, params);
135 if (local->ops->conf_tx)
136 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
137 ac, params);
138 trace_drv_return_int(local, ret);
139 return ret;
140}
141
142u64 drv_get_tsf(struct ieee80211_local *local,
143 struct ieee80211_sub_if_data *sdata)
144{
145 u64 ret = -1ULL;
146
147 might_sleep();
148
149 if (!check_sdata_in_driver(sdata))
150 return ret;
151
152 trace_drv_get_tsf(local, sdata);
153 if (local->ops->get_tsf)
154 ret = local->ops->get_tsf(&local->hw, &sdata->vif);
155 trace_drv_return_u64(local, ret);
156 return ret;
157}
158
159void drv_set_tsf(struct ieee80211_local *local,
160 struct ieee80211_sub_if_data *sdata,
161 u64 tsf)
162{
163 might_sleep();
164
165 if (!check_sdata_in_driver(sdata))
166 return;
167
168 trace_drv_set_tsf(local, sdata, tsf);
169 if (local->ops->set_tsf)
170 local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
171 trace_drv_return_void(local);
172}
173
174void drv_reset_tsf(struct ieee80211_local *local,
175 struct ieee80211_sub_if_data *sdata)
176{
177 might_sleep();
178
179 if (!check_sdata_in_driver(sdata))
180 return;
181
182 trace_drv_reset_tsf(local, sdata);
183 if (local->ops->reset_tsf)
184 local->ops->reset_tsf(&local->hw, &sdata->vif);
185 trace_drv_return_void(local);
186}
187
188int drv_switch_vif_chanctx(struct ieee80211_local *local,
189 struct ieee80211_vif_chanctx_switch *vifs,
190 int n_vifs, enum ieee80211_chanctx_switch_mode mode)
191{
192 int ret = 0;
193 int i;
194
195 if (!local->ops->switch_vif_chanctx)
196 return -EOPNOTSUPP;
197
198 for (i = 0; i < n_vifs; i++) {
199 struct ieee80211_chanctx *new_ctx =
200 container_of(vifs[i].new_ctx,
201 struct ieee80211_chanctx,
202 conf);
203 struct ieee80211_chanctx *old_ctx =
204 container_of(vifs[i].old_ctx,
205 struct ieee80211_chanctx,
206 conf);
207
208 WARN_ON_ONCE(!old_ctx->driver_present);
209 WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS &&
210 new_ctx->driver_present) ||
211 (mode == CHANCTX_SWMODE_REASSIGN_VIF &&
212 !new_ctx->driver_present));
213 }
214
215 trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode);
216 ret = local->ops->switch_vif_chanctx(&local->hw,
217 vifs, n_vifs, mode);
218 trace_drv_return_int(local, ret);
219
220 if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
221 for (i = 0; i < n_vifs; i++) {
222 struct ieee80211_chanctx *new_ctx =
223 container_of(vifs[i].new_ctx,
224 struct ieee80211_chanctx,
225 conf);
226 struct ieee80211_chanctx *old_ctx =
227 container_of(vifs[i].old_ctx,
228 struct ieee80211_chanctx,
229 conf);
230
231 new_ctx->driver_present = true;
232 old_ctx->driver_present = false;
233 }
234 }
235
236 return ret;
237}
238
239int drv_ampdu_action(struct ieee80211_local *local,
240 struct ieee80211_sub_if_data *sdata,
241 enum ieee80211_ampdu_mlme_action action,
242 struct ieee80211_sta *sta, u16 tid,
243 u16 *ssn, u8 buf_size, bool amsdu)
244{
245 int ret = -EOPNOTSUPP;
246
247 might_sleep();
248
249 sdata = get_bss_sdata(sdata);
250 if (!check_sdata_in_driver(sdata))
251 return -EIO;
252
253 trace_drv_ampdu_action(local, sdata, action, sta, tid,
254 ssn, buf_size, amsdu);
255
256 if (local->ops->ampdu_action)
257 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
258 sta, tid, ssn, buf_size, amsdu);
259
260 trace_drv_return_int(local, ret);
261
262 return ret;
263}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 02d91332d7dd..30987099eb8f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -137,59 +137,15 @@ static inline void drv_set_wakeup(struct ieee80211_local *local,
137} 137}
138#endif 138#endif
139 139
140static inline int drv_add_interface(struct ieee80211_local *local, 140int drv_add_interface(struct ieee80211_local *local,
141 struct ieee80211_sub_if_data *sdata) 141 struct ieee80211_sub_if_data *sdata);
142{
143 int ret;
144
145 might_sleep();
146
147 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
148 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
149 !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
150 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
151 return -EINVAL;
152
153 trace_drv_add_interface(local, sdata);
154 ret = local->ops->add_interface(&local->hw, &sdata->vif);
155 trace_drv_return_int(local, ret);
156
157 if (ret == 0)
158 sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
159
160 return ret;
161}
162
163static inline int drv_change_interface(struct ieee80211_local *local,
164 struct ieee80211_sub_if_data *sdata,
165 enum nl80211_iftype type, bool p2p)
166{
167 int ret;
168 142
169 might_sleep(); 143int drv_change_interface(struct ieee80211_local *local,
170 144 struct ieee80211_sub_if_data *sdata,
171 if (!check_sdata_in_driver(sdata)) 145 enum nl80211_iftype type, bool p2p);
172 return -EIO;
173
174 trace_drv_change_interface(local, sdata, type, p2p);
175 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
176 trace_drv_return_int(local, ret);
177 return ret;
178}
179
180static inline void drv_remove_interface(struct ieee80211_local *local,
181 struct ieee80211_sub_if_data *sdata)
182{
183 might_sleep();
184
185 if (!check_sdata_in_driver(sdata))
186 return;
187 146
188 trace_drv_remove_interface(local, sdata); 147void drv_remove_interface(struct ieee80211_local *local,
189 local->ops->remove_interface(&local->hw, &sdata->vif); 148 struct ieee80211_sub_if_data *sdata);
190 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
191 trace_drv_return_void(local);
192}
193 149
194static inline int drv_config(struct ieee80211_local *local, u32 changed) 150static inline int drv_config(struct ieee80211_local *local, u32 changed)
195{ 151{
@@ -260,6 +216,22 @@ static inline void drv_configure_filter(struct ieee80211_local *local,
260 trace_drv_return_void(local); 216 trace_drv_return_void(local);
261} 217}
262 218
219static inline void drv_config_iface_filter(struct ieee80211_local *local,
220 struct ieee80211_sub_if_data *sdata,
221 unsigned int filter_flags,
222 unsigned int changed_flags)
223{
224 might_sleep();
225
226 trace_drv_config_iface_filter(local, sdata, filter_flags,
227 changed_flags);
228 if (local->ops->config_iface_filter)
229 local->ops->config_iface_filter(&local->hw, &sdata->vif,
230 filter_flags,
231 changed_flags);
232 trace_drv_return_void(local);
233}
234
263static inline int drv_set_tim(struct ieee80211_local *local, 235static inline int drv_set_tim(struct ieee80211_local *local,
264 struct ieee80211_sta *sta, bool set) 236 struct ieee80211_sta *sta, bool set)
265{ 237{
@@ -580,25 +552,9 @@ int drv_sta_state(struct ieee80211_local *local,
580 enum ieee80211_sta_state old_state, 552 enum ieee80211_sta_state old_state,
581 enum ieee80211_sta_state new_state); 553 enum ieee80211_sta_state new_state);
582 554
583static inline void drv_sta_rc_update(struct ieee80211_local *local, 555void drv_sta_rc_update(struct ieee80211_local *local,
584 struct ieee80211_sub_if_data *sdata, 556 struct ieee80211_sub_if_data *sdata,
585 struct ieee80211_sta *sta, u32 changed) 557 struct ieee80211_sta *sta, u32 changed);
586{
587 sdata = get_bss_sdata(sdata);
588 if (!check_sdata_in_driver(sdata))
589 return;
590
591 WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
592 (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
593 sdata->vif.type != NL80211_IFTYPE_MESH_POINT));
594
595 trace_drv_sta_rc_update(local, sdata, sta, changed);
596 if (local->ops->sta_rc_update)
597 local->ops->sta_rc_update(&local->hw, &sdata->vif,
598 sta, changed);
599
600 trace_drv_return_void(local);
601}
602 558
603static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, 559static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
604 struct ieee80211_sub_if_data *sdata, 560 struct ieee80211_sub_if_data *sdata,
@@ -630,76 +586,17 @@ static inline void drv_sta_statistics(struct ieee80211_local *local,
630 trace_drv_return_void(local); 586 trace_drv_return_void(local);
631} 587}
632 588
633static inline int drv_conf_tx(struct ieee80211_local *local, 589int drv_conf_tx(struct ieee80211_local *local,
634 struct ieee80211_sub_if_data *sdata, u16 ac, 590 struct ieee80211_sub_if_data *sdata, u16 ac,
635 const struct ieee80211_tx_queue_params *params) 591 const struct ieee80211_tx_queue_params *params);
636{
637 int ret = -EOPNOTSUPP;
638
639 might_sleep();
640
641 if (!check_sdata_in_driver(sdata))
642 return -EIO;
643
644 if (WARN_ONCE(params->cw_min == 0 ||
645 params->cw_min > params->cw_max,
646 "%s: invalid CW_min/CW_max: %d/%d\n",
647 sdata->name, params->cw_min, params->cw_max))
648 return -EINVAL;
649
650 trace_drv_conf_tx(local, sdata, ac, params);
651 if (local->ops->conf_tx)
652 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
653 ac, params);
654 trace_drv_return_int(local, ret);
655 return ret;
656}
657
658static inline u64 drv_get_tsf(struct ieee80211_local *local,
659 struct ieee80211_sub_if_data *sdata)
660{
661 u64 ret = -1ULL;
662
663 might_sleep();
664
665 if (!check_sdata_in_driver(sdata))
666 return ret;
667
668 trace_drv_get_tsf(local, sdata);
669 if (local->ops->get_tsf)
670 ret = local->ops->get_tsf(&local->hw, &sdata->vif);
671 trace_drv_return_u64(local, ret);
672 return ret;
673}
674
675static inline void drv_set_tsf(struct ieee80211_local *local,
676 struct ieee80211_sub_if_data *sdata,
677 u64 tsf)
678{
679 might_sleep();
680
681 if (!check_sdata_in_driver(sdata))
682 return;
683
684 trace_drv_set_tsf(local, sdata, tsf);
685 if (local->ops->set_tsf)
686 local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
687 trace_drv_return_void(local);
688}
689
690static inline void drv_reset_tsf(struct ieee80211_local *local,
691 struct ieee80211_sub_if_data *sdata)
692{
693 might_sleep();
694 592
695 if (!check_sdata_in_driver(sdata)) 593u64 drv_get_tsf(struct ieee80211_local *local,
696 return; 594 struct ieee80211_sub_if_data *sdata);
697 595void drv_set_tsf(struct ieee80211_local *local,
698 trace_drv_reset_tsf(local, sdata); 596 struct ieee80211_sub_if_data *sdata,
699 if (local->ops->reset_tsf) 597 u64 tsf);
700 local->ops->reset_tsf(&local->hw, &sdata->vif); 598void drv_reset_tsf(struct ieee80211_local *local,
701 trace_drv_return_void(local); 599 struct ieee80211_sub_if_data *sdata);
702}
703 600
704static inline int drv_tx_last_beacon(struct ieee80211_local *local) 601static inline int drv_tx_last_beacon(struct ieee80211_local *local)
705{ 602{
@@ -714,30 +611,11 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local)
714 return ret; 611 return ret;
715} 612}
716 613
717static inline int drv_ampdu_action(struct ieee80211_local *local, 614int drv_ampdu_action(struct ieee80211_local *local,
718 struct ieee80211_sub_if_data *sdata, 615 struct ieee80211_sub_if_data *sdata,
719 enum ieee80211_ampdu_mlme_action action, 616 enum ieee80211_ampdu_mlme_action action,
720 struct ieee80211_sta *sta, u16 tid, 617 struct ieee80211_sta *sta, u16 tid,
721 u16 *ssn, u8 buf_size) 618 u16 *ssn, u8 buf_size, bool amsdu);
722{
723 int ret = -EOPNOTSUPP;
724
725 might_sleep();
726
727 sdata = get_bss_sdata(sdata);
728 if (!check_sdata_in_driver(sdata))
729 return -EIO;
730
731 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
732
733 if (local->ops->ampdu_action)
734 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
735 sta, tid, ssn, buf_size);
736
737 trace_drv_return_int(local, ret);
738
739 return ret;
740}
741 619
742static inline int drv_get_survey(struct ieee80211_local *local, int idx, 620static inline int drv_get_survey(struct ieee80211_local *local, int idx,
743 struct survey_info *survey) 621 struct survey_info *survey)
@@ -1066,58 +944,9 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
1066 trace_drv_return_void(local); 944 trace_drv_return_void(local);
1067} 945}
1068 946
1069static inline int 947int drv_switch_vif_chanctx(struct ieee80211_local *local,
1070drv_switch_vif_chanctx(struct ieee80211_local *local, 948 struct ieee80211_vif_chanctx_switch *vifs,
1071 struct ieee80211_vif_chanctx_switch *vifs, 949 int n_vifs, enum ieee80211_chanctx_switch_mode mode);
1072 int n_vifs,
1073 enum ieee80211_chanctx_switch_mode mode)
1074{
1075 int ret = 0;
1076 int i;
1077
1078 if (!local->ops->switch_vif_chanctx)
1079 return -EOPNOTSUPP;
1080
1081 for (i = 0; i < n_vifs; i++) {
1082 struct ieee80211_chanctx *new_ctx =
1083 container_of(vifs[i].new_ctx,
1084 struct ieee80211_chanctx,
1085 conf);
1086 struct ieee80211_chanctx *old_ctx =
1087 container_of(vifs[i].old_ctx,
1088 struct ieee80211_chanctx,
1089 conf);
1090
1091 WARN_ON_ONCE(!old_ctx->driver_present);
1092 WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS &&
1093 new_ctx->driver_present) ||
1094 (mode == CHANCTX_SWMODE_REASSIGN_VIF &&
1095 !new_ctx->driver_present));
1096 }
1097
1098 trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode);
1099 ret = local->ops->switch_vif_chanctx(&local->hw,
1100 vifs, n_vifs, mode);
1101 trace_drv_return_int(local, ret);
1102
1103 if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
1104 for (i = 0; i < n_vifs; i++) {
1105 struct ieee80211_chanctx *new_ctx =
1106 container_of(vifs[i].new_ctx,
1107 struct ieee80211_chanctx,
1108 conf);
1109 struct ieee80211_chanctx *old_ctx =
1110 container_of(vifs[i].old_ctx,
1111 struct ieee80211_chanctx,
1112 conf);
1113
1114 new_ctx->driver_present = true;
1115 old_ctx->driver_present = false;
1116 }
1117 }
1118
1119 return ret;
1120}
1121 950
1122static inline int drv_start_ap(struct ieee80211_local *local, 951static inline int drv_start_ap(struct ieee80211_local *local,
1123 struct ieee80211_sub_if_data *sdata) 952 struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6e52659f923f..f9605f13def9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -419,6 +419,8 @@ struct ieee80211_sta_tx_tspec {
419 bool downgraded; 419 bool downgraded;
420}; 420};
421 421
422DECLARE_EWMA(beacon_signal, 16, 4)
423
422struct ieee80211_if_managed { 424struct ieee80211_if_managed {
423 struct timer_list timer; 425 struct timer_list timer;
424 struct timer_list conn_mon_timer; 426 struct timer_list conn_mon_timer;
@@ -490,16 +492,7 @@ struct ieee80211_if_managed {
490 492
491 s16 p2p_noa_index; 493 s16 p2p_noa_index;
492 494
493 /* Signal strength from the last Beacon frame in the current BSS. */ 495 struct ewma_beacon_signal ave_beacon_signal;
494 int last_beacon_signal;
495
496 /*
497 * Weighted average of the signal strength from Beacon frames in the
498 * current BSS. This is in units of 1/16 of the signal unit to maintain
499 * accuracy and to speed up calculations, i.e., the value need to be
500 * divided by 16 to get the actual value.
501 */
502 int ave_beacon_signal;
503 496
504 /* 497 /*
505 * Number of Beacon frames used in ave_beacon_signal. This can be used 498 * Number of Beacon frames used in ave_beacon_signal. This can be used
@@ -535,6 +528,7 @@ struct ieee80211_if_managed {
535 struct sk_buff *teardown_skb; /* A copy to send through the AP */ 528 struct sk_buff *teardown_skb; /* A copy to send through the AP */
536 spinlock_t teardown_lock; /* To lock changing teardown_skb */ 529 spinlock_t teardown_lock; /* To lock changing teardown_skb */
537 bool tdls_chan_switch_prohibited; 530 bool tdls_chan_switch_prohibited;
531 bool tdls_wider_bw_prohibited;
538 532
539 /* WMM-AC TSPEC support */ 533 /* WMM-AC TSPEC support */
540 struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; 534 struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS];
@@ -1641,6 +1635,9 @@ void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
1641struct sk_buff * 1635struct sk_buff *
1642ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, 1636ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
1643 struct sk_buff *skb, u32 info_flags); 1637 struct sk_buff *skb, u32 info_flags);
1638void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
1639 struct ieee80211_supported_band *sband,
1640 int retry_count, int shift, bool send_to_cooked);
1644 1641
1645void ieee80211_check_fast_xmit(struct sta_info *sta); 1642void ieee80211_check_fast_xmit(struct sta_info *sta);
1646void ieee80211_check_fast_xmit_all(struct ieee80211_local *local); 1643void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
@@ -1853,7 +1850,7 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
1853void ieee80211_dynamic_ps_timer(unsigned long data); 1850void ieee80211_dynamic_ps_timer(unsigned long data);
1854void ieee80211_send_nullfunc(struct ieee80211_local *local, 1851void ieee80211_send_nullfunc(struct ieee80211_local *local,
1855 struct ieee80211_sub_if_data *sdata, 1852 struct ieee80211_sub_if_data *sdata,
1856 int powersave); 1853 bool powersave);
1857void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1854void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1858 struct ieee80211_hdr *hdr); 1855 struct ieee80211_hdr *hdr);
1859void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1856void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6964fc6a8ea2..42d7f0f65bd6 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1204,7 +1204,7 @@ static void ieee80211_iface_work(struct work_struct *work)
1204 if (!ieee80211_sdata_running(sdata)) 1204 if (!ieee80211_sdata_running(sdata))
1205 return; 1205 return;
1206 1206
1207 if (local->scanning) 1207 if (test_bit(SCAN_SW_SCANNING, &local->scanning))
1208 return; 1208 return;
1209 1209
1210 if (!ieee80211_can_run_worker(local)) 1210 if (!ieee80211_can_run_worker(local))
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ff79a13d231d..9b813a2f3a75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -543,7 +543,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
543 NL80211_FEATURE_HT_IBSS | 543 NL80211_FEATURE_HT_IBSS |
544 NL80211_FEATURE_VIF_TXPOWER | 544 NL80211_FEATURE_VIF_TXPOWER |
545 NL80211_FEATURE_MAC_ON_CREATE | 545 NL80211_FEATURE_MAC_ON_CREATE |
546 NL80211_FEATURE_USERSPACE_MPM; 546 NL80211_FEATURE_USERSPACE_MPM |
547 NL80211_FEATURE_FULL_AP_CLIENT_STATE;
547 548
548 if (!ops->hw_scan) 549 if (!ops->hw_scan)
549 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | 550 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index e06a5ca7c9a9..626e8de70842 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -94,6 +94,9 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
94 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan, 94 ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
95 ie->ht_operation, &sta_chan_def); 95 ie->ht_operation, &sta_chan_def);
96 96
97 ieee80211_vht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
98 ie->vht_operation, &sta_chan_def);
99
97 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef, 100 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
98 &sta_chan_def)) 101 &sta_chan_def))
99 return false; 102 return false;
@@ -436,8 +439,6 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
436 struct ieee80211_local *local = sdata->local; 439 struct ieee80211_local *local = sdata->local;
437 struct ieee80211_chanctx_conf *chanctx_conf; 440 struct ieee80211_chanctx_conf *chanctx_conf;
438 struct ieee80211_channel *channel; 441 struct ieee80211_channel *channel;
439 enum nl80211_channel_type channel_type =
440 cfg80211_get_chandef_type(&sdata->vif.bss_conf.chandef);
441 struct ieee80211_supported_band *sband; 442 struct ieee80211_supported_band *sband;
442 struct ieee80211_sta_ht_cap *ht_cap; 443 struct ieee80211_sta_ht_cap *ht_cap;
443 u8 *pos; 444 u8 *pos;
@@ -454,7 +455,10 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
454 sband = local->hw.wiphy->bands[channel->band]; 455 sband = local->hw.wiphy->bands[channel->band];
455 ht_cap = &sband->ht_cap; 456 ht_cap = &sband->ht_cap;
456 457
457 if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) 458 if (!ht_cap->ht_supported ||
459 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
460 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
461 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
458 return 0; 462 return 0;
459 463
460 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_operation)) 464 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_operation))
@@ -467,6 +471,68 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
467 return 0; 471 return 0;
468} 472}
469 473
474int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
475 struct sk_buff *skb)
476{
477 struct ieee80211_local *local = sdata->local;
478 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
479 struct ieee80211_supported_band *sband;
480 u8 *pos;
481
482 sband = local->hw.wiphy->bands[band];
483 if (!sband->vht_cap.vht_supported ||
484 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
485 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
486 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
487 return 0;
488
489 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_vht_cap))
490 return -ENOMEM;
491
492 pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_cap));
493 ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, sband->vht_cap.cap);
494
495 return 0;
496}
497
498int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
499 struct sk_buff *skb)
500{
501 struct ieee80211_local *local = sdata->local;
502 struct ieee80211_chanctx_conf *chanctx_conf;
503 struct ieee80211_channel *channel;
504 struct ieee80211_supported_band *sband;
505 struct ieee80211_sta_vht_cap *vht_cap;
506 u8 *pos;
507
508 rcu_read_lock();
509 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
510 if (WARN_ON(!chanctx_conf)) {
511 rcu_read_unlock();
512 return -EINVAL;
513 }
514 channel = chanctx_conf->def.chan;
515 rcu_read_unlock();
516
517 sband = local->hw.wiphy->bands[channel->band];
518 vht_cap = &sband->vht_cap;
519
520 if (!vht_cap->vht_supported ||
521 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
522 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
523 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
524 return 0;
525
526 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_vht_operation))
527 return -ENOMEM;
528
529 pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_operation));
530 ieee80211_ie_build_vht_oper(pos, vht_cap,
531 &sdata->vif.bss_conf.chandef);
532
533 return 0;
534}
535
470static void ieee80211_mesh_path_timer(unsigned long data) 536static void ieee80211_mesh_path_timer(unsigned long data)
471{ 537{
472 struct ieee80211_sub_if_data *sdata = 538 struct ieee80211_sub_if_data *sdata =
@@ -540,9 +606,9 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
540 * 606 *
541 * Return the header length. 607 * Return the header length.
542 */ 608 */
543int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata, 609unsigned int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
544 struct ieee80211s_hdr *meshhdr, 610 struct ieee80211s_hdr *meshhdr,
545 const char *addr4or5, const char *addr6) 611 const char *addr4or5, const char *addr6)
546{ 612{
547 if (WARN_ON(!addr4or5 && addr6)) 613 if (WARN_ON(!addr4or5 && addr6))
548 return 0; 614 return 0;
@@ -637,6 +703,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
637 2 + ifmsh->mesh_id_len + 703 2 + ifmsh->mesh_id_len +
638 2 + sizeof(struct ieee80211_meshconf_ie) + 704 2 + sizeof(struct ieee80211_meshconf_ie) +
639 2 + sizeof(__le16) + /* awake window */ 705 2 + sizeof(__le16) + /* awake window */
706 2 + sizeof(struct ieee80211_vht_cap) +
707 2 + sizeof(struct ieee80211_vht_operation) +
640 ifmsh->ie_len; 708 ifmsh->ie_len;
641 709
642 bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL); 710 bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL);
@@ -718,6 +786,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
718 mesh_add_meshid_ie(sdata, skb) || 786 mesh_add_meshid_ie(sdata, skb) ||
719 mesh_add_meshconf_ie(sdata, skb) || 787 mesh_add_meshconf_ie(sdata, skb) ||
720 mesh_add_awake_window_ie(sdata, skb) || 788 mesh_add_awake_window_ie(sdata, skb) ||
789 mesh_add_vht_cap_ie(sdata, skb) ||
790 mesh_add_vht_oper_ie(sdata, skb) ||
721 mesh_add_vendor_ies(sdata, skb)) 791 mesh_add_vendor_ies(sdata, skb))
722 goto out_free; 792 goto out_free;
723 793
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 50c8473cf9dc..a1596344c3ba 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -207,9 +207,9 @@ struct mesh_rmc {
207/* Various */ 207/* Various */
208int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 208int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
209 const u8 *da, const u8 *sa); 209 const u8 *da, const u8 *sa);
210int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata, 210unsigned int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata,
211 struct ieee80211s_hdr *meshhdr, 211 struct ieee80211s_hdr *meshhdr,
212 const char *addr4or5, const char *addr6); 212 const char *addr4or5, const char *addr6);
213int mesh_rmc_check(struct ieee80211_sub_if_data *sdata, 213int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
214 const u8 *addr, struct ieee80211s_hdr *mesh_hdr); 214 const u8 *addr, struct ieee80211s_hdr *mesh_hdr);
215bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 215bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
@@ -227,6 +227,10 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
227 struct sk_buff *skb); 227 struct sk_buff *skb);
228int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata, 228int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
229 struct sk_buff *skb); 229 struct sk_buff *skb);
230int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
231 struct sk_buff *skb);
232int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
233 struct sk_buff *skb);
230void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 234void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
231int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 235int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
232void ieee80211s_init(void); 236void ieee80211s_init(void);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 58384642e03c..a360b24b7df8 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -226,6 +226,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
226 2 + sizeof(struct ieee80211_meshconf_ie) + 226 2 + sizeof(struct ieee80211_meshconf_ie) +
227 2 + sizeof(struct ieee80211_ht_cap) + 227 2 + sizeof(struct ieee80211_ht_cap) +
228 2 + sizeof(struct ieee80211_ht_operation) + 228 2 + sizeof(struct ieee80211_ht_operation) +
229 2 + sizeof(struct ieee80211_vht_cap) +
230 2 + sizeof(struct ieee80211_vht_operation) +
229 2 + 8 + /* peering IE */ 231 2 + 8 + /* peering IE */
230 sdata->u.mesh.ie_len); 232 sdata->u.mesh.ie_len);
231 if (!skb) 233 if (!skb)
@@ -306,7 +308,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
306 308
307 if (action != WLAN_SP_MESH_PEERING_CLOSE) { 309 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
308 if (mesh_add_ht_cap_ie(sdata, skb) || 310 if (mesh_add_ht_cap_ie(sdata, skb) ||
309 mesh_add_ht_oper_ie(sdata, skb)) 311 mesh_add_ht_oper_ie(sdata, skb) ||
312 mesh_add_vht_cap_ie(sdata, skb) ||
313 mesh_add_vht_oper_ie(sdata, skb))
310 goto free; 314 goto free;
311 } 315 }
312 316
@@ -402,6 +406,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
402 elems->ht_cap_elem, sta)) 406 elems->ht_cap_elem, sta))
403 changed |= IEEE80211_RC_BW_CHANGED; 407 changed |= IEEE80211_RC_BW_CHANGED;
404 408
409 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
410 elems->vht_cap_elem, sta);
411
405 if (bw != sta->sta.bandwidth) 412 if (bw != sta->sta.bandwidth)
406 changed |= IEEE80211_RC_BW_CHANGED; 413 changed |= IEEE80211_RC_BW_CHANGED;
407 414
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cd7e55e08a23..56ef9a8e151c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -82,13 +82,6 @@ MODULE_PARM_DESC(probe_wait_ms,
82 " before disconnecting (reason 4)."); 82 " before disconnecting (reason 4).");
83 83
84/* 84/*
85 * Weight given to the latest Beacon frame when calculating average signal
86 * strength for Beacon frames received in the current BSS. This must be
87 * between 1 and 15.
88 */
89#define IEEE80211_SIGNAL_AVE_WEIGHT 3
90
91/*
92 * How many Beacon frames need to have been used in average signal strength 85 * How many Beacon frames need to have been used in average signal strength
93 * before starting to indicate signal change events. 86 * before starting to indicate signal change events.
94 */ 87 */
@@ -943,7 +936,7 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
943 936
944void ieee80211_send_nullfunc(struct ieee80211_local *local, 937void ieee80211_send_nullfunc(struct ieee80211_local *local,
945 struct ieee80211_sub_if_data *sdata, 938 struct ieee80211_sub_if_data *sdata,
946 int powersave) 939 bool powersave)
947{ 940{
948 struct sk_buff *skb; 941 struct sk_buff *skb;
949 struct ieee80211_hdr_3addr *nullfunc; 942 struct ieee80211_hdr_3addr *nullfunc;
@@ -1427,7 +1420,7 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
1427 msecs_to_jiffies(conf->dynamic_ps_timeout)); 1420 msecs_to_jiffies(conf->dynamic_ps_timeout));
1428 } else { 1421 } else {
1429 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) 1422 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
1430 ieee80211_send_nullfunc(local, sdata, 1); 1423 ieee80211_send_nullfunc(local, sdata, true);
1431 1424
1432 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && 1425 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
1433 ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) 1426 ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
@@ -1642,7 +1635,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1642 msecs_to_jiffies( 1635 msecs_to_jiffies(
1643 local->hw.conf.dynamic_ps_timeout)); 1636 local->hw.conf.dynamic_ps_timeout));
1644 } else { 1637 } else {
1645 ieee80211_send_nullfunc(local, sdata, 1); 1638 ieee80211_send_nullfunc(local, sdata, true);
1646 /* Flush to get the tx status of nullfunc frame */ 1639 /* Flush to get the tx status of nullfunc frame */
1647 ieee80211_flush_queues(local, sdata, false); 1640 ieee80211_flush_queues(local, sdata, false);
1648 } 1641 }
@@ -2275,7 +2268,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
2275 2268
2276 if (ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) { 2269 if (ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) {
2277 ifmgd->nullfunc_failed = false; 2270 ifmgd->nullfunc_failed = false;
2278 ieee80211_send_nullfunc(sdata->local, sdata, 0); 2271 ieee80211_send_nullfunc(sdata->local, sdata, false);
2279 } else { 2272 } else {
2280 int ssid_len; 2273 int ssid_len;
2281 2274
@@ -3262,16 +3255,6 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
3262 if (ifmgd->associated && 3255 if (ifmgd->associated &&
3263 ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 3256 ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
3264 ieee80211_reset_ap_probe(sdata); 3257 ieee80211_reset_ap_probe(sdata);
3265
3266 if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
3267 ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) {
3268 /* got probe response, continue with auth */
3269 sdata_info(sdata, "direct probe responded\n");
3270 ifmgd->auth_data->tries = 0;
3271 ifmgd->auth_data->timeout = jiffies;
3272 ifmgd->auth_data->timeout_started = true;
3273 run_again(sdata, ifmgd->auth_data->timeout);
3274 }
3275} 3258}
3276 3259
3277/* 3260/*
@@ -3374,24 +3357,21 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3374 bssid = ifmgd->associated->bssid; 3357 bssid = ifmgd->associated->bssid;
3375 3358
3376 /* Track average RSSI from the Beacon frames of the current AP */ 3359 /* Track average RSSI from the Beacon frames of the current AP */
3377 ifmgd->last_beacon_signal = rx_status->signal;
3378 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { 3360 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
3379 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; 3361 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
3380 ifmgd->ave_beacon_signal = rx_status->signal * 16; 3362 ewma_beacon_signal_init(&ifmgd->ave_beacon_signal);
3381 ifmgd->last_cqm_event_signal = 0; 3363 ifmgd->last_cqm_event_signal = 0;
3382 ifmgd->count_beacon_signal = 1; 3364 ifmgd->count_beacon_signal = 1;
3383 ifmgd->last_ave_beacon_signal = 0; 3365 ifmgd->last_ave_beacon_signal = 0;
3384 } else { 3366 } else {
3385 ifmgd->ave_beacon_signal =
3386 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
3387 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
3388 ifmgd->ave_beacon_signal) / 16;
3389 ifmgd->count_beacon_signal++; 3367 ifmgd->count_beacon_signal++;
3390 } 3368 }
3391 3369
3370 ewma_beacon_signal_add(&ifmgd->ave_beacon_signal, -rx_status->signal);
3371
3392 if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold && 3372 if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
3393 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) { 3373 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
3394 int sig = ifmgd->ave_beacon_signal; 3374 int sig = -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal);
3395 int last_sig = ifmgd->last_ave_beacon_signal; 3375 int last_sig = ifmgd->last_ave_beacon_signal;
3396 struct ieee80211_event event = { 3376 struct ieee80211_event event = {
3397 .type = RSSI_EVENT, 3377 .type = RSSI_EVENT,
@@ -3418,10 +3398,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3418 if (bss_conf->cqm_rssi_thold && 3398 if (bss_conf->cqm_rssi_thold &&
3419 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && 3399 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
3420 !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) { 3400 !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
3421 int sig = ifmgd->ave_beacon_signal / 16; 3401 int sig = -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal);
3422 int last_event = ifmgd->last_cqm_event_signal; 3402 int last_event = ifmgd->last_cqm_event_signal;
3423 int thold = bss_conf->cqm_rssi_thold; 3403 int thold = bss_conf->cqm_rssi_thold;
3424 int hyst = bss_conf->cqm_rssi_hyst; 3404 int hyst = bss_conf->cqm_rssi_hyst;
3405
3425 if (sig < thold && 3406 if (sig < thold &&
3426 (last_event == 0 || sig < last_event - hyst)) { 3407 (last_event == 0 || sig < last_event - hyst)) {
3427 ifmgd->last_cqm_event_signal = sig; 3408 ifmgd->last_cqm_event_signal = sig;
@@ -3456,31 +3437,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3456 len - baselen, false, &elems, 3437 len - baselen, false, &elems,
3457 care_about_ies, ncrc); 3438 care_about_ies, ncrc);
3458 3439
3459 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) { 3440 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
3460 bool directed_tim = ieee80211_check_tim(elems.tim, 3441 ieee80211_check_tim(elems.tim, elems.tim_len, ifmgd->aid)) {
3461 elems.tim_len, 3442 if (local->hw.conf.dynamic_ps_timeout > 0) {
3462 ifmgd->aid); 3443 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
3463 if (directed_tim) { 3444 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
3464 if (local->hw.conf.dynamic_ps_timeout > 0) { 3445 ieee80211_hw_config(local,
3465 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 3446 IEEE80211_CONF_CHANGE_PS);
3466 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
3467 ieee80211_hw_config(local,
3468 IEEE80211_CONF_CHANGE_PS);
3469 }
3470 ieee80211_send_nullfunc(local, sdata, 0);
3471 } else if (!local->pspolling && sdata->u.mgd.powersave) {
3472 local->pspolling = true;
3473
3474 /*
3475 * Here is assumed that the driver will be
3476 * able to send ps-poll frame and receive a
3477 * response even though power save mode is
3478 * enabled, but some drivers might require
3479 * to disable power save here. This needs
3480 * to be investigated.
3481 */
3482 ieee80211_send_pspoll(local, sdata);
3483 } 3447 }
3448 ieee80211_send_nullfunc(local, sdata, false);
3449 } else if (!local->pspolling && sdata->u.mgd.powersave) {
3450 local->pspolling = true;
3451
3452 /*
3453 * Here is assumed that the driver will be
3454 * able to send ps-poll frame and receive a
3455 * response even though power save mode is
3456 * enabled, but some drivers might require
3457 * to disable power save here. This needs
3458 * to be investigated.
3459 */
3460 ieee80211_send_pspoll(local, sdata);
3484 } 3461 }
3485 } 3462 }
3486 3463
@@ -3717,12 +3694,14 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
3717 reason); 3694 reason);
3718} 3695}
3719 3696
3720static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) 3697static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
3721{ 3698{
3722 struct ieee80211_local *local = sdata->local; 3699 struct ieee80211_local *local = sdata->local;
3723 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3700 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3724 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; 3701 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
3725 u32 tx_flags = 0; 3702 u32 tx_flags = 0;
3703 u16 trans = 1;
3704 u16 status = 0;
3726 3705
3727 sdata_assert_lock(sdata); 3706 sdata_assert_lock(sdata);
3728 3707
@@ -3746,54 +3725,27 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
3746 3725
3747 drv_mgd_prepare_tx(local, sdata); 3726 drv_mgd_prepare_tx(local, sdata);
3748 3727
3749 if (auth_data->bss->proberesp_ies) { 3728 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
3750 u16 trans = 1; 3729 auth_data->bss->bssid, auth_data->tries,
3751 u16 status = 0; 3730 IEEE80211_AUTH_MAX_TRIES);
3752
3753 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
3754 auth_data->bss->bssid, auth_data->tries,
3755 IEEE80211_AUTH_MAX_TRIES);
3756 3731
3757 auth_data->expected_transaction = 2; 3732 auth_data->expected_transaction = 2;
3758 3733
3759 if (auth_data->algorithm == WLAN_AUTH_SAE) { 3734 if (auth_data->algorithm == WLAN_AUTH_SAE) {
3760 trans = auth_data->sae_trans; 3735 trans = auth_data->sae_trans;
3761 status = auth_data->sae_status; 3736 status = auth_data->sae_status;
3762 auth_data->expected_transaction = trans; 3737 auth_data->expected_transaction = trans;
3763 } 3738 }
3764
3765 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
3766 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
3767 IEEE80211_TX_INTFL_MLME_CONN_TX;
3768
3769 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
3770 auth_data->data, auth_data->data_len,
3771 auth_data->bss->bssid,
3772 auth_data->bss->bssid, NULL, 0, 0,
3773 tx_flags);
3774 } else {
3775 const u8 *ssidie;
3776 3739
3777 sdata_info(sdata, "direct probe to %pM (try %d/%i)\n", 3740 if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
3778 auth_data->bss->bssid, auth_data->tries, 3741 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
3779 IEEE80211_AUTH_MAX_TRIES); 3742 IEEE80211_TX_INTFL_MLME_CONN_TX;
3780 3743
3781 rcu_read_lock(); 3744 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
3782 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); 3745 auth_data->data, auth_data->data_len,
3783 if (!ssidie) { 3746 auth_data->bss->bssid,
3784 rcu_read_unlock(); 3747 auth_data->bss->bssid, NULL, 0, 0,
3785 return -EINVAL; 3748 tx_flags);
3786 }
3787 /*
3788 * Direct probe is sent to broadcast address as some APs
3789 * will not answer to direct packet in unassociated state.
3790 */
3791 ieee80211_send_probe_req(sdata, sdata->vif.addr, NULL,
3792 ssidie + 2, ssidie[1],
3793 NULL, 0, (u32) -1, true, 0,
3794 auth_data->bss->channel, false);
3795 rcu_read_unlock();
3796 }
3797 3749
3798 if (tx_flags == 0) { 3750 if (tx_flags == 0) {
3799 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 3751 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
@@ -3874,8 +3826,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3874 bool status_acked = ifmgd->status_acked; 3826 bool status_acked = ifmgd->status_acked;
3875 3827
3876 ifmgd->status_received = false; 3828 ifmgd->status_received = false;
3877 if (ifmgd->auth_data && 3829 if (ifmgd->auth_data && ieee80211_is_auth(fc)) {
3878 (ieee80211_is_probe_req(fc) || ieee80211_is_auth(fc))) {
3879 if (status_acked) { 3830 if (status_acked) {
3880 ifmgd->auth_data->timeout = 3831 ifmgd->auth_data->timeout =
3881 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; 3832 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
@@ -3906,7 +3857,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3906 * so let's just kill the auth data 3857 * so let's just kill the auth data
3907 */ 3858 */
3908 ieee80211_destroy_auth_data(sdata, false); 3859 ieee80211_destroy_auth_data(sdata, false);
3909 } else if (ieee80211_probe_auth(sdata)) { 3860 } else if (ieee80211_auth(sdata)) {
3910 u8 bssid[ETH_ALEN]; 3861 u8 bssid[ETH_ALEN];
3911 struct ieee80211_event event = { 3862 struct ieee80211_event event = {
3912 .type = MLME_EVENT, 3863 .type = MLME_EVENT,
@@ -4613,7 +4564,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4613 if (err) 4564 if (err)
4614 goto err_clear; 4565 goto err_clear;
4615 4566
4616 err = ieee80211_probe_auth(sdata); 4567 err = ieee80211_auth(sdata);
4617 if (err) { 4568 if (err) {
4618 sta_info_destroy_addr(sdata, req->bss->bssid); 4569 sta_info_destroy_addr(sdata, req->bss->bssid);
4619 goto err_clear; 4570 goto err_clear;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index f2c75cf491fc..04401037140e 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -57,7 +57,7 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
57 * to send a new nullfunc frame to inform the AP that we 57 * to send a new nullfunc frame to inform the AP that we
58 * are again sleeping. 58 * are again sleeping.
59 */ 59 */
60 ieee80211_send_nullfunc(local, sdata, 1); 60 ieee80211_send_nullfunc(local, sdata, true);
61} 61}
62 62
63/* inform AP that we are awake again, unless power save is enabled */ 63/* inform AP that we are awake again, unless power save is enabled */
@@ -66,7 +66,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
66 struct ieee80211_local *local = sdata->local; 66 struct ieee80211_local *local = sdata->local;
67 67
68 if (!local->ps_sdata) 68 if (!local->ps_sdata)
69 ieee80211_send_nullfunc(local, sdata, 0); 69 ieee80211_send_nullfunc(local, sdata, false);
70 else if (local->offchannel_ps_enabled) { 70 else if (local->offchannel_ps_enabled) {
71 /* 71 /*
72 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware 72 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
@@ -93,7 +93,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
93 * restart the timer now and send a nullfunc frame to inform 93 * restart the timer now and send a nullfunc frame to inform
94 * the AP that we are awake. 94 * the AP that we are awake.
95 */ 95 */
96 ieee80211_send_nullfunc(local, sdata, 0); 96 ieee80211_send_nullfunc(local, sdata, false);
97 mod_timer(&local->dynamic_ps_timer, jiffies + 97 mod_timer(&local->dynamic_ps_timer, jiffies +
98 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); 98 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
99 } 99 }
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index b676b9fa707b..ad88ad4e8eb1 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -23,7 +23,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
23 23
24 ieee80211_del_virtual_monitor(local); 24 ieee80211_del_virtual_monitor(local);
25 25
26 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION)) { 26 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION) &&
27 !(wowlan && wowlan->any)) {
27 mutex_lock(&local->sta_mtx); 28 mutex_lock(&local->sta_mtx);
28 list_for_each_entry(sta, &local->sta_list, list) { 29 list_for_each_entry(sta, &local->sta_list, list) {
29 set_sta_flag(sta, WLAN_STA_BLOCK_BA); 30 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 9ce8883d5f44..b07e2f748f93 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -305,7 +305,10 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
305 info->control.rates[0].idx = i; 305 info->control.rates[0].idx = i;
306 break; 306 break;
307 } 307 }
308 WARN_ON_ONCE(i == sband->n_bitrates); 308 WARN_ONCE(i == sband->n_bitrates,
309 "no supported rates (0x%x) in rate_mask 0x%x with flags 0x%x\n",
310 sta ? sta->supp_rates[sband->band] : 0,
311 rate_mask, rate_flags);
309 312
310 info->control.rates[0].count = 313 info->control.rates[0].count =
311 (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 314 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index 1db5f7c3318a..820b0abc9c0d 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -85,12 +85,10 @@ minstrel_stats_open(struct inode *inode, struct file *file)
85 file->private_data = ms; 85 file->private_data = ms;
86 p = ms->buf; 86 p = ms->buf;
87 p += sprintf(p, "\n"); 87 p += sprintf(p, "\n");
88 p += sprintf(p, "best __________rate_________ ______" 88 p += sprintf(p,
89 "statistics______ ________last_______ " 89 "best __________rate_________ ________statistics________ ________last_______ ______sum-of________\n");
90 "______sum-of________\n"); 90 p += sprintf(p,
91 p += sprintf(p, "rate [name idx airtime max_tp] [ Ăž(tp) Ăž(prob) " 91 "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n");
92 "sd(prob)] [prob.|retry|suc|att] "
93 "[#success | #attempts]\n");
94 92
95 for (i = 0; i < mi->n_rates; i++) { 93 for (i = 0; i < mi->n_rates; i++) {
96 struct minstrel_rate *mr = &mi->r[i]; 94 struct minstrel_rate *mr = &mi->r[i];
@@ -112,7 +110,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
112 prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 110 prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
113 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 111 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
114 112
115 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" 113 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
116 " %3u.%1u %3u %3u %-3u " 114 " %3u.%1u %3u %3u %-3u "
117 "%9llu %-9llu\n", 115 "%9llu %-9llu\n",
118 tp_max / 10, tp_max % 10, 116 tp_max / 10, tp_max % 10,
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index 6822ce0f95e5..5320e35ed3d0 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -86,7 +86,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
86 prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 86 prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
87 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); 87 eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
88 88
89 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u" 89 p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
90 " %3u.%1u %3u %3u %-3u " 90 " %3u.%1u %3u %3u %-3u "
91 "%9llu %-9llu\n", 91 "%9llu %-9llu\n",
92 tp_max / 10, tp_max % 10, 92 tp_max / 10, tp_max % 10,
@@ -129,12 +129,10 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
129 p = ms->buf; 129 p = ms->buf;
130 130
131 p += sprintf(p, "\n"); 131 p += sprintf(p, "\n");
132 p += sprintf(p, " best ____________rate__________ " 132 p += sprintf(p,
133 "______statistics______ ________last_______ " 133 " best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n");
134 "______sum-of________\n"); 134 p += sprintf(p,
135 p += sprintf(p, "mode guard # rate [name idx airtime max_tp] " 135 "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n");
136 "[ Ăž(tp) Ăž(prob) sd(prob)] [prob.|retry|suc|att] [#success | "
137 "#attempts]\n");
138 136
139 p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); 137 p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
140 for (i = 0; i < MINSTREL_CCK_GROUP; i++) 138 for (i = 0; i < MINSTREL_CCK_GROUP; i++)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index b087c71ff7fe..d5ded8749ac4 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -133,6 +133,7 @@ enum ieee80211_agg_stop_reason {
133 * @buf_size: reorder buffer size at receiver 133 * @buf_size: reorder buffer size at receiver
134 * @failed_bar_ssn: ssn of the last failed BAR tx attempt 134 * @failed_bar_ssn: ssn of the last failed BAR tx attempt
135 * @bar_pending: BAR needs to be re-sent 135 * @bar_pending: BAR needs to be re-sent
136 * @amsdu: support A-MSDU withing A-MDPU
136 * 137 *
137 * This structure's lifetime is managed by RCU, assignments to 138 * This structure's lifetime is managed by RCU, assignments to
138 * the array holding it must hold the aggregation mutex. 139 * the array holding it must hold the aggregation mutex.
@@ -158,6 +159,7 @@ struct tid_ampdu_tx {
158 159
159 u16 failed_bar_ssn; 160 u16 failed_bar_ssn;
160 bool bar_pending; 161 bool bar_pending;
162 bool amsdu;
161}; 163};
162 164
163/** 165/**
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 8ba583243509..98fd04c4b2a0 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -668,16 +668,70 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
668} 668}
669EXPORT_SYMBOL(ieee80211_tx_status_noskb); 669EXPORT_SYMBOL(ieee80211_tx_status_noskb);
670 670
671void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) 671void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
672 struct ieee80211_supported_band *sband,
673 int retry_count, int shift, bool send_to_cooked)
672{ 674{
673 struct sk_buff *skb2; 675 struct sk_buff *skb2;
676 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
677 struct ieee80211_sub_if_data *sdata;
678 struct net_device *prev_dev = NULL;
679 int rtap_len;
680
681 /* send frame to monitor interfaces now */
682 rtap_len = ieee80211_tx_radiotap_len(info);
683 if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
684 pr_err("ieee80211_tx_status: headroom too small\n");
685 dev_kfree_skb(skb);
686 return;
687 }
688 ieee80211_add_tx_radiotap_header(local, sband, skb, retry_count,
689 rtap_len, shift);
690
691 /* XXX: is this sufficient for BPF? */
692 skb_set_mac_header(skb, 0);
693 skb->ip_summed = CHECKSUM_UNNECESSARY;
694 skb->pkt_type = PACKET_OTHERHOST;
695 skb->protocol = htons(ETH_P_802_2);
696 memset(skb->cb, 0, sizeof(skb->cb));
697
698 rcu_read_lock();
699 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
700 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
701 if (!ieee80211_sdata_running(sdata))
702 continue;
703
704 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
705 !send_to_cooked)
706 continue;
707
708 if (prev_dev) {
709 skb2 = skb_clone(skb, GFP_ATOMIC);
710 if (skb2) {
711 skb2->dev = prev_dev;
712 netif_rx(skb2);
713 }
714 }
715
716 prev_dev = sdata->dev;
717 }
718 }
719 if (prev_dev) {
720 skb->dev = prev_dev;
721 netif_rx(skb);
722 skb = NULL;
723 }
724 rcu_read_unlock();
725 dev_kfree_skb(skb);
726}
727
728void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
729{
674 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 730 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
675 struct ieee80211_local *local = hw_to_local(hw); 731 struct ieee80211_local *local = hw_to_local(hw);
676 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 732 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
677 __le16 fc; 733 __le16 fc;
678 struct ieee80211_supported_band *sband; 734 struct ieee80211_supported_band *sband;
679 struct ieee80211_sub_if_data *sdata;
680 struct net_device *prev_dev = NULL;
681 struct sta_info *sta; 735 struct sta_info *sta;
682 struct rhash_head *tmp; 736 struct rhash_head *tmp;
683 int retry_count; 737 int retry_count;
@@ -685,7 +739,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
685 bool send_to_cooked; 739 bool send_to_cooked;
686 bool acked; 740 bool acked;
687 struct ieee80211_bar *bar; 741 struct ieee80211_bar *bar;
688 int rtap_len;
689 int shift = 0; 742 int shift = 0;
690 int tid = IEEE80211_NUM_TIDS; 743 int tid = IEEE80211_NUM_TIDS;
691 const struct bucket_table *tbl; 744 const struct bucket_table *tbl;
@@ -878,51 +931,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
878 return; 931 return;
879 } 932 }
880 933
881 /* send frame to monitor interfaces now */ 934 /* send to monitor interfaces */
882 rtap_len = ieee80211_tx_radiotap_len(info); 935 ieee80211_tx_monitor(local, skb, sband, retry_count, shift, send_to_cooked);
883 if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
884 pr_err("ieee80211_tx_status: headroom too small\n");
885 dev_kfree_skb(skb);
886 return;
887 }
888 ieee80211_add_tx_radiotap_header(local, sband, skb, retry_count,
889 rtap_len, shift);
890
891 /* XXX: is this sufficient for BPF? */
892 skb_set_mac_header(skb, 0);
893 skb->ip_summed = CHECKSUM_UNNECESSARY;
894 skb->pkt_type = PACKET_OTHERHOST;
895 skb->protocol = htons(ETH_P_802_2);
896 memset(skb->cb, 0, sizeof(skb->cb));
897
898 rcu_read_lock();
899 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
900 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
901 if (!ieee80211_sdata_running(sdata))
902 continue;
903
904 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
905 !send_to_cooked)
906 continue;
907
908 if (prev_dev) {
909 skb2 = skb_clone(skb, GFP_ATOMIC);
910 if (skb2) {
911 skb2->dev = prev_dev;
912 netif_rx(skb2);
913 }
914 }
915
916 prev_dev = sdata->dev;
917 }
918 }
919 if (prev_dev) {
920 skb->dev = prev_dev;
921 netif_rx(skb);
922 skb = NULL;
923 }
924 rcu_read_unlock();
925 dev_kfree_skb(skb);
926} 936}
927EXPORT_SYMBOL(ieee80211_tx_status); 937EXPORT_SYMBOL(ieee80211_tx_status);
928 938
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 4e202d0679b2..ecc5e2a8f80b 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -41,9 +41,11 @@ static void ieee80211_tdls_add_ext_capab(struct ieee80211_sub_if_data *sdata,
41 struct sk_buff *skb) 41 struct sk_buff *skb)
42{ 42{
43 struct ieee80211_local *local = sdata->local; 43 struct ieee80211_local *local = sdata->local;
44 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
44 bool chan_switch = local->hw.wiphy->features & 45 bool chan_switch = local->hw.wiphy->features &
45 NL80211_FEATURE_TDLS_CHANNEL_SWITCH; 46 NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
46 bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW); 47 bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
48 !ifmgd->tdls_wider_bw_prohibited;
47 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 49 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
48 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 50 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
49 bool vht = sband && sband->vht_cap.vht_supported; 51 bool vht = sband && sband->vht_cap.vht_supported;
@@ -331,8 +333,8 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata,
331 333
332 /* proceed to downgrade the chandef until usable or the same */ 334 /* proceed to downgrade the chandef until usable or the same */
333 while (uc.width > max_width && 335 while (uc.width > max_width &&
334 !cfg80211_reg_can_beacon(sdata->local->hw.wiphy, 336 !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc,
335 &uc, sdata->wdev.iftype)) 337 sdata->wdev.iftype))
336 ieee80211_chandef_downgrade(&uc); 338 ieee80211_chandef_downgrade(&uc);
337 339
338 if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) { 340 if (!cfg80211_chandef_identical(&uc, &sta->tdls_chandef)) {
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 6f14591d8ca9..314e3bd7fbdb 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -497,6 +497,36 @@ TRACE_EVENT(drv_configure_filter,
497 ) 497 )
498); 498);
499 499
500TRACE_EVENT(drv_config_iface_filter,
501 TP_PROTO(struct ieee80211_local *local,
502 struct ieee80211_sub_if_data *sdata,
503 unsigned int filter_flags,
504 unsigned int changed_flags),
505
506 TP_ARGS(local, sdata, filter_flags, changed_flags),
507
508 TP_STRUCT__entry(
509 LOCAL_ENTRY
510 VIF_ENTRY
511 __field(unsigned int, filter_flags)
512 __field(unsigned int, changed_flags)
513 ),
514
515 TP_fast_assign(
516 LOCAL_ASSIGN;
517 VIF_ASSIGN;
518 __entry->filter_flags = filter_flags;
519 __entry->changed_flags = changed_flags;
520 ),
521
522 TP_printk(
523 LOCAL_PR_FMT VIF_PR_FMT
524 " filter_flags: %#x changed_flags: %#x",
525 LOCAL_PR_ARG, VIF_PR_ARG, __entry->filter_flags,
526 __entry->changed_flags
527 )
528);
529
500TRACE_EVENT(drv_set_tim, 530TRACE_EVENT(drv_set_tim,
501 TP_PROTO(struct ieee80211_local *local, 531 TP_PROTO(struct ieee80211_local *local,
502 struct ieee80211_sta *sta, bool set), 532 struct ieee80211_sta *sta, bool set),
@@ -944,9 +974,9 @@ TRACE_EVENT(drv_ampdu_action,
944 struct ieee80211_sub_if_data *sdata, 974 struct ieee80211_sub_if_data *sdata,
945 enum ieee80211_ampdu_mlme_action action, 975 enum ieee80211_ampdu_mlme_action action,
946 struct ieee80211_sta *sta, u16 tid, 976 struct ieee80211_sta *sta, u16 tid,
947 u16 *ssn, u8 buf_size), 977 u16 *ssn, u8 buf_size, bool amsdu),
948 978
949 TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size), 979 TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size, amsdu),
950 980
951 TP_STRUCT__entry( 981 TP_STRUCT__entry(
952 LOCAL_ENTRY 982 LOCAL_ENTRY
@@ -955,6 +985,7 @@ TRACE_EVENT(drv_ampdu_action,
955 __field(u16, tid) 985 __field(u16, tid)
956 __field(u16, ssn) 986 __field(u16, ssn)
957 __field(u8, buf_size) 987 __field(u8, buf_size)
988 __field(bool, amsdu)
958 VIF_ENTRY 989 VIF_ENTRY
959 ), 990 ),
960 991
@@ -966,12 +997,13 @@ TRACE_EVENT(drv_ampdu_action,
966 __entry->tid = tid; 997 __entry->tid = tid;
967 __entry->ssn = ssn ? *ssn : 0; 998 __entry->ssn = ssn ? *ssn : 0;
968 __entry->buf_size = buf_size; 999 __entry->buf_size = buf_size;
1000 __entry->amsdu = amsdu;
969 ), 1001 ),
970 1002
971 TP_printk( 1003 TP_printk(
972 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d", 1004 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d amsdu:%d",
973 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, 1005 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action,
974 __entry->tid, __entry->buf_size 1006 __entry->tid, __entry->buf_size, __entry->amsdu
975 ) 1007 )
976); 1008);
977 1009
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 84e0e8c7fb23..464ba1a625bd 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2767,7 +2767,8 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
2767 2767
2768 if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { 2768 if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
2769 *ieee80211_get_qos_ctl(hdr) = tid; 2769 *ieee80211_get_qos_ctl(hdr) = tid;
2770 hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); 2770 if (!sta->sta.txq[0])
2771 hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
2771 } else { 2772 } else {
2772 info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; 2773 info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
2773 hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number); 2774 hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);
@@ -3512,6 +3513,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
3512{ 3513{
3513 struct ieee80211_mutable_offsets offs = {}; 3514 struct ieee80211_mutable_offsets offs = {};
3514 struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false); 3515 struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false);
3516 struct sk_buff *copy;
3517 struct ieee80211_supported_band *sband;
3518 int shift;
3519
3520 if (!bcn)
3521 return bcn;
3515 3522
3516 if (tim_offset) 3523 if (tim_offset)
3517 *tim_offset = offs.tim_offset; 3524 *tim_offset = offs.tim_offset;
@@ -3519,6 +3526,19 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
3519 if (tim_length) 3526 if (tim_length)
3520 *tim_length = offs.tim_length; 3527 *tim_length = offs.tim_length;
3521 3528
3529 if (ieee80211_hw_check(hw, BEACON_TX_STATUS) ||
3530 !hw_to_local(hw)->monitors)
3531 return bcn;
3532
3533 /* send a copy to monitor interfaces */
3534 copy = skb_copy(bcn, GFP_ATOMIC);
3535 if (!copy)
3536 return bcn;
3537
3538 shift = ieee80211_vif_get_shift(vif);
3539 sband = hw->wiphy->bands[ieee80211_get_sdata_band(vif_to_sdata(vif))];
3540 ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
3541
3522 return bcn; 3542 return bcn;
3523} 3543}
3524EXPORT_SYMBOL(ieee80211_beacon_get_tim); 3544EXPORT_SYMBOL(ieee80211_beacon_get_tim);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1104421bc525..60c4dbf92625 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1966,7 +1966,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1966 if (!sdata->u.mgd.associated) 1966 if (!sdata->u.mgd.associated)
1967 continue; 1967 continue;
1968 1968
1969 ieee80211_send_nullfunc(local, sdata, 0); 1969 ieee80211_send_nullfunc(local, sdata, false);
1970 } 1970 }
1971 } 1971 }
1972 1972
@@ -2017,8 +2017,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2017 mutex_lock(&local->sta_mtx); 2017 mutex_lock(&local->sta_mtx);
2018 2018
2019 list_for_each_entry(sta, &local->sta_list, list) { 2019 list_for_each_entry(sta, &local->sta_list, list) {
2020 ieee80211_sta_tear_down_BA_sessions( 2020 if (!local->resuming)
2021 sta, AGG_STOP_LOCAL_REQUEST); 2021 ieee80211_sta_tear_down_BA_sessions(
2022 sta, AGG_STOP_LOCAL_REQUEST);
2022 clear_sta_flag(sta, WLAN_STA_BLOCK_BA); 2023 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
2023 } 2024 }
2024 2025
@@ -2324,6 +2325,8 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
2324 if (chandef->center_freq2) 2325 if (chandef->center_freq2)
2325 vht_oper->center_freq_seg2_idx = 2326 vht_oper->center_freq_seg2_idx =
2326 ieee80211_frequency_to_channel(chandef->center_freq2); 2327 ieee80211_frequency_to_channel(chandef->center_freq2);
2328 else
2329 vht_oper->center_freq_seg2_idx = 0x00;
2327 2330
2328 switch (chandef->width) { 2331 switch (chandef->width) {
2329 case NL80211_CHAN_WIDTH_160: 2332 case NL80211_CHAN_WIDTH_160:
@@ -2541,7 +2544,7 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif)
2541 /* non-managed type inferfaces */ 2544 /* non-managed type inferfaces */
2542 return 0; 2545 return 0;
2543 } 2546 }
2544 return ifmgd->ave_beacon_signal / 16; 2547 return -ewma_beacon_signal_read(&ifmgd->ave_beacon_signal);
2545} 2548}
2546EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); 2549EXPORT_SYMBOL_GPL(ieee80211_ave_rssi);
2547 2550