aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c92
-rw-r--r--net/mac80211/chan.c5
-rw-r--r--net/mac80211/debugfs.c55
-rw-r--r--net/mac80211/driver-ops.h27
-rw-r--r--net/mac80211/ibss.c608
-rw-r--r--net/mac80211/ieee80211_i.h30
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/key.c2
-rw-r--r--net/mac80211/mlme.c334
-rw-r--r--net/mac80211/rc80211_minstrel.c14
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c23
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c26
-rw-r--r--net/mac80211/rx.c39
-rw-r--r--net/mac80211/scan.c3
-rw-r--r--net/mac80211/spectmgmt.c162
-rw-r--r--net/mac80211/trace.h35
-rw-r--r--net/mac80211/tx.c39
-rw-r--r--net/mac80211/util.c162
-rw-r--r--net/mac80211/vht.c4
19 files changed, 1159 insertions, 505 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2e7855a1b10d..ac28af74a414 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2865,30 +2865,43 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
2865 if (!ieee80211_sdata_running(sdata)) 2865 if (!ieee80211_sdata_running(sdata))
2866 return; 2866 return;
2867 2867
2868 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
2869 return;
2870
2871 sdata->radar_required = sdata->csa_radar_required; 2868 sdata->radar_required = sdata->csa_radar_required;
2872 err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, 2869 err = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
2873 &changed); 2870 &changed);
2874 if (WARN_ON(err < 0)) 2871 if (WARN_ON(err < 0))
2875 return; 2872 return;
2876 2873
2877 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); 2874 if (!local->use_chanctx) {
2878 if (err < 0) 2875 local->_oper_chandef = local->csa_chandef;
2879 return; 2876 ieee80211_hw_config(local, 0);
2877 }
2880 2878
2881 changed |= err; 2879 ieee80211_bss_info_change_notify(sdata, changed);
2882 kfree(sdata->u.ap.next_beacon); 2880
2883 sdata->u.ap.next_beacon = NULL; 2881 switch (sdata->vif.type) {
2882 case NL80211_IFTYPE_AP:
2883 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
2884 if (err < 0)
2885 return;
2886 changed |= err;
2887 kfree(sdata->u.ap.next_beacon);
2888 sdata->u.ap.next_beacon = NULL;
2889
2890 ieee80211_bss_info_change_notify(sdata, err);
2891 break;
2892 case NL80211_IFTYPE_ADHOC:
2893 ieee80211_ibss_finish_csa(sdata);
2894 break;
2895 default:
2896 WARN_ON(1);
2897 return;
2898 }
2884 sdata->vif.csa_active = false; 2899 sdata->vif.csa_active = false;
2885 2900
2886 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2901 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2887 IEEE80211_MAX_QUEUE_MAP, 2902 IEEE80211_MAX_QUEUE_MAP,
2888 IEEE80211_QUEUE_STOP_REASON_CSA); 2903 IEEE80211_QUEUE_STOP_REASON_CSA);
2889 2904
2890 ieee80211_bss_info_change_notify(sdata, changed);
2891
2892 cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); 2905 cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef);
2893} 2906}
2894 2907
@@ -2936,20 +2949,56 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
2936 if (sdata->vif.csa_active) 2949 if (sdata->vif.csa_active)
2937 return -EBUSY; 2950 return -EBUSY;
2938 2951
2939 /* only handle AP for now. */
2940 switch (sdata->vif.type) { 2952 switch (sdata->vif.type) {
2941 case NL80211_IFTYPE_AP: 2953 case NL80211_IFTYPE_AP:
2954 sdata->csa_counter_offset_beacon =
2955 params->counter_offset_beacon;
2956 sdata->csa_counter_offset_presp = params->counter_offset_presp;
2957 sdata->u.ap.next_beacon =
2958 cfg80211_beacon_dup(&params->beacon_after);
2959 if (!sdata->u.ap.next_beacon)
2960 return -ENOMEM;
2961
2962 err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
2963 if (err < 0) {
2964 kfree(sdata->u.ap.next_beacon);
2965 return err;
2966 }
2967 break;
2968 case NL80211_IFTYPE_ADHOC:
2969 if (!sdata->vif.bss_conf.ibss_joined)
2970 return -EINVAL;
2971
2972 if (params->chandef.width != sdata->u.ibss.chandef.width)
2973 return -EINVAL;
2974
2975 switch (params->chandef.width) {
2976 case NL80211_CHAN_WIDTH_40:
2977 if (cfg80211_get_chandef_type(&params->chandef) !=
2978 cfg80211_get_chandef_type(&sdata->u.ibss.chandef))
2979 return -EINVAL;
2980 case NL80211_CHAN_WIDTH_5:
2981 case NL80211_CHAN_WIDTH_10:
2982 case NL80211_CHAN_WIDTH_20_NOHT:
2983 case NL80211_CHAN_WIDTH_20:
2984 break;
2985 default:
2986 return -EINVAL;
2987 }
2988
2989 /* changes into another band are not supported */
2990 if (sdata->u.ibss.chandef.chan->band !=
2991 params->chandef.chan->band)
2992 return -EINVAL;
2993
2994 err = ieee80211_ibss_csa_beacon(sdata, params);
2995 if (err < 0)
2996 return err;
2942 break; 2997 break;
2943 default: 2998 default:
2944 return -EOPNOTSUPP; 2999 return -EOPNOTSUPP;
2945 } 3000 }
2946 3001
2947 sdata->u.ap.next_beacon = cfg80211_beacon_dup(&params->beacon_after);
2948 if (!sdata->u.ap.next_beacon)
2949 return -ENOMEM;
2950
2951 sdata->csa_counter_offset_beacon = params->counter_offset_beacon;
2952 sdata->csa_counter_offset_presp = params->counter_offset_presp;
2953 sdata->csa_radar_required = params->radar_required; 3002 sdata->csa_radar_required = params->radar_required;
2954 3003
2955 if (params->block_tx) 3004 if (params->block_tx)
@@ -2957,10 +3006,6 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
2957 IEEE80211_MAX_QUEUE_MAP, 3006 IEEE80211_MAX_QUEUE_MAP,
2958 IEEE80211_QUEUE_STOP_REASON_CSA); 3007 IEEE80211_QUEUE_STOP_REASON_CSA);
2959 3008
2960 err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
2961 if (err < 0)
2962 return err;
2963
2964 local->csa_chandef = params->chandef; 3009 local->csa_chandef = params->chandef;
2965 sdata->vif.csa_active = true; 3010 sdata->vif.csa_active = true;
2966 3011
@@ -3014,7 +3059,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3014 need_offchan = true; 3059 need_offchan = true;
3015 if (!ieee80211_is_action(mgmt->frame_control) || 3060 if (!ieee80211_is_action(mgmt->frame_control) ||
3016 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC || 3061 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
3017 mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED) 3062 mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED ||
3063 mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT)
3018 break; 3064 break;
3019 rcu_read_lock(); 3065 rcu_read_lock();
3020 sta = sta_info_get(sdata, mgmt->da); 3066 sta = sta_info_get(sdata, mgmt->da);
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 3a4764b2869e..03ba6b5c5373 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -453,11 +453,6 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
453 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL; 453 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
454 drv_change_chanctx(local, ctx, chanctx_changed); 454 drv_change_chanctx(local, ctx, chanctx_changed);
455 455
456 if (!local->use_chanctx) {
457 local->_oper_chandef = *chandef;
458 ieee80211_hw_config(local, 0);
459 }
460
461 ieee80211_recalc_chanctx_chantype(local, ctx); 456 ieee80211_recalc_chanctx_chantype(local, ctx);
462 ieee80211_recalc_smps_chanctx(local, ctx); 457 ieee80211_recalc_smps_chanctx(local, ctx);
463 ieee80211_recalc_radar_chanctx(local, ctx); 458 ieee80211_recalc_radar_chanctx(local, ctx);
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index b0e32d628114..5c090e41d9bb 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -103,54 +103,57 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
103 if (!buf) 103 if (!buf)
104 return 0; 104 return 0;
105 105
106 sf += snprintf(buf, mxln - sf, "0x%x\n", local->hw.flags); 106 sf += scnprintf(buf, mxln - sf, "0x%x\n", local->hw.flags);
107 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) 107 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
108 sf += snprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n"); 108 sf += scnprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n");
109 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 109 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
110 sf += snprintf(buf + sf, mxln - sf, "RX_INCLUDES_FCS\n"); 110 sf += scnprintf(buf + sf, mxln - sf, "RX_INCLUDES_FCS\n");
111 if (local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) 111 if (local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)
112 sf += snprintf(buf + sf, mxln - sf, 112 sf += scnprintf(buf + sf, mxln - sf,
113 "HOST_BCAST_PS_BUFFERING\n"); 113 "HOST_BCAST_PS_BUFFERING\n");
114 if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE) 114 if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)
115 sf += snprintf(buf + sf, mxln - sf, 115 sf += scnprintf(buf + sf, mxln - sf,
116 "2GHZ_SHORT_SLOT_INCAPABLE\n"); 116 "2GHZ_SHORT_SLOT_INCAPABLE\n");
117 if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE) 117 if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)
118 sf += snprintf(buf + sf, mxln - sf, 118 sf += scnprintf(buf + sf, mxln - sf,
119 "2GHZ_SHORT_PREAMBLE_INCAPABLE\n"); 119 "2GHZ_SHORT_PREAMBLE_INCAPABLE\n");
120 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 120 if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
121 sf += snprintf(buf + sf, mxln - sf, "SIGNAL_UNSPEC\n"); 121 sf += scnprintf(buf + sf, mxln - sf, "SIGNAL_UNSPEC\n");
122 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 122 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
123 sf += snprintf(buf + sf, mxln - sf, "SIGNAL_DBM\n"); 123 sf += scnprintf(buf + sf, mxln - sf, "SIGNAL_DBM\n");
124 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC) 124 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC)
125 sf += snprintf(buf + sf, mxln - sf, "NEED_DTIM_BEFORE_ASSOC\n"); 125 sf += scnprintf(buf + sf, mxln - sf,
126 "NEED_DTIM_BEFORE_ASSOC\n");
126 if (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT) 127 if (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)
127 sf += snprintf(buf + sf, mxln - sf, "SPECTRUM_MGMT\n"); 128 sf += scnprintf(buf + sf, mxln - sf, "SPECTRUM_MGMT\n");
128 if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) 129 if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)
129 sf += snprintf(buf + sf, mxln - sf, "AMPDU_AGGREGATION\n"); 130 sf += scnprintf(buf + sf, mxln - sf, "AMPDU_AGGREGATION\n");
130 if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS) 131 if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS)
131 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PS\n"); 132 sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_PS\n");
132 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 133 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
133 sf += snprintf(buf + sf, mxln - sf, "PS_NULLFUNC_STACK\n"); 134 sf += scnprintf(buf + sf, mxln - sf, "PS_NULLFUNC_STACK\n");
134 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 135 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
135 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); 136 sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n");
136 if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) 137 if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE)
137 sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); 138 sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n");
138 if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) 139 if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS)
139 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n"); 140 sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n");
140 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) 141 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
141 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_SMPS\n"); 142 sf += scnprintf(buf + sf, mxln - sf,
143 "SUPPORTS_DYNAMIC_SMPS\n");
142 if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) 144 if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
143 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); 145 sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n");
144 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 146 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
145 sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n"); 147 sf += scnprintf(buf + sf, mxln - sf,
148 "REPORTS_TX_ACK_STATUS\n");
146 if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 149 if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
147 sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n"); 150 sf += scnprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n");
148 if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK) 151 if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)
149 sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); 152 sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n");
150 if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) 153 if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
151 sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n"); 154 sf += scnprintf(buf + sf, mxln - sf, "AP_LINK_PS\n");
152 if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW) 155 if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)
153 sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n"); 156 sf += scnprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n");
154 157
155 rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 158 rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
156 kfree(buf); 159 kfree(buf);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index b3ea11f3d526..5d03c47c0a4c 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1085,4 +1085,31 @@ drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1085 } 1085 }
1086} 1086}
1087 1087
1088static inline int drv_join_ibss(struct ieee80211_local *local,
1089 struct ieee80211_sub_if_data *sdata)
1090{
1091 int ret = 0;
1092
1093 might_sleep();
1094 check_sdata_in_driver(sdata);
1095
1096 trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
1097 if (local->ops->join_ibss)
1098 ret = local->ops->join_ibss(&local->hw, &sdata->vif);
1099 trace_drv_return_int(local, ret);
1100 return ret;
1101}
1102
1103static inline void drv_leave_ibss(struct ieee80211_local *local,
1104 struct ieee80211_sub_if_data *sdata)
1105{
1106 might_sleep();
1107 check_sdata_in_driver(sdata);
1108
1109 trace_drv_leave_ibss(local, sdata);
1110 if (local->ops->leave_ibss)
1111 local->ops->leave_ibss(&local->hw, &sdata->vif);
1112 trace_drv_return_void(local);
1113}
1114
1088#endif /* __MAC80211_DRIVER_OPS */ 1115#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a12afe77bb26..21a0b8835cb3 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -39,7 +39,8 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
39 const int beacon_int, const u32 basic_rates, 39 const int beacon_int, const u32 basic_rates,
40 const u16 capability, u64 tsf, 40 const u16 capability, u64 tsf,
41 struct cfg80211_chan_def *chandef, 41 struct cfg80211_chan_def *chandef,
42 bool *have_higher_than_11mbit) 42 bool *have_higher_than_11mbit,
43 struct cfg80211_csa_settings *csa_settings)
43{ 44{
44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 45 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
45 struct ieee80211_local *local = sdata->local; 46 struct ieee80211_local *local = sdata->local;
@@ -59,6 +60,7 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
59 2 + 8 /* max Supported Rates */ + 60 2 + 8 /* max Supported Rates */ +
60 3 /* max DS params */ + 61 3 /* max DS params */ +
61 4 /* IBSS params */ + 62 4 /* IBSS params */ +
63 5 /* Channel Switch Announcement */ +
62 2 + (IEEE80211_MAX_SUPP_RATES - 8) + 64 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
63 2 + sizeof(struct ieee80211_ht_cap) + 65 2 + sizeof(struct ieee80211_ht_cap) +
64 2 + sizeof(struct ieee80211_ht_operation) + 66 2 + sizeof(struct ieee80211_ht_operation) +
@@ -135,6 +137,16 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
135 *pos++ = 0; 137 *pos++ = 0;
136 *pos++ = 0; 138 *pos++ = 0;
137 139
140 if (csa_settings) {
141 *pos++ = WLAN_EID_CHANNEL_SWITCH;
142 *pos++ = 3;
143 *pos++ = csa_settings->block_tx ? 1 : 0;
144 *pos++ = ieee80211_frequency_to_channel(
145 csa_settings->chandef.chan->center_freq);
146 sdata->csa_counter_offset_beacon = (pos - presp->head);
147 *pos++ = csa_settings->count;
148 }
149
138 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */ 150 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
139 if (rates_n > 8) { 151 if (rates_n > 8) {
140 *pos++ = WLAN_EID_EXT_SUPP_RATES; 152 *pos++ = WLAN_EID_EXT_SUPP_RATES;
@@ -217,6 +229,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
217 struct beacon_data *presp; 229 struct beacon_data *presp;
218 enum nl80211_bss_scan_width scan_width; 230 enum nl80211_bss_scan_width scan_width;
219 bool have_higher_than_11mbit; 231 bool have_higher_than_11mbit;
232 int err;
220 233
221 sdata_assert_lock(sdata); 234 sdata_assert_lock(sdata);
222 235
@@ -235,6 +248,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
235 ieee80211_bss_info_change_notify(sdata, 248 ieee80211_bss_info_change_notify(sdata,
236 BSS_CHANGED_IBSS | 249 BSS_CHANGED_IBSS |
237 BSS_CHANGED_BEACON_ENABLED); 250 BSS_CHANGED_BEACON_ENABLED);
251 drv_leave_ibss(local, sdata);
238 } 252 }
239 253
240 presp = rcu_dereference_protected(ifibss->presp, 254 presp = rcu_dereference_protected(ifibss->presp,
@@ -276,7 +290,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
276 290
277 presp = ieee80211_ibss_build_presp(sdata, beacon_int, basic_rates, 291 presp = ieee80211_ibss_build_presp(sdata, beacon_int, basic_rates,
278 capability, tsf, &chandef, 292 capability, tsf, &chandef,
279 &have_higher_than_11mbit); 293 &have_higher_than_11mbit, NULL);
280 if (!presp) 294 if (!presp)
281 return; 295 return;
282 296
@@ -317,11 +331,26 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
317 else 331 else
318 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; 332 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
319 333
334 ieee80211_set_wmm_default(sdata, true);
335
320 sdata->vif.bss_conf.ibss_joined = true; 336 sdata->vif.bss_conf.ibss_joined = true;
321 sdata->vif.bss_conf.ibss_creator = creator; 337 sdata->vif.bss_conf.ibss_creator = creator;
322 ieee80211_bss_info_change_notify(sdata, bss_change);
323 338
324 ieee80211_set_wmm_default(sdata, true); 339 err = drv_join_ibss(local, sdata);
340 if (err) {
341 sdata->vif.bss_conf.ibss_joined = false;
342 sdata->vif.bss_conf.ibss_creator = false;
343 sdata->vif.bss_conf.enable_beacon = false;
344 sdata->vif.bss_conf.ssid_len = 0;
345 RCU_INIT_POINTER(ifibss->presp, NULL);
346 kfree_rcu(presp, rcu_head);
347 ieee80211_vif_release_channel(sdata);
348 sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n",
349 err);
350 return;
351 }
352
353 ieee80211_bss_info_change_notify(sdata, bss_change);
325 354
326 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 355 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
327 mod_timer(&ifibss->timer, 356 mod_timer(&ifibss->timer,
@@ -416,6 +445,169 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
416 tsf, false); 445 tsf, false);
417} 446}
418 447
448static int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
449 struct cfg80211_csa_settings *csa_settings)
450{
451 struct sk_buff *skb;
452 struct ieee80211_mgmt *mgmt;
453 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
454 struct ieee80211_local *local = sdata->local;
455 int freq;
456 int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +
457 sizeof(mgmt->u.action.u.chan_switch);
458 u8 *pos;
459
460 skb = dev_alloc_skb(local->tx_headroom + hdr_len +
461 5 + /* channel switch announcement element */
462 3); /* secondary channel offset element */
463 if (!skb)
464 return -1;
465
466 skb_reserve(skb, local->tx_headroom);
467 mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len);
468 memset(mgmt, 0, hdr_len);
469 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
470 IEEE80211_STYPE_ACTION);
471
472 eth_broadcast_addr(mgmt->da);
473 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
474 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
475 mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
476 mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
477 pos = skb_put(skb, 5);
478 *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
479 *pos++ = 3; /* IE length */
480 *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */
481 freq = csa_settings->chandef.chan->center_freq;
482 *pos++ = ieee80211_frequency_to_channel(freq); /* channel */
483 *pos++ = csa_settings->count; /* count */
484
485 if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
486 enum nl80211_channel_type ch_type;
487
488 skb_put(skb, 3);
489 *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
490 *pos++ = 1; /* IE length */
491 ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
492 if (ch_type == NL80211_CHAN_HT40PLUS)
493 *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
494 else
495 *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
496 }
497
498 ieee80211_tx_skb(sdata, skb);
499 return 0;
500}
501
502int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
503 struct cfg80211_csa_settings *csa_settings)
504{
505 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
506 struct beacon_data *presp, *old_presp;
507 struct cfg80211_bss *cbss;
508 const struct cfg80211_bss_ies *ies;
509 u16 capability;
510 u64 tsf;
511 int ret = 0;
512
513 sdata_assert_lock(sdata);
514
515 capability = WLAN_CAPABILITY_IBSS;
516
517 if (ifibss->privacy)
518 capability |= WLAN_CAPABILITY_PRIVACY;
519
520 cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan,
521 ifibss->bssid, ifibss->ssid,
522 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
523 WLAN_CAPABILITY_PRIVACY,
524 capability);
525
526 if (WARN_ON(!cbss)) {
527 ret = -EINVAL;
528 goto out;
529 }
530
531 rcu_read_lock();
532 ies = rcu_dereference(cbss->ies);
533 tsf = ies->tsf;
534 rcu_read_unlock();
535 cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
536
537 old_presp = rcu_dereference_protected(ifibss->presp,
538 lockdep_is_held(&sdata->wdev.mtx));
539
540 presp = ieee80211_ibss_build_presp(sdata,
541 sdata->vif.bss_conf.beacon_int,
542 sdata->vif.bss_conf.basic_rates,
543 capability, tsf, &ifibss->chandef,
544 NULL, csa_settings);
545 if (!presp) {
546 ret = -ENOMEM;
547 goto out;
548 }
549
550 rcu_assign_pointer(ifibss->presp, presp);
551 if (old_presp)
552 kfree_rcu(old_presp, rcu_head);
553
554 /* it might not send the beacon for a while. send an action frame
555 * immediately to announce the channel switch.
556 */
557 if (csa_settings)
558 ieee80211_send_action_csa(sdata, csa_settings);
559
560 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
561 out:
562 return ret;
563}
564
565int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
566{
567 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
568 struct cfg80211_bss *cbss;
569 int err;
570 u16 capability;
571
572 sdata_lock(sdata);
573 /* update cfg80211 bss information with the new channel */
574 if (!is_zero_ether_addr(ifibss->bssid)) {
575 capability = WLAN_CAPABILITY_IBSS;
576
577 if (ifibss->privacy)
578 capability |= WLAN_CAPABILITY_PRIVACY;
579
580 cbss = cfg80211_get_bss(sdata->local->hw.wiphy,
581 ifibss->chandef.chan,
582 ifibss->bssid, ifibss->ssid,
583 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
584 WLAN_CAPABILITY_PRIVACY,
585 capability);
586 /* XXX: should not really modify cfg80211 data */
587 if (cbss) {
588 cbss->channel = sdata->local->csa_chandef.chan;
589 cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
590 }
591 }
592
593 ifibss->chandef = sdata->local->csa_chandef;
594
595 /* generate the beacon */
596 err = ieee80211_ibss_csa_beacon(sdata, NULL);
597 sdata_unlock(sdata);
598 if (err < 0)
599 return err;
600
601 return 0;
602}
603
604void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata)
605{
606 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
607
608 cancel_work_sync(&ifibss->csa_connection_drop_work);
609}
610
419static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta) 611static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
420 __acquires(RCU) 612 __acquires(RCU)
421{ 613{
@@ -499,6 +691,295 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
499 return ieee80211_ibss_finish_sta(sta); 691 return ieee80211_ibss_finish_sta(sta);
500} 692}
501 693
694static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
695{
696 struct ieee80211_local *local = sdata->local;
697 int active = 0;
698 struct sta_info *sta;
699
700 sdata_assert_lock(sdata);
701
702 rcu_read_lock();
703
704 list_for_each_entry_rcu(sta, &local->sta_list, list) {
705 if (sta->sdata == sdata &&
706 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
707 jiffies)) {
708 active++;
709 break;
710 }
711 }
712
713 rcu_read_unlock();
714
715 return active;
716}
717
718static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
719{
720 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
721 struct ieee80211_local *local = sdata->local;
722 struct cfg80211_bss *cbss;
723 struct beacon_data *presp;
724 struct sta_info *sta;
725 int active_ibss;
726 u16 capability;
727
728 active_ibss = ieee80211_sta_active_ibss(sdata);
729
730 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
731 capability = WLAN_CAPABILITY_IBSS;
732
733 if (ifibss->privacy)
734 capability |= WLAN_CAPABILITY_PRIVACY;
735
736 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
737 ifibss->bssid, ifibss->ssid,
738 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
739 WLAN_CAPABILITY_PRIVACY,
740 capability);
741
742 if (cbss) {
743 cfg80211_unlink_bss(local->hw.wiphy, cbss);
744 cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
745 }
746 }
747
748 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
749
750 sta_info_flush(sdata);
751
752 spin_lock_bh(&ifibss->incomplete_lock);
753 while (!list_empty(&ifibss->incomplete_stations)) {
754 sta = list_first_entry(&ifibss->incomplete_stations,
755 struct sta_info, list);
756 list_del(&sta->list);
757 spin_unlock_bh(&ifibss->incomplete_lock);
758
759 sta_info_free(local, sta);
760 spin_lock_bh(&ifibss->incomplete_lock);
761 }
762 spin_unlock_bh(&ifibss->incomplete_lock);
763
764 netif_carrier_off(sdata->dev);
765
766 sdata->vif.bss_conf.ibss_joined = false;
767 sdata->vif.bss_conf.ibss_creator = false;
768 sdata->vif.bss_conf.enable_beacon = false;
769 sdata->vif.bss_conf.ssid_len = 0;
770
771 /* remove beacon */
772 presp = rcu_dereference_protected(ifibss->presp,
773 lockdep_is_held(&sdata->wdev.mtx));
774 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
775 if (presp)
776 kfree_rcu(presp, rcu_head);
777
778 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
779 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
780 BSS_CHANGED_IBSS);
781 drv_leave_ibss(local, sdata);
782 ieee80211_vif_release_channel(sdata);
783}
784
785static void ieee80211_csa_connection_drop_work(struct work_struct *work)
786{
787 struct ieee80211_sub_if_data *sdata =
788 container_of(work, struct ieee80211_sub_if_data,
789 u.ibss.csa_connection_drop_work);
790
791 ieee80211_ibss_disconnect(sdata);
792 synchronize_rcu();
793 skb_queue_purge(&sdata->skb_queue);
794
795 /* trigger a scan to find another IBSS network to join */
796 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
797}
798
799static bool
800ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
801 struct ieee802_11_elems *elems,
802 bool beacon)
803{
804 struct cfg80211_csa_settings params;
805 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
806 struct ieee80211_chanctx_conf *chanctx_conf;
807 struct ieee80211_chanctx *chanctx;
808 enum nl80211_channel_type ch_type;
809 int err, num_chanctx;
810 u32 sta_flags;
811 u8 mode;
812
813 if (sdata->vif.csa_active)
814 return true;
815
816 if (!sdata->vif.bss_conf.ibss_joined)
817 return false;
818
819 sta_flags = IEEE80211_STA_DISABLE_VHT;
820 switch (ifibss->chandef.width) {
821 case NL80211_CHAN_WIDTH_5:
822 case NL80211_CHAN_WIDTH_10:
823 case NL80211_CHAN_WIDTH_20_NOHT:
824 sta_flags |= IEEE80211_STA_DISABLE_HT;
825 /* fall through */
826 case NL80211_CHAN_WIDTH_20:
827 sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
828 break;
829 default:
830 break;
831 }
832
833 memset(&params, 0, sizeof(params));
834 err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon,
835 ifibss->chandef.chan->band,
836 sta_flags, ifibss->bssid,
837 &params.count, &mode,
838 &params.chandef);
839
840 /* can't switch to destination channel, fail */
841 if (err < 0)
842 goto disconnect;
843
844 /* did not contain a CSA */
845 if (err)
846 return false;
847
848 if (ifibss->chandef.chan->band != params.chandef.chan->band)
849 goto disconnect;
850
851 switch (ifibss->chandef.width) {
852 case NL80211_CHAN_WIDTH_20_NOHT:
853 case NL80211_CHAN_WIDTH_20:
854 case NL80211_CHAN_WIDTH_40:
855 /* keep our current HT mode (HT20/HT40+/HT40-), even if
856 * another mode has been announced. The mode is not adopted
857 * within the beacon while doing CSA and we should therefore
858 * keep the mode which we announce.
859 */
860 ch_type = cfg80211_get_chandef_type(&ifibss->chandef);
861 cfg80211_chandef_create(&params.chandef, params.chandef.chan,
862 ch_type);
863 break;
864 case NL80211_CHAN_WIDTH_5:
865 case NL80211_CHAN_WIDTH_10:
866 if (params.chandef.width != ifibss->chandef.width) {
867 sdata_info(sdata,
868 "IBSS %pM received channel switch from incompatible channel width (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
869 ifibss->bssid,
870 params.chandef.chan->center_freq,
871 params.chandef.width,
872 params.chandef.center_freq1,
873 params.chandef.center_freq2);
874 goto disconnect;
875 }
876 break;
877 default:
878 /* should not happen, sta_flags should prevent VHT modes. */
879 WARN_ON(1);
880 goto disconnect;
881 }
882
883 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, &params.chandef,
884 IEEE80211_CHAN_DISABLED)) {
885 sdata_info(sdata,
886 "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
887 ifibss->bssid,
888 params.chandef.chan->center_freq,
889 params.chandef.width,
890 params.chandef.center_freq1,
891 params.chandef.center_freq2);
892 goto disconnect;
893 }
894
895 err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
896 &params.chandef);
897 if (err < 0)
898 goto disconnect;
899 if (err) {
900 params.radar_required = true;
901
902 /* TODO: IBSS-DFS not (yet) supported, disconnect. */
903 goto disconnect;
904 }
905
906 rcu_read_lock();
907 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
908 if (!chanctx_conf) {
909 rcu_read_unlock();
910 goto disconnect;
911 }
912
913 /* don't handle for multi-VIF cases */
914 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
915 if (chanctx->refcount > 1) {
916 rcu_read_unlock();
917 goto disconnect;
918 }
919 num_chanctx = 0;
920 list_for_each_entry_rcu(chanctx, &sdata->local->chanctx_list, list)
921 num_chanctx++;
922
923 if (num_chanctx > 1) {
924 rcu_read_unlock();
925 goto disconnect;
926 }
927 rcu_read_unlock();
928
929 /* all checks done, now perform the channel switch. */
930 ibss_dbg(sdata,
931 "received channel switch announcement to go to channel %d MHz\n",
932 params.chandef.chan->center_freq);
933
934 params.block_tx = !!mode;
935
936 ieee80211_ibss_csa_beacon(sdata, &params);
937 sdata->csa_radar_required = params.radar_required;
938
939 if (params.block_tx)
940 ieee80211_stop_queues_by_reason(&sdata->local->hw,
941 IEEE80211_MAX_QUEUE_MAP,
942 IEEE80211_QUEUE_STOP_REASON_CSA);
943
944 sdata->local->csa_chandef = params.chandef;
945 sdata->vif.csa_active = true;
946
947 ieee80211_bss_info_change_notify(sdata, err);
948 drv_channel_switch_beacon(sdata, &params.chandef);
949
950 return true;
951disconnect:
952 ibss_dbg(sdata, "Can't handle channel switch, disconnect\n");
953 ieee80211_queue_work(&sdata->local->hw,
954 &ifibss->csa_connection_drop_work);
955
956 return true;
957}
958
959static void
960ieee80211_rx_mgmt_spectrum_mgmt(struct ieee80211_sub_if_data *sdata,
961 struct ieee80211_mgmt *mgmt, size_t len,
962 struct ieee80211_rx_status *rx_status,
963 struct ieee802_11_elems *elems)
964{
965 int required_len;
966
967 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
968 return;
969
970 /* CSA is the only action we handle for now */
971 if (mgmt->u.action.u.measurement.action_code !=
972 WLAN_ACTION_SPCT_CHL_SWITCH)
973 return;
974
975 required_len = IEEE80211_MIN_ACTION_SIZE +
976 sizeof(mgmt->u.action.u.chan_switch);
977 if (len < required_len)
978 return;
979
980 ieee80211_ibss_process_chanswitch(sdata, elems, false);
981}
982
502static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, 983static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
503 struct ieee80211_mgmt *mgmt, 984 struct ieee80211_mgmt *mgmt,
504 size_t len) 985 size_t len)
@@ -661,10 +1142,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
661 1142
662 /* check if we need to merge IBSS */ 1143 /* check if we need to merge IBSS */
663 1144
664 /* we use a fixed BSSID */
665 if (sdata->u.ibss.fixed_bssid)
666 goto put_bss;
667
668 /* not an IBSS */ 1145 /* not an IBSS */
669 if (!(cbss->capability & WLAN_CAPABILITY_IBSS)) 1146 if (!(cbss->capability & WLAN_CAPABILITY_IBSS))
670 goto put_bss; 1147 goto put_bss;
@@ -680,10 +1157,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
680 sdata->u.ibss.ssid_len)) 1157 sdata->u.ibss.ssid_len))
681 goto put_bss; 1158 goto put_bss;
682 1159
1160 /* process channel switch */
1161 if (ieee80211_ibss_process_chanswitch(sdata, elems, true))
1162 goto put_bss;
1163
683 /* same BSSID */ 1164 /* same BSSID */
684 if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) 1165 if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid))
685 goto put_bss; 1166 goto put_bss;
686 1167
1168 /* we use a fixed BSSID */
1169 if (sdata->u.ibss.fixed_bssid)
1170 goto put_bss;
1171
687 if (ieee80211_have_rx_timestamp(rx_status)) { 1172 if (ieee80211_have_rx_timestamp(rx_status)) {
688 /* time when timestamp field was received */ 1173 /* time when timestamp field was received */
689 rx_timestamp = 1174 rx_timestamp =
@@ -775,30 +1260,6 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
775 ieee80211_queue_work(&local->hw, &sdata->work); 1260 ieee80211_queue_work(&local->hw, &sdata->work);
776} 1261}
777 1262
778static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
779{
780 struct ieee80211_local *local = sdata->local;
781 int active = 0;
782 struct sta_info *sta;
783
784 sdata_assert_lock(sdata);
785
786 rcu_read_lock();
787
788 list_for_each_entry_rcu(sta, &local->sta_list, list) {
789 if (sta->sdata == sdata &&
790 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
791 jiffies)) {
792 active++;
793 break;
794 }
795 }
796
797 rcu_read_unlock();
798
799 return active;
800}
801
802static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) 1263static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
803{ 1264{
804 struct ieee80211_local *local = sdata->local; 1265 struct ieee80211_local *local = sdata->local;
@@ -1076,6 +1537,8 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1076 struct ieee80211_rx_status *rx_status; 1537 struct ieee80211_rx_status *rx_status;
1077 struct ieee80211_mgmt *mgmt; 1538 struct ieee80211_mgmt *mgmt;
1078 u16 fc; 1539 u16 fc;
1540 struct ieee802_11_elems elems;
1541 int ies_len;
1079 1542
1080 rx_status = IEEE80211_SKB_RXCB(skb); 1543 rx_status = IEEE80211_SKB_RXCB(skb);
1081 mgmt = (struct ieee80211_mgmt *) skb->data; 1544 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -1101,6 +1564,27 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1101 case IEEE80211_STYPE_DEAUTH: 1564 case IEEE80211_STYPE_DEAUTH:
1102 ieee80211_rx_mgmt_deauth_ibss(sdata, mgmt, skb->len); 1565 ieee80211_rx_mgmt_deauth_ibss(sdata, mgmt, skb->len);
1103 break; 1566 break;
1567 case IEEE80211_STYPE_ACTION:
1568 switch (mgmt->u.action.category) {
1569 case WLAN_CATEGORY_SPECTRUM_MGMT:
1570 ies_len = skb->len -
1571 offsetof(struct ieee80211_mgmt,
1572 u.action.u.chan_switch.variable);
1573
1574 if (ies_len < 0)
1575 break;
1576
1577 ieee802_11_parse_elems(
1578 mgmt->u.action.u.chan_switch.variable,
1579 ies_len, true, &elems);
1580
1581 if (elems.parse_error)
1582 break;
1583
1584 ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
1585 rx_status, &elems);
1586 break;
1587 }
1104 } 1588 }
1105 1589
1106 mgmt_out: 1590 mgmt_out:
@@ -1167,6 +1651,8 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
1167 (unsigned long) sdata); 1651 (unsigned long) sdata);
1168 INIT_LIST_HEAD(&ifibss->incomplete_stations); 1652 INIT_LIST_HEAD(&ifibss->incomplete_stations);
1169 spin_lock_init(&ifibss->incomplete_lock); 1653 spin_lock_init(&ifibss->incomplete_lock);
1654 INIT_WORK(&ifibss->csa_connection_drop_work,
1655 ieee80211_csa_connection_drop_work);
1170} 1656}
1171 1657
1172/* scan finished notification */ 1658/* scan finished notification */
@@ -1265,73 +1751,19 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1265int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) 1751int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1266{ 1752{
1267 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 1753 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
1268 struct ieee80211_local *local = sdata->local;
1269 struct cfg80211_bss *cbss;
1270 u16 capability;
1271 int active_ibss;
1272 struct sta_info *sta;
1273 struct beacon_data *presp;
1274
1275 active_ibss = ieee80211_sta_active_ibss(sdata);
1276
1277 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
1278 capability = WLAN_CAPABILITY_IBSS;
1279
1280 if (ifibss->privacy)
1281 capability |= WLAN_CAPABILITY_PRIVACY;
1282
1283 cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
1284 ifibss->bssid, ifibss->ssid,
1285 ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
1286 WLAN_CAPABILITY_PRIVACY,
1287 capability);
1288 1754
1289 if (cbss) { 1755 ieee80211_ibss_disconnect(sdata);
1290 cfg80211_unlink_bss(local->hw.wiphy, cbss);
1291 cfg80211_put_bss(local->hw.wiphy, cbss);
1292 }
1293 }
1294
1295 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
1296 memset(ifibss->bssid, 0, ETH_ALEN);
1297 ifibss->ssid_len = 0; 1756 ifibss->ssid_len = 0;
1298 1757 memset(ifibss->bssid, 0, ETH_ALEN);
1299 sta_info_flush(sdata);
1300
1301 spin_lock_bh(&ifibss->incomplete_lock);
1302 while (!list_empty(&ifibss->incomplete_stations)) {
1303 sta = list_first_entry(&ifibss->incomplete_stations,
1304 struct sta_info, list);
1305 list_del(&sta->list);
1306 spin_unlock_bh(&ifibss->incomplete_lock);
1307
1308 sta_info_free(local, sta);
1309 spin_lock_bh(&ifibss->incomplete_lock);
1310 }
1311 spin_unlock_bh(&ifibss->incomplete_lock);
1312
1313 netif_carrier_off(sdata->dev);
1314 1758
1315 /* remove beacon */ 1759 /* remove beacon */
1316 kfree(sdata->u.ibss.ie); 1760 kfree(sdata->u.ibss.ie);
1317 presp = rcu_dereference_protected(ifibss->presp,
1318 lockdep_is_held(&sdata->wdev.mtx));
1319 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1320 1761
1321 /* on the next join, re-program HT parameters */ 1762 /* on the next join, re-program HT parameters */
1322 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa)); 1763 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa));
1323 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask)); 1764 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask));
1324 1765
1325 sdata->vif.bss_conf.ibss_joined = false;
1326 sdata->vif.bss_conf.ibss_creator = false;
1327 sdata->vif.bss_conf.enable_beacon = false;
1328 sdata->vif.bss_conf.ssid_len = 0;
1329 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
1330 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
1331 BSS_CHANGED_IBSS);
1332 ieee80211_vif_release_channel(sdata);
1333 synchronize_rcu(); 1766 synchronize_rcu();
1334 kfree(presp);
1335 1767
1336 skb_queue_purge(&sdata->skb_queue); 1768 skb_queue_purge(&sdata->skb_queue);
1337 1769
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b6186517ec56..3a87c8976a32 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -322,7 +322,6 @@ struct ieee80211_roc_work {
322 322
323/* flags used in struct ieee80211_if_managed.flags */ 323/* flags used in struct ieee80211_if_managed.flags */
324enum ieee80211_sta_flags { 324enum ieee80211_sta_flags {
325 IEEE80211_STA_BEACON_POLL = BIT(0),
326 IEEE80211_STA_CONNECTION_POLL = BIT(1), 325 IEEE80211_STA_CONNECTION_POLL = BIT(1),
327 IEEE80211_STA_CONTROL_PORT = BIT(2), 326 IEEE80211_STA_CONTROL_PORT = BIT(2),
328 IEEE80211_STA_DISABLE_HT = BIT(4), 327 IEEE80211_STA_DISABLE_HT = BIT(4),
@@ -487,6 +486,7 @@ struct ieee80211_if_managed {
487 486
488struct ieee80211_if_ibss { 487struct ieee80211_if_ibss {
489 struct timer_list timer; 488 struct timer_list timer;
489 struct work_struct csa_connection_drop_work;
490 490
491 unsigned long last_scan_completed; 491 unsigned long last_scan_completed;
492 492
@@ -1330,6 +1330,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
1330void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata); 1330void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
1331void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1331void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1332 struct sk_buff *skb); 1332 struct sk_buff *skb);
1333int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
1334 struct cfg80211_csa_settings *csa_settings);
1335int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
1336void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
1333 1337
1334/* mesh code */ 1338/* mesh code */
1335void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); 1339void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
@@ -1481,6 +1485,29 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
1481void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, 1485void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1482 struct ieee80211_mgmt *mgmt, 1486 struct ieee80211_mgmt *mgmt,
1483 size_t len); 1487 size_t len);
1488/**
1489 * ieee80211_parse_ch_switch_ie - parses channel switch IEs
1490 * @sdata: the sdata of the interface which has received the frame
1491 * @elems: parsed 802.11 elements received with the frame
1492 * @beacon: indicates if the frame was a beacon or probe response
1493 * @current_band: indicates the current band
1494 * @sta_flags: contains information about own capabilities and restrictions
1495 * to decide which channel switch announcements can be accepted. Only the
1496 * following subset of &enum ieee80211_sta_flags are evaluated:
1497 * %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
1498 * %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
1499 * %IEEE80211_STA_DISABLE_160MHZ.
1500 * @count: to be filled with the counter until the switch (on success only)
1501 * @bssid: the currently connected bssid (for reporting)
1502 * @mode: to be filled with CSA mode (on success only)
1503 * @new_chandef: to be filled with destination chandef (on success only)
1504 * Return: 0 on success, <0 on error and >0 if there is nothing to parse.
1505 */
1506int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
1507 struct ieee802_11_elems *elems, bool beacon,
1508 enum ieee80211_band current_band,
1509 u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
1510 struct cfg80211_chan_def *new_chandef);
1484 1511
1485/* Suspend/resume and hw reconfiguration */ 1512/* Suspend/resume and hw reconfiguration */
1486int ieee80211_reconfig(struct ieee80211_local *local); 1513int ieee80211_reconfig(struct ieee80211_local *local);
@@ -1654,6 +1681,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1654void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, 1681void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
1655 const struct ieee80211_ht_operation *ht_oper, 1682 const struct ieee80211_ht_operation *ht_oper,
1656 struct cfg80211_chan_def *chandef); 1683 struct cfg80211_chan_def *chandef);
1684u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
1657 1685
1658int __must_check 1686int __must_check
1659ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1687ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index fcecd633514e..e48f103b9ade 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -766,6 +766,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
766 if (sdata->vif.type == NL80211_IFTYPE_STATION) 766 if (sdata->vif.type == NL80211_IFTYPE_STATION)
767 ieee80211_mgd_stop(sdata); 767 ieee80211_mgd_stop(sdata);
768 768
769 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
770 ieee80211_ibss_stop(sdata);
771
772
769 /* 773 /*
770 * Remove all stations associated with this interface. 774 * Remove all stations associated with this interface.
771 * 775 *
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 620677e897bd..3e51dd7d98b3 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -879,7 +879,7 @@ ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
879 keyconf->keylen, keyconf->key, 879 keyconf->keylen, keyconf->key,
880 0, NULL); 880 0, NULL);
881 if (IS_ERR(key)) 881 if (IS_ERR(key))
882 return ERR_PTR(PTR_ERR(key)); 882 return ERR_CAST(key);
883 883
884 if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED) 884 if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED)
885 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; 885 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 86e4ad56b573..91cc8281e266 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -145,66 +145,6 @@ static int ecw2cw(int ecw)
145 return (1 << ecw) - 1; 145 return (1 << ecw) - 1;
146} 146}
147 147
148static u32 chandef_downgrade(struct cfg80211_chan_def *c)
149{
150 u32 ret;
151 int tmp;
152
153 switch (c->width) {
154 case NL80211_CHAN_WIDTH_20:
155 c->width = NL80211_CHAN_WIDTH_20_NOHT;
156 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
157 break;
158 case NL80211_CHAN_WIDTH_40:
159 c->width = NL80211_CHAN_WIDTH_20;
160 c->center_freq1 = c->chan->center_freq;
161 ret = IEEE80211_STA_DISABLE_40MHZ |
162 IEEE80211_STA_DISABLE_VHT;
163 break;
164 case NL80211_CHAN_WIDTH_80:
165 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
166 /* n_P40 */
167 tmp /= 2;
168 /* freq_P40 */
169 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
170 c->width = NL80211_CHAN_WIDTH_40;
171 ret = IEEE80211_STA_DISABLE_VHT;
172 break;
173 case NL80211_CHAN_WIDTH_80P80:
174 c->center_freq2 = 0;
175 c->width = NL80211_CHAN_WIDTH_80;
176 ret = IEEE80211_STA_DISABLE_80P80MHZ |
177 IEEE80211_STA_DISABLE_160MHZ;
178 break;
179 case NL80211_CHAN_WIDTH_160:
180 /* n_P20 */
181 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
182 /* n_P80 */
183 tmp /= 4;
184 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
185 c->width = NL80211_CHAN_WIDTH_80;
186 ret = IEEE80211_STA_DISABLE_80P80MHZ |
187 IEEE80211_STA_DISABLE_160MHZ;
188 break;
189 default:
190 case NL80211_CHAN_WIDTH_20_NOHT:
191 WARN_ON_ONCE(1);
192 c->width = NL80211_CHAN_WIDTH_20_NOHT;
193 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
194 break;
195 case NL80211_CHAN_WIDTH_5:
196 case NL80211_CHAN_WIDTH_10:
197 WARN_ON_ONCE(1);
198 /* keep c->width */
199 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
200 break;
201 }
202
203 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
204
205 return ret;
206}
207
208static u32 148static u32
209ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, 149ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
210 struct ieee80211_supported_band *sband, 150 struct ieee80211_supported_band *sband,
@@ -352,7 +292,7 @@ out:
352 break; 292 break;
353 } 293 }
354 294
355 ret |= chandef_downgrade(chandef); 295 ret |= ieee80211_chandef_downgrade(chandef);
356 } 296 }
357 297
358 if (chandef->width != vht_chandef.width && !tracking) 298 if (chandef->width != vht_chandef.width && !tracking)
@@ -406,13 +346,13 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
406 */ 346 */
407 if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ && 347 if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ &&
408 chandef.width == NL80211_CHAN_WIDTH_80P80) 348 chandef.width == NL80211_CHAN_WIDTH_80P80)
409 flags |= chandef_downgrade(&chandef); 349 flags |= ieee80211_chandef_downgrade(&chandef);
410 if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ && 350 if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
411 chandef.width == NL80211_CHAN_WIDTH_160) 351 chandef.width == NL80211_CHAN_WIDTH_160)
412 flags |= chandef_downgrade(&chandef); 352 flags |= ieee80211_chandef_downgrade(&chandef);
413 if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ && 353 if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
414 chandef.width > NL80211_CHAN_WIDTH_20) 354 chandef.width > NL80211_CHAN_WIDTH_20)
415 flags |= chandef_downgrade(&chandef); 355 flags |= ieee80211_chandef_downgrade(&chandef);
416 356
417 if (cfg80211_chandef_identical(&chandef, &sdata->vif.bss_conf.chandef)) 357 if (cfg80211_chandef_identical(&chandef, &sdata->vif.bss_conf.chandef))
418 return 0; 358 return 0;
@@ -893,8 +833,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
893 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 833 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
894 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 834 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
895 835
896 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 836 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
897 IEEE80211_STA_CONNECTION_POLL))
898 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; 837 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
899 838
900 ieee80211_tx_skb(sdata, skb); 839 ieee80211_tx_skb(sdata, skb);
@@ -937,6 +876,8 @@ static void ieee80211_chswitch_work(struct work_struct *work)
937 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); 876 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
938 struct ieee80211_local *local = sdata->local; 877 struct ieee80211_local *local = sdata->local;
939 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 878 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
879 u32 changed = 0;
880 int ret;
940 881
941 if (!ieee80211_sdata_running(sdata)) 882 if (!ieee80211_sdata_running(sdata))
942 return; 883 return;
@@ -945,24 +886,39 @@ static void ieee80211_chswitch_work(struct work_struct *work)
945 if (!ifmgd->associated) 886 if (!ifmgd->associated)
946 goto out; 887 goto out;
947 888
948 local->_oper_chandef = local->csa_chandef; 889 ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
890 &changed);
891 if (ret) {
892 sdata_info(sdata,
893 "vif channel switch failed, disconnecting\n");
894 ieee80211_queue_work(&sdata->local->hw,
895 &ifmgd->csa_connection_drop_work);
896 goto out;
897 }
949 898
950 if (!local->ops->channel_switch) { 899 if (!local->use_chanctx) {
951 /* call "hw_config" only if doing sw channel switch */ 900 local->_oper_chandef = local->csa_chandef;
952 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 901 /* Call "hw_config" only if doing sw channel switch.
953 } else { 902 * Otherwise update the channel directly
954 /* update the device channel directly */ 903 */
955 local->hw.conf.chandef = local->_oper_chandef; 904 if (!local->ops->channel_switch)
905 ieee80211_hw_config(local, 0);
906 else
907 local->hw.conf.chandef = local->_oper_chandef;
956 } 908 }
957 909
958 /* XXX: shouldn't really modify cfg80211-owned data! */ 910 /* XXX: shouldn't really modify cfg80211-owned data! */
959 ifmgd->associated->channel = local->_oper_chandef.chan; 911 ifmgd->associated->channel = local->csa_chandef.chan;
960 912
961 /* XXX: wait for a beacon first? */ 913 /* XXX: wait for a beacon first? */
962 ieee80211_wake_queues_by_reason(&local->hw, 914 ieee80211_wake_queues_by_reason(&local->hw,
963 IEEE80211_MAX_QUEUE_MAP, 915 IEEE80211_MAX_QUEUE_MAP,
964 IEEE80211_QUEUE_STOP_REASON_CSA); 916 IEEE80211_QUEUE_STOP_REASON_CSA);
917
918 ieee80211_bss_info_change_notify(sdata, changed);
919
965 out: 920 out:
921 sdata->vif.csa_active = false;
966 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 922 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
967 sdata_unlock(sdata); 923 sdata_unlock(sdata);
968} 924}
@@ -1000,20 +956,12 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1000 struct ieee80211_local *local = sdata->local; 956 struct ieee80211_local *local = sdata->local;
1001 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 957 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1002 struct cfg80211_bss *cbss = ifmgd->associated; 958 struct cfg80211_bss *cbss = ifmgd->associated;
1003 struct ieee80211_bss *bss;
1004 struct ieee80211_chanctx *chanctx; 959 struct ieee80211_chanctx *chanctx;
1005 enum ieee80211_band new_band; 960 enum ieee80211_band current_band;
1006 int new_freq;
1007 u8 new_chan_no;
1008 u8 count; 961 u8 count;
1009 u8 mode; 962 u8 mode;
1010 struct ieee80211_channel *new_chan;
1011 struct cfg80211_chan_def new_chandef = {}; 963 struct cfg80211_chan_def new_chandef = {};
1012 struct cfg80211_chan_def new_vht_chandef = {}; 964 int res;
1013 const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
1014 const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
1015 const struct ieee80211_ht_operation *ht_oper;
1016 int secondary_channel_offset = -1;
1017 965
1018 sdata_assert_lock(sdata); 966 sdata_assert_lock(sdata);
1019 967
@@ -1027,162 +975,23 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1027 if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED) 975 if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
1028 return; 976 return;
1029 977
1030 sec_chan_offs = elems->sec_chan_offs; 978 current_band = cbss->channel->band;
1031 wide_bw_chansw_ie = elems->wide_bw_chansw_ie; 979 res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band,
1032 ht_oper = elems->ht_operation; 980 ifmgd->flags,
1033 981 ifmgd->associated->bssid, &count,
1034 if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | 982 &mode, &new_chandef);
1035 IEEE80211_STA_DISABLE_40MHZ)) { 983 if (res < 0)
1036 sec_chan_offs = NULL;
1037 wide_bw_chansw_ie = NULL;
1038 /* only used for bandwidth here */
1039 ht_oper = NULL;
1040 }
1041
1042 if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
1043 wide_bw_chansw_ie = NULL;
1044
1045 if (elems->ext_chansw_ie) {
1046 if (!ieee80211_operating_class_to_band(
1047 elems->ext_chansw_ie->new_operating_class,
1048 &new_band)) {
1049 sdata_info(sdata,
1050 "cannot understand ECSA IE operating class %d, disconnecting\n",
1051 elems->ext_chansw_ie->new_operating_class);
1052 ieee80211_queue_work(&local->hw,
1053 &ifmgd->csa_connection_drop_work);
1054 }
1055 new_chan_no = elems->ext_chansw_ie->new_ch_num;
1056 count = elems->ext_chansw_ie->count;
1057 mode = elems->ext_chansw_ie->mode;
1058 } else if (elems->ch_switch_ie) {
1059 new_band = cbss->channel->band;
1060 new_chan_no = elems->ch_switch_ie->new_ch_num;
1061 count = elems->ch_switch_ie->count;
1062 mode = elems->ch_switch_ie->mode;
1063 } else {
1064 /* nothing here we understand */
1065 return;
1066 }
1067
1068 bss = (void *)cbss->priv;
1069
1070 new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
1071 new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
1072 if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) {
1073 sdata_info(sdata,
1074 "AP %pM switches to unsupported channel (%d MHz), disconnecting\n",
1075 ifmgd->associated->bssid, new_freq);
1076 ieee80211_queue_work(&local->hw, 984 ieee80211_queue_work(&local->hw,
1077 &ifmgd->csa_connection_drop_work); 985 &ifmgd->csa_connection_drop_work);
986 if (res)
1078 return; 987 return;
1079 }
1080
1081 if (!beacon && sec_chan_offs) {
1082 secondary_channel_offset = sec_chan_offs->sec_chan_offs;
1083 } else if (beacon && ht_oper) {
1084 secondary_channel_offset =
1085 ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
1086 } else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
1087 /*
1088 * If it's not a beacon, HT is enabled and the IE not present,
1089 * it's 20 MHz, 802.11-2012 8.5.2.6:
1090 * This element [the Secondary Channel Offset Element] is
1091 * present when switching to a 40 MHz channel. It may be
1092 * present when switching to a 20 MHz channel (in which
1093 * case the secondary channel offset is set to SCN).
1094 */
1095 secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
1096 }
1097
1098 switch (secondary_channel_offset) {
1099 default:
1100 /* secondary_channel_offset was present but is invalid */
1101 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
1102 cfg80211_chandef_create(&new_chandef, new_chan,
1103 NL80211_CHAN_HT20);
1104 break;
1105 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
1106 cfg80211_chandef_create(&new_chandef, new_chan,
1107 NL80211_CHAN_HT40PLUS);
1108 break;
1109 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
1110 cfg80211_chandef_create(&new_chandef, new_chan,
1111 NL80211_CHAN_HT40MINUS);
1112 break;
1113 case -1:
1114 cfg80211_chandef_create(&new_chandef, new_chan,
1115 NL80211_CHAN_NO_HT);
1116 /* keep width for 5/10 MHz channels */
1117 switch (sdata->vif.bss_conf.chandef.width) {
1118 case NL80211_CHAN_WIDTH_5:
1119 case NL80211_CHAN_WIDTH_10:
1120 new_chandef.width = sdata->vif.bss_conf.chandef.width;
1121 break;
1122 default:
1123 break;
1124 }
1125 break;
1126 }
1127
1128 if (wide_bw_chansw_ie) {
1129 new_vht_chandef.chan = new_chan;
1130 new_vht_chandef.center_freq1 =
1131 ieee80211_channel_to_frequency(
1132 wide_bw_chansw_ie->new_center_freq_seg0,
1133 new_band);
1134
1135 switch (wide_bw_chansw_ie->new_channel_width) {
1136 default:
1137 /* hmmm, ignore VHT and use HT if present */
1138 case IEEE80211_VHT_CHANWIDTH_USE_HT:
1139 new_vht_chandef.chan = NULL;
1140 break;
1141 case IEEE80211_VHT_CHANWIDTH_80MHZ:
1142 new_vht_chandef.width = NL80211_CHAN_WIDTH_80;
1143 break;
1144 case IEEE80211_VHT_CHANWIDTH_160MHZ:
1145 new_vht_chandef.width = NL80211_CHAN_WIDTH_160;
1146 break;
1147 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
1148 /* field is otherwise reserved */
1149 new_vht_chandef.center_freq2 =
1150 ieee80211_channel_to_frequency(
1151 wide_bw_chansw_ie->new_center_freq_seg1,
1152 new_band);
1153 new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
1154 break;
1155 }
1156 if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ &&
1157 new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
1158 chandef_downgrade(&new_vht_chandef);
1159 if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
1160 new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
1161 chandef_downgrade(&new_vht_chandef);
1162 if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
1163 new_vht_chandef.width > NL80211_CHAN_WIDTH_20)
1164 chandef_downgrade(&new_vht_chandef);
1165 }
1166
1167 /* if VHT data is there validate & use it */
1168 if (new_vht_chandef.chan) {
1169 if (!cfg80211_chandef_compatible(&new_vht_chandef,
1170 &new_chandef)) {
1171 sdata_info(sdata,
1172 "AP %pM CSA has inconsistent channel data, disconnecting\n",
1173 ifmgd->associated->bssid);
1174 ieee80211_queue_work(&local->hw,
1175 &ifmgd->csa_connection_drop_work);
1176 return;
1177 }
1178 new_chandef = new_vht_chandef;
1179 }
1180 988
1181 if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef, 989 if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef,
1182 IEEE80211_CHAN_DISABLED)) { 990 IEEE80211_CHAN_DISABLED)) {
1183 sdata_info(sdata, 991 sdata_info(sdata,
1184 "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", 992 "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
1185 ifmgd->associated->bssid, new_freq, 993 ifmgd->associated->bssid,
994 new_chandef.chan->center_freq,
1186 new_chandef.width, new_chandef.center_freq1, 995 new_chandef.width, new_chandef.center_freq1,
1187 new_chandef.center_freq2); 996 new_chandef.center_freq2);
1188 ieee80211_queue_work(&local->hw, 997 ieee80211_queue_work(&local->hw,
@@ -1191,17 +1000,28 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1191 } 1000 }
1192 1001
1193 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; 1002 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
1003 sdata->vif.csa_active = true;
1194 1004
1005 mutex_lock(&local->chanctx_mtx);
1195 if (local->use_chanctx) { 1006 if (local->use_chanctx) {
1196 sdata_info(sdata, 1007 u32 num_chanctx = 0;
1197 "not handling channel switch with channel contexts\n"); 1008 list_for_each_entry(chanctx, &local->chanctx_list, list)
1198 ieee80211_queue_work(&local->hw, 1009 num_chanctx++;
1199 &ifmgd->csa_connection_drop_work); 1010
1200 return; 1011 if (num_chanctx > 1 ||
1012 !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
1013 sdata_info(sdata,
1014 "not handling chan-switch with channel contexts\n");
1015 ieee80211_queue_work(&local->hw,
1016 &ifmgd->csa_connection_drop_work);
1017 mutex_unlock(&local->chanctx_mtx);
1018 return;
1019 }
1201 } 1020 }
1202 1021
1203 mutex_lock(&local->chanctx_mtx);
1204 if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { 1022 if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) {
1023 ieee80211_queue_work(&local->hw,
1024 &ifmgd->csa_connection_drop_work);
1205 mutex_unlock(&local->chanctx_mtx); 1025 mutex_unlock(&local->chanctx_mtx);
1206 return; 1026 return;
1207 } 1027 }
@@ -1374,8 +1194,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
1374 if (!mgd->associated) 1194 if (!mgd->associated)
1375 return false; 1195 return false;
1376 1196
1377 if (mgd->flags & (IEEE80211_STA_BEACON_POLL | 1197 if (mgd->flags & IEEE80211_STA_CONNECTION_POLL)
1378 IEEE80211_STA_CONNECTION_POLL))
1379 return false; 1198 return false;
1380 1199
1381 if (!mgd->have_beacon) 1200 if (!mgd->have_beacon)
@@ -1691,8 +1510,7 @@ static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
1691{ 1510{
1692 lockdep_assert_held(&sdata->local->mtx); 1511 lockdep_assert_held(&sdata->local->mtx);
1693 1512
1694 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1513 sdata->u.mgd.flags &= ~IEEE80211_STA_CONNECTION_POLL;
1695 IEEE80211_STA_BEACON_POLL);
1696 ieee80211_run_deferred_scan(sdata->local); 1514 ieee80211_run_deferred_scan(sdata->local);
1697} 1515}
1698 1516
@@ -1954,11 +1772,8 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
1954 struct ieee80211_local *local = sdata->local; 1772 struct ieee80211_local *local = sdata->local;
1955 1773
1956 mutex_lock(&local->mtx); 1774 mutex_lock(&local->mtx);
1957 if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 1775 if (!(ifmgd->flags & IEEE80211_STA_CONNECTION_POLL))
1958 IEEE80211_STA_CONNECTION_POLL))) { 1776 goto out;
1959 mutex_unlock(&local->mtx);
1960 return;
1961 }
1962 1777
1963 __ieee80211_stop_poll(sdata); 1778 __ieee80211_stop_poll(sdata);
1964 1779
@@ -2094,15 +1909,9 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2094 * because otherwise we would reset the timer every time and 1909 * because otherwise we would reset the timer every time and
2095 * never check whether we received a probe response! 1910 * never check whether we received a probe response!
2096 */ 1911 */
2097 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 1912 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
2098 IEEE80211_STA_CONNECTION_POLL))
2099 already = true; 1913 already = true;
2100 1914
2101 if (beacon)
2102 ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
2103 else
2104 ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
2105
2106 mutex_unlock(&sdata->local->mtx); 1915 mutex_unlock(&sdata->local->mtx);
2107 1916
2108 if (already) 1917 if (already)
@@ -2174,6 +1983,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2174 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 1983 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2175 true, frame_buf); 1984 true, frame_buf);
2176 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 1985 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
1986 sdata->vif.csa_active = false;
2177 ieee80211_wake_queues_by_reason(&sdata->local->hw, 1987 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2178 IEEE80211_MAX_QUEUE_MAP, 1988 IEEE80211_MAX_QUEUE_MAP,
2179 IEEE80211_QUEUE_STOP_REASON_CSA); 1989 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -3061,17 +2871,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3061 } 2871 }
3062 } 2872 }
3063 2873
3064 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 2874 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
3065 mlme_dbg_ratelimited(sdata, 2875 mlme_dbg_ratelimited(sdata,
3066 "cancelling AP probe due to a received beacon\n"); 2876 "cancelling AP probe due to a received beacon\n");
3067 mutex_lock(&local->mtx); 2877 ieee80211_reset_ap_probe(sdata);
3068 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
3069 ieee80211_run_deferred_scan(local);
3070 mutex_unlock(&local->mtx);
3071
3072 mutex_lock(&local->iflist_mtx);
3073 ieee80211_recalc_ps(local, -1);
3074 mutex_unlock(&local->iflist_mtx);
3075 } 2878 }
3076 2879
3077 /* 2880 /*
@@ -3543,8 +3346,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3543 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3346 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3544 run_again(sdata, ifmgd->assoc_data->timeout); 3347 run_again(sdata, ifmgd->assoc_data->timeout);
3545 3348
3546 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 3349 if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL &&
3547 IEEE80211_STA_CONNECTION_POLL) &&
3548 ifmgd->associated) { 3350 ifmgd->associated) {
3549 u8 bssid[ETH_ALEN]; 3351 u8 bssid[ETH_ALEN];
3550 int max_tries; 3352 int max_tries;
@@ -3876,7 +3678,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3876 return ret; 3678 return ret;
3877 3679
3878 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) { 3680 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
3879 ifmgd->flags |= chandef_downgrade(&chandef); 3681 ifmgd->flags |= ieee80211_chandef_downgrade(&chandef);
3880 ret = ieee80211_vif_use_channel(sdata, &chandef, 3682 ret = ieee80211_vif_use_channel(sdata, &chandef,
3881 IEEE80211_CHANCTX_SHARED); 3683 IEEE80211_CHANCTX_SHARED);
3882 } 3684 }
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 8b5f7ef7c0c9..7fa1b36e6202 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -203,6 +203,15 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
203 memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate)); 203 memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate));
204 mi->max_prob_rate = tmp_prob_rate; 204 mi->max_prob_rate = tmp_prob_rate;
205 205
206#ifdef CONFIG_MAC80211_DEBUGFS
207 /* use fixed index if set */
208 if (mp->fixed_rate_idx != -1) {
209 mi->max_tp_rate[0] = mp->fixed_rate_idx;
210 mi->max_tp_rate[1] = mp->fixed_rate_idx;
211 mi->max_prob_rate = mp->fixed_rate_idx;
212 }
213#endif
214
206 /* Reset update timer */ 215 /* Reset update timer */
207 mi->stats_update = jiffies; 216 mi->stats_update = jiffies;
208 217
@@ -310,6 +319,11 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
310 /* increase sum packet counter */ 319 /* increase sum packet counter */
311 mi->packet_count++; 320 mi->packet_count++;
312 321
322#ifdef CONFIG_MAC80211_DEBUGFS
323 if (mp->fixed_rate_idx != -1)
324 return;
325#endif
326
313 delta = (mi->packet_count * sampling_ratio / 100) - 327 delta = (mi->packet_count * sampling_ratio / 100) -
314 (mi->sample_count + mi->sample_deferred / 2); 328 (mi->sample_count + mi->sample_deferred / 2);
315 329
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 7c323f27ba23..5d60779a0c1b 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -365,6 +365,14 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
365 } 365 }
366 } 366 }
367 367
368#ifdef CONFIG_MAC80211_DEBUGFS
369 /* use fixed index if set */
370 if (mp->fixed_rate_idx != -1) {
371 mi->max_tp_rate = mp->fixed_rate_idx;
372 mi->max_tp_rate2 = mp->fixed_rate_idx;
373 mi->max_prob_rate = mp->fixed_rate_idx;
374 }
375#endif
368 376
369 mi->stats_update = jiffies; 377 mi->stats_update = jiffies;
370} 378}
@@ -774,6 +782,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
774 info->flags |= mi->tx_flags; 782 info->flags |= mi->tx_flags;
775 minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble); 783 minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);
776 784
785#ifdef CONFIG_MAC80211_DEBUGFS
786 if (mp->fixed_rate_idx != -1)
787 return;
788#endif
789
777 /* Don't use EAPOL frames for sampling on non-mrr hw */ 790 /* Don't use EAPOL frames for sampling on non-mrr hw */
778 if (mp->hw->max_rates == 1 && 791 if (mp->hw->max_rates == 1 &&
779 (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) 792 (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
@@ -781,16 +794,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
781 else 794 else
782 sample_idx = minstrel_get_sample_rate(mp, mi); 795 sample_idx = minstrel_get_sample_rate(mp, mi);
783 796
784#ifdef CONFIG_MAC80211_DEBUGFS
785 /* use fixed index if set */
786 if (mp->fixed_rate_idx != -1) {
787 mi->max_tp_rate = mp->fixed_rate_idx;
788 mi->max_tp_rate2 = mp->fixed_rate_idx;
789 mi->max_prob_rate = mp->fixed_rate_idx;
790 sample_idx = -1;
791 }
792#endif
793
794 mi->total_packets++; 797 mi->total_packets++;
795 798
796 /* wraparound */ 799 /* wraparound */
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index c97a0657c043..6ff134650a84 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -167,29 +167,29 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
167 * provide large enough buffers. */ 167 * provide large enough buffers. */
168 length = length < RC_PID_PRINT_BUF_SIZE ? 168 length = length < RC_PID_PRINT_BUF_SIZE ?
169 length : RC_PID_PRINT_BUF_SIZE; 169 length : RC_PID_PRINT_BUF_SIZE;
170 p = snprintf(pb, length, "%u %lu ", ev->id, ev->timestamp); 170 p = scnprintf(pb, length, "%u %lu ", ev->id, ev->timestamp);
171 switch (ev->type) { 171 switch (ev->type) {
172 case RC_PID_EVENT_TYPE_TX_STATUS: 172 case RC_PID_EVENT_TYPE_TX_STATUS:
173 p += snprintf(pb + p, length - p, "tx_status %u %u", 173 p += scnprintf(pb + p, length - p, "tx_status %u %u",
174 !(ev->data.flags & IEEE80211_TX_STAT_ACK), 174 !(ev->data.flags & IEEE80211_TX_STAT_ACK),
175 ev->data.tx_status.status.rates[0].idx); 175 ev->data.tx_status.status.rates[0].idx);
176 break; 176 break;
177 case RC_PID_EVENT_TYPE_RATE_CHANGE: 177 case RC_PID_EVENT_TYPE_RATE_CHANGE:
178 p += snprintf(pb + p, length - p, "rate_change %d %d", 178 p += scnprintf(pb + p, length - p, "rate_change %d %d",
179 ev->data.index, ev->data.rate); 179 ev->data.index, ev->data.rate);
180 break; 180 break;
181 case RC_PID_EVENT_TYPE_TX_RATE: 181 case RC_PID_EVENT_TYPE_TX_RATE:
182 p += snprintf(pb + p, length - p, "tx_rate %d %d", 182 p += scnprintf(pb + p, length - p, "tx_rate %d %d",
183 ev->data.index, ev->data.rate); 183 ev->data.index, ev->data.rate);
184 break; 184 break;
185 case RC_PID_EVENT_TYPE_PF_SAMPLE: 185 case RC_PID_EVENT_TYPE_PF_SAMPLE:
186 p += snprintf(pb + p, length - p, 186 p += scnprintf(pb + p, length - p,
187 "pf_sample %d %d %d %d", 187 "pf_sample %d %d %d %d",
188 ev->data.pf_sample, ev->data.prop_err, 188 ev->data.pf_sample, ev->data.prop_err,
189 ev->data.int_err, ev->data.der_err); 189 ev->data.int_err, ev->data.der_err);
190 break; 190 break;
191 } 191 }
192 p += snprintf(pb + p, length - p, "\n"); 192 p += scnprintf(pb + p, length - p, "\n");
193 193
194 spin_unlock_irqrestore(&events->lock, status); 194 spin_unlock_irqrestore(&events->lock, status);
195 195
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 674eac1f996c..0011ac815097 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -995,8 +995,9 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
995 rx->sta->num_duplicates++; 995 rx->sta->num_duplicates++;
996 } 996 }
997 return RX_DROP_UNUSABLE; 997 return RX_DROP_UNUSABLE;
998 } else 998 } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) {
999 rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; 999 rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl;
1000 }
1000 } 1001 }
1001 1002
1002 if (unlikely(rx->skb->len < 16)) { 1003 if (unlikely(rx->skb->len < 16)) {
@@ -2402,7 +2403,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2402 return RX_DROP_UNUSABLE; 2403 return RX_DROP_UNUSABLE;
2403 2404
2404 if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && 2405 if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
2405 mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED) 2406 mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED &&
2407 mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)
2406 return RX_DROP_UNUSABLE; 2408 return RX_DROP_UNUSABLE;
2407 2409
2408 if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) 2410 if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
@@ -2566,31 +2568,46 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2566 2568
2567 goto queue; 2569 goto queue;
2568 case WLAN_CATEGORY_SPECTRUM_MGMT: 2570 case WLAN_CATEGORY_SPECTRUM_MGMT:
2569 if (status->band != IEEE80211_BAND_5GHZ)
2570 break;
2571
2572 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2573 break;
2574
2575 /* verify action_code is present */ 2571 /* verify action_code is present */
2576 if (len < IEEE80211_MIN_ACTION_SIZE + 1) 2572 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2577 break; 2573 break;
2578 2574
2579 switch (mgmt->u.action.u.measurement.action_code) { 2575 switch (mgmt->u.action.u.measurement.action_code) {
2580 case WLAN_ACTION_SPCT_MSR_REQ: 2576 case WLAN_ACTION_SPCT_MSR_REQ:
2577 if (status->band != IEEE80211_BAND_5GHZ)
2578 break;
2579
2581 if (len < (IEEE80211_MIN_ACTION_SIZE + 2580 if (len < (IEEE80211_MIN_ACTION_SIZE +
2582 sizeof(mgmt->u.action.u.measurement))) 2581 sizeof(mgmt->u.action.u.measurement)))
2583 break; 2582 break;
2583
2584 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2585 break;
2586
2584 ieee80211_process_measurement_req(sdata, mgmt, len); 2587 ieee80211_process_measurement_req(sdata, mgmt, len);
2585 goto handled; 2588 goto handled;
2586 case WLAN_ACTION_SPCT_CHL_SWITCH: 2589 case WLAN_ACTION_SPCT_CHL_SWITCH: {
2587 if (sdata->vif.type != NL80211_IFTYPE_STATION) 2590 u8 *bssid;
2591 if (len < (IEEE80211_MIN_ACTION_SIZE +
2592 sizeof(mgmt->u.action.u.chan_switch)))
2593 break;
2594
2595 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
2596 sdata->vif.type != NL80211_IFTYPE_ADHOC)
2588 break; 2597 break;
2589 2598
2590 if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid)) 2599 if (sdata->vif.type == NL80211_IFTYPE_STATION)
2600 bssid = sdata->u.mgd.bssid;
2601 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
2602 bssid = sdata->u.ibss.bssid;
2603 else
2604 break;
2605
2606 if (!ether_addr_equal(mgmt->bssid, bssid))
2591 break; 2607 break;
2592 2608
2593 goto queue; 2609 goto queue;
2610 }
2594 } 2611 }
2595 break; 2612 break;
2596 case WLAN_CATEGORY_SA_QUERY: 2613 case WLAN_CATEGORY_SA_QUERY:
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 08afe74b98f4..ecb57b0bf74a 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -391,8 +391,7 @@ static bool ieee80211_can_scan(struct ieee80211_local *local,
391 return false; 391 return false;
392 392
393 if (sdata->vif.type == NL80211_IFTYPE_STATION && 393 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
394 sdata->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 394 sdata->u.mgd.flags & IEEE80211_STA_CONNECTION_POLL)
395 IEEE80211_STA_CONNECTION_POLL))
396 return false; 395 return false;
397 396
398 return true; 397 return true;
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 578eea3fc04d..921597e279a3 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -21,6 +21,168 @@
21#include "sta_info.h" 21#include "sta_info.h"
22#include "wme.h" 22#include "wme.h"
23 23
24int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
25 struct ieee802_11_elems *elems, bool beacon,
26 enum ieee80211_band current_band,
27 u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
28 struct cfg80211_chan_def *new_chandef)
29{
30 enum ieee80211_band new_band;
31 int new_freq;
32 u8 new_chan_no;
33 struct ieee80211_channel *new_chan;
34 struct cfg80211_chan_def new_vht_chandef = {};
35 const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
36 const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
37 const struct ieee80211_ht_operation *ht_oper;
38 int secondary_channel_offset = -1;
39
40 sec_chan_offs = elems->sec_chan_offs;
41 wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
42 ht_oper = elems->ht_operation;
43
44 if (sta_flags & (IEEE80211_STA_DISABLE_HT |
45 IEEE80211_STA_DISABLE_40MHZ)) {
46 sec_chan_offs = NULL;
47 wide_bw_chansw_ie = NULL;
48 /* only used for bandwidth here */
49 ht_oper = NULL;
50 }
51
52 if (sta_flags & IEEE80211_STA_DISABLE_VHT)
53 wide_bw_chansw_ie = NULL;
54
55 if (elems->ext_chansw_ie) {
56 if (!ieee80211_operating_class_to_band(
57 elems->ext_chansw_ie->new_operating_class,
58 &new_band)) {
59 sdata_info(sdata,
60 "cannot understand ECSA IE operating class %d, disconnecting\n",
61 elems->ext_chansw_ie->new_operating_class);
62 return -EINVAL;
63 }
64 new_chan_no = elems->ext_chansw_ie->new_ch_num;
65 *count = elems->ext_chansw_ie->count;
66 *mode = elems->ext_chansw_ie->mode;
67 } else if (elems->ch_switch_ie) {
68 new_band = current_band;
69 new_chan_no = elems->ch_switch_ie->new_ch_num;
70 *count = elems->ch_switch_ie->count;
71 *mode = elems->ch_switch_ie->mode;
72 } else {
73 /* nothing here we understand */
74 return 1;
75 }
76
77 new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
78 new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
79 if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) {
80 sdata_info(sdata,
81 "BSS %pM switches to unsupported channel (%d MHz), disconnecting\n",
82 bssid, new_freq);
83 return -EINVAL;
84 }
85
86 if (!beacon && sec_chan_offs) {
87 secondary_channel_offset = sec_chan_offs->sec_chan_offs;
88 } else if (beacon && ht_oper) {
89 secondary_channel_offset =
90 ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
91 } else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) {
92 /* If it's not a beacon, HT is enabled and the IE not present,
93 * it's 20 MHz, 802.11-2012 8.5.2.6:
94 * This element [the Secondary Channel Offset Element] is
95 * present when switching to a 40 MHz channel. It may be
96 * present when switching to a 20 MHz channel (in which
97 * case the secondary channel offset is set to SCN).
98 */
99 secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
100 }
101
102 switch (secondary_channel_offset) {
103 default:
104 /* secondary_channel_offset was present but is invalid */
105 case IEEE80211_HT_PARAM_CHA_SEC_NONE:
106 cfg80211_chandef_create(new_chandef, new_chan,
107 NL80211_CHAN_HT20);
108 break;
109 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
110 cfg80211_chandef_create(new_chandef, new_chan,
111 NL80211_CHAN_HT40PLUS);
112 break;
113 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
114 cfg80211_chandef_create(new_chandef, new_chan,
115 NL80211_CHAN_HT40MINUS);
116 break;
117 case -1:
118 cfg80211_chandef_create(new_chandef, new_chan,
119 NL80211_CHAN_NO_HT);
120 /* keep width for 5/10 MHz channels */
121 switch (sdata->vif.bss_conf.chandef.width) {
122 case NL80211_CHAN_WIDTH_5:
123 case NL80211_CHAN_WIDTH_10:
124 new_chandef->width = sdata->vif.bss_conf.chandef.width;
125 break;
126 default:
127 break;
128 }
129 break;
130 }
131
132 if (wide_bw_chansw_ie) {
133 new_vht_chandef.chan = new_chan;
134 new_vht_chandef.center_freq1 =
135 ieee80211_channel_to_frequency(
136 wide_bw_chansw_ie->new_center_freq_seg0,
137 new_band);
138
139 switch (wide_bw_chansw_ie->new_channel_width) {
140 default:
141 /* hmmm, ignore VHT and use HT if present */
142 case IEEE80211_VHT_CHANWIDTH_USE_HT:
143 new_vht_chandef.chan = NULL;
144 break;
145 case IEEE80211_VHT_CHANWIDTH_80MHZ:
146 new_vht_chandef.width = NL80211_CHAN_WIDTH_80;
147 break;
148 case IEEE80211_VHT_CHANWIDTH_160MHZ:
149 new_vht_chandef.width = NL80211_CHAN_WIDTH_160;
150 break;
151 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
152 /* field is otherwise reserved */
153 new_vht_chandef.center_freq2 =
154 ieee80211_channel_to_frequency(
155 wide_bw_chansw_ie->new_center_freq_seg1,
156 new_band);
157 new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
158 break;
159 }
160 if (sta_flags & IEEE80211_STA_DISABLE_80P80MHZ &&
161 new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
162 ieee80211_chandef_downgrade(&new_vht_chandef);
163 if (sta_flags & IEEE80211_STA_DISABLE_160MHZ &&
164 new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
165 ieee80211_chandef_downgrade(&new_vht_chandef);
166 if (sta_flags & IEEE80211_STA_DISABLE_40MHZ &&
167 new_vht_chandef.width > NL80211_CHAN_WIDTH_20)
168 ieee80211_chandef_downgrade(&new_vht_chandef);
169 }
170
171 /* if VHT data is there validate & use it */
172 if (new_vht_chandef.chan) {
173 if (!cfg80211_chandef_compatible(&new_vht_chandef,
174 new_chandef)) {
175 sdata_info(sdata,
176 "BSS %pM: CSA has inconsistent channel data, disconnecting\n",
177 bssid);
178 return -EINVAL;
179 }
180 *new_chandef = new_vht_chandef;
181 }
182
183 return 0;
184}
185
24static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata, 186static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
25 struct ieee80211_msrment_ie *request_ie, 187 struct ieee80211_msrment_ie *request_ie,
26 const u8 *da, const u8 *bssid, 188 const u8 *da, const u8 *bssid,
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 3fb9dd6d02fc..d4cee98533fd 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1475,6 +1475,41 @@ DEFINE_EVENT(local_sdata_evt, drv_ipv6_addr_change,
1475); 1475);
1476#endif 1476#endif
1477 1477
1478TRACE_EVENT(drv_join_ibss,
1479 TP_PROTO(struct ieee80211_local *local,
1480 struct ieee80211_sub_if_data *sdata,
1481 struct ieee80211_bss_conf *info),
1482
1483 TP_ARGS(local, sdata, info),
1484
1485 TP_STRUCT__entry(
1486 LOCAL_ENTRY
1487 VIF_ENTRY
1488 __field(u8, dtimper)
1489 __field(u16, bcnint)
1490 __dynamic_array(u8, ssid, info->ssid_len);
1491 ),
1492
1493 TP_fast_assign(
1494 LOCAL_ASSIGN;
1495 VIF_ASSIGN;
1496 __entry->dtimper = info->dtim_period;
1497 __entry->bcnint = info->beacon_int;
1498 memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
1499 ),
1500
1501 TP_printk(
1502 LOCAL_PR_FMT VIF_PR_FMT,
1503 LOCAL_PR_ARG, VIF_PR_ARG
1504 )
1505);
1506
1507DEFINE_EVENT(local_sdata_evt, drv_leave_ibss,
1508 TP_PROTO(struct ieee80211_local *local,
1509 struct ieee80211_sub_if_data *sdata),
1510 TP_ARGS(local, sdata)
1511);
1512
1478/* 1513/*
1479 * Tracing for API calls that drivers call. 1514 * Tracing for API calls that drivers call.
1480 */ 1515 */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3456c0486b48..4fcbf634b548 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1981,7 +1981,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1981 * EAPOL frames from the local station. 1981 * EAPOL frames from the local station.
1982 */ 1982 */
1983 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && 1983 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
1984 !is_multicast_ether_addr(hdr.addr1) && !authorized && 1984 !multicast && !authorized &&
1985 (cpu_to_be16(ethertype) != sdata->control_port_protocol || 1985 (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
1986 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { 1986 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
1987#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1987#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -2357,15 +2357,31 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata,
2357 struct probe_resp *resp; 2357 struct probe_resp *resp;
2358 int counter_offset_beacon = sdata->csa_counter_offset_beacon; 2358 int counter_offset_beacon = sdata->csa_counter_offset_beacon;
2359 int counter_offset_presp = sdata->csa_counter_offset_presp; 2359 int counter_offset_presp = sdata->csa_counter_offset_presp;
2360 u8 *beacon_data;
2361 size_t beacon_data_len;
2362
2363 switch (sdata->vif.type) {
2364 case NL80211_IFTYPE_AP:
2365 beacon_data = beacon->tail;
2366 beacon_data_len = beacon->tail_len;
2367 break;
2368 case NL80211_IFTYPE_ADHOC:
2369 beacon_data = beacon->head;
2370 beacon_data_len = beacon->head_len;
2371 break;
2372 default:
2373 return;
2374 }
2375 if (WARN_ON(counter_offset_beacon >= beacon_data_len))
2376 return;
2360 2377
2361 /* warn if the driver did not check for/react to csa completeness */ 2378 /* warn if the driver did not check for/react to csa completeness */
2362 if (WARN_ON(((u8 *)beacon->tail)[counter_offset_beacon] == 0)) 2379 if (WARN_ON(beacon_data[counter_offset_beacon] == 0))
2363 return; 2380 return;
2364 2381
2365 ((u8 *)beacon->tail)[counter_offset_beacon]--; 2382 beacon_data[counter_offset_beacon]--;
2366 2383
2367 if (sdata->vif.type == NL80211_IFTYPE_AP && 2384 if (sdata->vif.type == NL80211_IFTYPE_AP && counter_offset_presp) {
2368 counter_offset_presp) {
2369 rcu_read_lock(); 2385 rcu_read_lock();
2370 resp = rcu_dereference(sdata->u.ap.probe_resp); 2386 resp = rcu_dereference(sdata->u.ap.probe_resp);
2371 2387
@@ -2400,6 +2416,15 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
2400 goto out; 2416 goto out;
2401 beacon_data = beacon->tail; 2417 beacon_data = beacon->tail;
2402 beacon_data_len = beacon->tail_len; 2418 beacon_data_len = beacon->tail_len;
2419 } else if (vif->type == NL80211_IFTYPE_ADHOC) {
2420 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2421
2422 beacon = rcu_dereference(ifibss->presp);
2423 if (!beacon)
2424 goto out;
2425
2426 beacon_data = beacon->head;
2427 beacon_data_len = beacon->head_len;
2403 } else { 2428 } else {
2404 WARN_ON(1); 2429 WARN_ON(1);
2405 goto out; 2430 goto out;
@@ -2484,6 +2509,10 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2484 if (!presp) 2509 if (!presp)
2485 goto out; 2510 goto out;
2486 2511
2512 if (sdata->vif.csa_active)
2513 ieee80211_update_csa(sdata, presp);
2514
2515
2487 skb = dev_alloc_skb(local->tx_headroom + presp->head_len); 2516 skb = dev_alloc_skb(local->tx_headroom + presp->head_len);
2488 if (!skb) 2517 if (!skb)
2489 goto out; 2518 goto out;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9c3200bcfc02..1220f5afdb7e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -567,18 +567,15 @@ void ieee80211_flush_queues(struct ieee80211_local *local,
567 IEEE80211_QUEUE_STOP_REASON_FLUSH); 567 IEEE80211_QUEUE_STOP_REASON_FLUSH);
568} 568}
569 569
570void ieee80211_iterate_active_interfaces( 570static void __iterate_active_interfaces(struct ieee80211_local *local,
571 struct ieee80211_hw *hw, u32 iter_flags, 571 u32 iter_flags,
572 void (*iterator)(void *data, u8 *mac, 572 void (*iterator)(void *data, u8 *mac,
573 struct ieee80211_vif *vif), 573 struct ieee80211_vif *vif),
574 void *data) 574 void *data)
575{ 575{
576 struct ieee80211_local *local = hw_to_local(hw);
577 struct ieee80211_sub_if_data *sdata; 576 struct ieee80211_sub_if_data *sdata;
578 577
579 mutex_lock(&local->iflist_mtx); 578 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
580
581 list_for_each_entry(sdata, &local->interfaces, list) {
582 switch (sdata->vif.type) { 579 switch (sdata->vif.type) {
583 case NL80211_IFTYPE_MONITOR: 580 case NL80211_IFTYPE_MONITOR:
584 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 581 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
@@ -597,13 +594,25 @@ void ieee80211_iterate_active_interfaces(
597 &sdata->vif); 594 &sdata->vif);
598 } 595 }
599 596
600 sdata = rcu_dereference_protected(local->monitor_sdata, 597 sdata = rcu_dereference_check(local->monitor_sdata,
601 lockdep_is_held(&local->iflist_mtx)); 598 lockdep_is_held(&local->iflist_mtx) ||
599 lockdep_rtnl_is_held());
602 if (sdata && 600 if (sdata &&
603 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || 601 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
604 sdata->flags & IEEE80211_SDATA_IN_DRIVER)) 602 sdata->flags & IEEE80211_SDATA_IN_DRIVER))
605 iterator(data, sdata->vif.addr, &sdata->vif); 603 iterator(data, sdata->vif.addr, &sdata->vif);
604}
605
606void ieee80211_iterate_active_interfaces(
607 struct ieee80211_hw *hw, u32 iter_flags,
608 void (*iterator)(void *data, u8 *mac,
609 struct ieee80211_vif *vif),
610 void *data)
611{
612 struct ieee80211_local *local = hw_to_local(hw);
606 613
614 mutex_lock(&local->iflist_mtx);
615 __iterate_active_interfaces(local, iter_flags, iterator, data);
607 mutex_unlock(&local->iflist_mtx); 616 mutex_unlock(&local->iflist_mtx);
608} 617}
609EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 618EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
@@ -615,38 +624,26 @@ void ieee80211_iterate_active_interfaces_atomic(
615 void *data) 624 void *data)
616{ 625{
617 struct ieee80211_local *local = hw_to_local(hw); 626 struct ieee80211_local *local = hw_to_local(hw);
618 struct ieee80211_sub_if_data *sdata;
619 627
620 rcu_read_lock(); 628 rcu_read_lock();
629 __iterate_active_interfaces(local, iter_flags, iterator, data);
630 rcu_read_unlock();
631}
632EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
621 633
622 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 634void ieee80211_iterate_active_interfaces_rtnl(
623 switch (sdata->vif.type) { 635 struct ieee80211_hw *hw, u32 iter_flags,
624 case NL80211_IFTYPE_MONITOR: 636 void (*iterator)(void *data, u8 *mac,
625 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) 637 struct ieee80211_vif *vif),
626 continue; 638 void *data)
627 break; 639{
628 case NL80211_IFTYPE_AP_VLAN: 640 struct ieee80211_local *local = hw_to_local(hw);
629 continue;
630 default:
631 break;
632 }
633 if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
634 !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
635 continue;
636 if (ieee80211_sdata_running(sdata))
637 iterator(data, sdata->vif.addr,
638 &sdata->vif);
639 }
640 641
641 sdata = rcu_dereference(local->monitor_sdata); 642 ASSERT_RTNL();
642 if (sdata &&
643 (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
644 sdata->flags & IEEE80211_SDATA_IN_DRIVER))
645 iterator(data, sdata->vif.addr, &sdata->vif);
646 643
647 rcu_read_unlock(); 644 __iterate_active_interfaces(local, iter_flags, iterator, data);
648} 645}
649EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 646EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
650 647
651/* 648/*
652 * Nothing should have been stuffed into the workqueue during 649 * Nothing should have been stuffed into the workqueue during
@@ -1007,14 +1004,21 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1007 */ 1004 */
1008 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); 1005 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION);
1009 1006
1010 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1007 /* Set defaults according to 802.11-2007 Table 7-37 */
1011 /* Set defaults according to 802.11-2007 Table 7-37 */ 1008 aCWmax = 1023;
1012 aCWmax = 1023; 1009 if (use_11b)
1013 if (use_11b) 1010 aCWmin = 31;
1014 aCWmin = 31; 1011 else
1015 else 1012 aCWmin = 15;
1016 aCWmin = 15; 1013
1014 /* Confiure old 802.11b/g medium access rules. */
1015 qparam.cw_max = aCWmax;
1016 qparam.cw_min = aCWmin;
1017 qparam.txop = 0;
1018 qparam.aifs = 2;
1017 1019
1020 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1021 /* Update if QoS is enabled. */
1018 if (enable_qos) { 1022 if (enable_qos) {
1019 switch (ac) { 1023 switch (ac) {
1020 case IEEE80211_AC_BK: 1024 case IEEE80211_AC_BK:
@@ -1050,12 +1054,6 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
1050 qparam.aifs = 2; 1054 qparam.aifs = 2;
1051 break; 1055 break;
1052 } 1056 }
1053 } else {
1054 /* Confiure old 802.11b/g medium access rules. */
1055 qparam.cw_max = aCWmax;
1056 qparam.cw_min = aCWmin;
1057 qparam.txop = 0;
1058 qparam.aifs = 2;
1059 } 1057 }
1060 1058
1061 qparam.uapsd = false; 1059 qparam.uapsd = false;
@@ -1084,8 +1082,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1084 struct ieee80211_mgmt *mgmt; 1082 struct ieee80211_mgmt *mgmt;
1085 int err; 1083 int err;
1086 1084
1087 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 1085 /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
1088 sizeof(*mgmt) + 6 + extra_len); 1086 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 6 + extra_len);
1089 if (!skb) 1087 if (!skb)
1090 return; 1088 return;
1091 1089
@@ -2292,3 +2290,63 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw)
2292 ieee80211_queue_work(hw, &local->radar_detected_work); 2290 ieee80211_queue_work(hw, &local->radar_detected_work);
2293} 2291}
2294EXPORT_SYMBOL(ieee80211_radar_detected); 2292EXPORT_SYMBOL(ieee80211_radar_detected);
2293
2294u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
2295{
2296 u32 ret;
2297 int tmp;
2298
2299 switch (c->width) {
2300 case NL80211_CHAN_WIDTH_20:
2301 c->width = NL80211_CHAN_WIDTH_20_NOHT;
2302 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
2303 break;
2304 case NL80211_CHAN_WIDTH_40:
2305 c->width = NL80211_CHAN_WIDTH_20;
2306 c->center_freq1 = c->chan->center_freq;
2307 ret = IEEE80211_STA_DISABLE_40MHZ |
2308 IEEE80211_STA_DISABLE_VHT;
2309 break;
2310 case NL80211_CHAN_WIDTH_80:
2311 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
2312 /* n_P40 */
2313 tmp /= 2;
2314 /* freq_P40 */
2315 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
2316 c->width = NL80211_CHAN_WIDTH_40;
2317 ret = IEEE80211_STA_DISABLE_VHT;
2318 break;
2319 case NL80211_CHAN_WIDTH_80P80:
2320 c->center_freq2 = 0;
2321 c->width = NL80211_CHAN_WIDTH_80;
2322 ret = IEEE80211_STA_DISABLE_80P80MHZ |
2323 IEEE80211_STA_DISABLE_160MHZ;
2324 break;
2325 case NL80211_CHAN_WIDTH_160:
2326 /* n_P20 */
2327 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
2328 /* n_P80 */
2329 tmp /= 4;
2330 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
2331 c->width = NL80211_CHAN_WIDTH_80;
2332 ret = IEEE80211_STA_DISABLE_80P80MHZ |
2333 IEEE80211_STA_DISABLE_160MHZ;
2334 break;
2335 default:
2336 case NL80211_CHAN_WIDTH_20_NOHT:
2337 WARN_ON_ONCE(1);
2338 c->width = NL80211_CHAN_WIDTH_20_NOHT;
2339 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
2340 break;
2341 case NL80211_CHAN_WIDTH_5:
2342 case NL80211_CHAN_WIDTH_10:
2343 WARN_ON_ONCE(1);
2344 /* keep c->width */
2345 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
2346 break;
2347 }
2348
2349 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
2350
2351 return ret;
2352}
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index 97c289414e32..de0112785aae 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -185,13 +185,13 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
185 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) { 185 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) {
186 vht_cap->cap |= cap_info & 186 vht_cap->cap |= cap_info &
187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | 187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
188 IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX |
189 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX); 188 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX);
190 } 189 }
191 190
192 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) 191 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
193 vht_cap->cap |= cap_info & 192 vht_cap->cap |= cap_info &
194 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; 193 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
194 IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX);
195 195
196 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) 196 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
197 vht_cap->cap |= cap_info & 197 vht_cap->cap |= cap_info &