History

Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

John W. Linville committed 12 years ago

Commit 7eb24502 parents 474a41e 73fb08e27 files · +339 −195Browse files

Unified · Split

27 files
  1. include/linux/ieee80211.h +4 −0
  2. include/net/cfg80211.h +14 −9
  3. include/net/mac80211.h +4 −2
  4. include/net/regulatory.h +13 −8
  5. include/uapi/linux/nl80211.h +6 −0
  6. net/mac80211/cfg.c +67 −54
  7. net/mac80211/ibss.c +2 −10
  8. net/mac80211/ieee80211_i.h +1 −0
  9. net/mac80211/mlme.c +46 −24
  10. net/mac80211/pm.c +11 −3
  11. net/mac80211/rx.c +3 −0
  12. net/mac80211/scan.c +4 −2
  13. net/mac80211/tx.c +1 −1
  14. net/wireless/ap.c +5 −4
  15. net/wireless/chan.c +56 −0
  16. net/wireless/core.c +1 −1
  17. net/wireless/core.h +4 −6
  18. net/wireless/genregdb.awk +7 −1
  19. net/wireless/ibss.c +4 −4
  20. net/wireless/mlme.c +1 −1
  21. net/wireless/nl80211.c +21 −3
  22. net/wireless/reg.c +42 −44
  23. net/wireless/reg.h +0 −1
  24. net/wireless/scan.c +19 −12
  25. net/wireless/sme.c +0 −1
  26. net/wireless/util.c +2 −3
  27. net/wireless/wext-sme.c +1 −1
include/linux/ieee80211.h+4−0
@@ -154,6 +154,10 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2) · 153 unmodified lines
154154 802.11e clarifies the figure in section 7.1.2. The frame body is
155155 up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
156156 #define IEEE80211_MAX_DATA_LEN 2304
157+/* 802.11ad extends maximum MSDU size for DMG (freq > 40Ghz) networks
158+ * to 7920 bytes, see 8.2.3 General frame format
159+ */
160+#define IEEE80211_MAX_DATA_LEN_DMG 7920
157161 /* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
158162 #define IEEE80211_MAX_FRAME_LEN 2352
159163
include/net/cfg80211.h+14−9
@@ -151,6 +151,7 @@ enum ieee80211_channel_flags { · 150 unmodified lines
151151 * @dfs_state: current state of this channel. Only relevant if radar is required
152152 * on this channel.
153153 * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
154+ * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
154155 */
155156 struct ieee80211_channel {
156157 enum ieee80211_band band;
@@ -165,6 +166,7 @@ struct ieee80211_channel { · 8 unmodified lines
165166 int orig_mag, orig_mpwr;
166167 enum nl80211_dfs_state dfs_state;
167168 unsigned long dfs_state_entered;
169+ unsigned int dfs_cac_ms;
168170 };
169171
170172 /**
@@ -2503,7 +2505,8 @@ struct cfg80211_ops { · 2332 unmodified lines
25032505
25042506 int (*start_radar_detection)(struct wiphy *wiphy,
25052507 struct net_device *dev,
2506− struct cfg80211_chan_def *chandef);
2508+ struct cfg80211_chan_def *chandef,
2509+ u32 cac_time_ms);
25072510 int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
25082511 struct cfg80211_update_ft_ies_params *ftie);
25092512 int (*crit_proto_start)(struct wiphy *wiphy,
@@ -3180,6 +3183,7 @@ struct cfg80211_cached_keys; · 670 unmodified lines
31803183 * @p2p_started: true if this is a P2P Device that has been started
31813184 * @cac_started: true if DFS channel availability check has been started
31823185 * @cac_start_time: timestamp (jiffies) when the dfs state was entered.
3186+ * @cac_time_ms: CAC time in ms
31833187 * @ps: powersave mode is enabled
31843188 * @ps_timeout: dynamic powersave timeout
31853189 * @ap_unexpected_nlportid: (private) netlink port ID of application
@@ -3235,6 +3239,7 @@ struct wireless_dev { · 49 unmodified lines
32353239
32363240 bool cac_started;
32373241 unsigned long cac_start_time;
3242+ unsigned int cac_time_ms;
32383243
32393244 #ifdef CONFIG_CFG80211_WEXT
32403245 /* wext data */
@@ -3667,7 +3672,7 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy); · 426 unmodified lines
36673672 * cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame
36683673 *
36693674 * @wiphy: the wiphy reporting the BSS
3670− * @channel: The channel the frame was received on
3675+ * @rx_channel: The channel the frame was received on
36713676 * @scan_width: width of the control channel
36723677 * @mgmt: the management frame (probe response or beacon)
36733678 * @len: length of the management frame
@@ -3682,18 +3687,18 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy); · 8 unmodified lines
36823687 */
36833688 struct cfg80211_bss * __must_check
36843689 cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
3685− struct ieee80211_channel *channel,
3690+ struct ieee80211_channel *rx_channel,
36863691 enum nl80211_bss_scan_width scan_width,
36873692 struct ieee80211_mgmt *mgmt, size_t len,
36883693 s32 signal, gfp_t gfp);
36893694
36903695 static inline struct cfg80211_bss * __must_check
36913696 cfg80211_inform_bss_frame(struct wiphy *wiphy,
3692− struct ieee80211_channel *channel,
3697+ struct ieee80211_channel *rx_channel,
36933698 struct ieee80211_mgmt *mgmt, size_t len,
36943699 s32 signal, gfp_t gfp)
36953700 {
3696− return cfg80211_inform_bss_width_frame(wiphy, channel,
3701+ return cfg80211_inform_bss_width_frame(wiphy, rx_channel,
36973702 NL80211_BSS_CHAN_WIDTH_20,
36983703 mgmt, len, signal, gfp);
36993704 }
@@ -3702,7 +3707,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 2 unmodified lines
37023707 * cfg80211_inform_bss - inform cfg80211 of a new BSS
37033708 *
37043709 * @wiphy: the wiphy reporting the BSS
3705− * @channel: The channel the frame was received on
3710+ * @rx_channel: The channel the frame was received on
37063711 * @scan_width: width of the control channel
37073712 * @bssid: the BSSID of the BSS
37083713 * @tsf: the TSF sent by the peer in the beacon/probe response (or 0)
@@ -3721,7 +3726,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, · 12 unmodified lines
37213726 */
37223727 struct cfg80211_bss * __must_check
37233728 cfg80211_inform_bss_width(struct wiphy *wiphy,
3724− struct ieee80211_channel *channel,
3729+ struct ieee80211_channel *rx_channel,
37253730 enum nl80211_bss_scan_width scan_width,
37263731 const u8 *bssid, u64 tsf, u16 capability,
37273732 u16 beacon_interval, const u8 *ie, size_t ielen,
@@ -3729,12 +3734,12 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, · 1 unmodified line
37293734
37303735 static inline struct cfg80211_bss * __must_check
37313736 cfg80211_inform_bss(struct wiphy *wiphy,
3732− struct ieee80211_channel *channel,
3737+ struct ieee80211_channel *rx_channel,
37333738 const u8 *bssid, u64 tsf, u16 capability,
37343739 u16 beacon_interval, const u8 *ie, size_t ielen,
37353740 s32 signal, gfp_t gfp)
37363741 {
3737− return cfg80211_inform_bss_width(wiphy, channel,
3742+ return cfg80211_inform_bss_width(wiphy, rx_channel,
37383743 NL80211_BSS_CHAN_WIDTH_20,
37393744 bssid, tsf, capability,
37403745 beacon_interval, ie, ielen, signal,
include/net/mac80211.h+4−2
@@ -697,11 +697,11 @@ struct ieee80211_tx_info { · 696 unmodified lines
697697 } control;
698698 struct {
699699 struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
700− int ack_signal;
700+ s32 ack_signal;
701701 u8 ampdu_ack_len;
702702 u8 ampdu_len;
703703 u8 antenna;
704− /* 21 bytes free */
704+ void *status_driver_data[21 / sizeof(void *)];
705705 } status;
706706 struct {
707707 struct ieee80211_tx_rate driver_rates[
@@ -877,11 +877,13 @@ enum mac80211_rx_flags { · 169 unmodified lines
877877 * @RX_VHT_FLAG_80MHZ: 80 MHz was used
878878 * @RX_VHT_FLAG_80P80MHZ: 80+80 MHz was used
879879 * @RX_VHT_FLAG_160MHZ: 160 MHz was used
880+ * @RX_VHT_FLAG_BF: packet was beamformed
880881 */
881882 enum mac80211_rx_vht_flags {
882883 RX_VHT_FLAG_80MHZ = BIT(0),
883884 RX_VHT_FLAG_80P80MHZ = BIT(1),
884885 RX_VHT_FLAG_160MHZ = BIT(2),
886+ RX_VHT_FLAG_BF = BIT(3),
885887 };
886888
887889 /**
include/net/regulatory.h+13−8
@@ -155,6 +155,7 @@ struct ieee80211_reg_rule { · 154 unmodified lines
155155 struct ieee80211_freq_range freq_range;
156156 struct ieee80211_power_rule power_rule;
157157 u32 flags;
158+ u32 dfs_cac_ms;
158159 };
159160
160161 struct ieee80211_regdomain {
@@ -172,14 +173,18 @@ struct ieee80211_regdomain { · 11 unmodified lines
172173 #define DBM_TO_MBM(gain) ((gain) * 100)
173174 #define MBM_TO_DBM(gain) ((gain) / 100)
174175
175−#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
176−{ \
177− .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
178− .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
179− .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
180− .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\
181− .power_rule.max_eirp = DBM_TO_MBM(eirp), \
182− .flags = reg_flags, \
176+#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \
177+{ \
178+ .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
179+ .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
180+ .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
181+ .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
182+ .power_rule.max_eirp = DBM_TO_MBM(eirp), \
183+ .flags = reg_flags, \
184+ .dfs_cac_ms = dfs_cac, \
183185 }
184186
187+#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
188+ REG_RULE_EXT(start, end, bw, gain, eirp, 0, reg_flags)
189+
185190 #endif
include/uapi/linux/nl80211.h+6−0
@@ -2335,6 +2335,7 @@ enum nl80211_band_attr { · 2334 unmodified lines
23352335 * @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel
23362336 * using this channel as the primary or any of the secondary channels
23372337 * isn't possible
2338+ * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
23382339 * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
23392340 * currently defined
23402341 * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@@ -2353,6 +2354,7 @@ enum nl80211_frequency_attr { · 12 unmodified lines
23532354 NL80211_FREQUENCY_ATTR_NO_HT40_PLUS,
23542355 NL80211_FREQUENCY_ATTR_NO_80MHZ,
23552356 NL80211_FREQUENCY_ATTR_NO_160MHZ,
2357+ NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
23562358
23572359 /* keep last */
23582360 __NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@ -2449,6 +2451,8 @@ enum nl80211_reg_type { · 90 unmodified lines
24492451 * If you don't have one then don't send this.
24502452 * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
24512453 * a given frequency range. The value is in mBm (100 * dBm).
2454+ * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
2455+ * If not present or 0 default CAC time will be used.
24522456 * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
24532457 * currently defined
24542458 * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
@@ -2464,6 +2468,8 @@ enum nl80211_reg_rule_attr { · 9 unmodified lines
24642468 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
24652469 NL80211_ATTR_POWER_RULE_MAX_EIRP,
24662470
2471+ NL80211_ATTR_DFS_CAC_TIME,
2472+
24672473 /* keep last */
24682474 __NL80211_REG_RULE_ATTR_AFTER_LAST,
24692475 NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
net/mac80211/cfg.c+67−54
@@ -2914,11 +2914,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, · 2913 unmodified lines
29142914
29152915 static int ieee80211_start_radar_detection(struct wiphy *wiphy,
29162916 struct net_device *dev,
2917− struct cfg80211_chan_def *chandef)
2917+ struct cfg80211_chan_def *chandef,
2918+ u32 cac_time_ms)
29182919 {
29192920 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
29202921 struct ieee80211_local *local = sdata->local;
2921− unsigned long timeout;
29222922 int err;
29232923
29242924 mutex_lock(&local->mtx);
@@ -2937,9 +2937,9 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy, · 12 unmodified lines
29372937 if (err)
29382938 goto out_unlock;
29392939
2940− timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
29412940 ieee80211_queue_delayed_work(&sdata->local->hw,
2942− &sdata->dfs_cac_timer_work, timeout);
2941+ &sdata->dfs_cac_timer_work,
2942+ msecs_to_jiffies(cac_time_ms));
29432943
29442944 out_unlock:
29452945 mutex_unlock(&local->mtx);
@@ -3089,52 +3089,11 @@ unlock: · 143 unmodified lines
30893089 sdata_unlock(sdata);
30903090 }
30913091
3092−int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3093− struct cfg80211_csa_settings *params)
3092+static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
3093+ struct cfg80211_csa_settings *params,
3094+ u32 *changed)
30943095 {
3095− struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3096− struct ieee80211_local *local = sdata->local;
3097− struct ieee80211_chanctx_conf *chanctx_conf;
3098− struct ieee80211_chanctx *chanctx;
3099− struct ieee80211_if_mesh __maybe_unused *ifmsh;
3100− int err, num_chanctx, changed = 0;
3101−
3102− sdata_assert_lock(sdata);
3103−
3104− if (!list_empty(&local->roc_list) || local->scanning)
3105− return -EBUSY;
3106−
3107− if (sdata->wdev.cac_started)
3108− return -EBUSY;
3109−
3110− if (cfg80211_chandef_identical(&params->chandef,
3111− &sdata->vif.bss_conf.chandef))
3112− return -EINVAL;
3113−
3114− rcu_read_lock();
3115− chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3116− if (!chanctx_conf) {
3117− rcu_read_unlock();
3118− return -EBUSY;
3119− }
3120−
3121− /* don't handle for multi-VIF cases */
3122− chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
3123− if (chanctx->refcount > 1) {
3124− rcu_read_unlock();
3125− return -EBUSY;
3126− }
3127− num_chanctx = 0;
3128− list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
3129− num_chanctx++;
3130− rcu_read_unlock();
3131−
3132− if (num_chanctx > 1)
3133− return -EBUSY;
3134−
3135− /* don't allow another channel switch if one is already active. */
3136− if (sdata->vif.csa_active)
3137− return -EBUSY;
3096+ int err;
31383097
31393098 switch (sdata->vif.type) {
31403099 case NL80211_IFTYPE_AP:
@@ -3170,7 +3129,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, · 29 unmodified lines
31703129 kfree(sdata->u.ap.next_beacon);
31713130 return err;
31723131 }
3173− changed |= err;
3132+ *changed |= err;
31743133
31753134 break;
31763135 case NL80211_IFTYPE_ADHOC:
@@ -3204,15 +3163,15 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, · 27 unmodified lines
32043163 err = ieee80211_ibss_csa_beacon(sdata, params);
32053164 if (err < 0)
32063165 return err;
3207− changed |= err;
3166+ *changed |= err;
32083167 }
32093168
32103169 ieee80211_send_action_csa(sdata, params);
32113170
32123171 break;
32133172 #ifdef CONFIG_MAC80211_MESH
3214− case NL80211_IFTYPE_MESH_POINT:
3215− ifmsh = &sdata->u.mesh;
3173+ case NL80211_IFTYPE_MESH_POINT: {
3174+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
32163175
32173176 if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
32183177 return -EINVAL;
@@ -3237,18 +3196,72 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, · 18 unmodified lines
32373196 ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
32383197 return err;
32393198 }
3240− changed |= err;
3199+ *changed |= err;
32413200 }
32423201
32433202 if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT)
32443203 ieee80211_send_action_csa(sdata, params);
32453204
32463205 break;
3206+ }
32473207 #endif
32483208 default:
32493209 return -EOPNOTSUPP;
32503210 }
32513211
3212+ return 0;
3213+}
3214+
3215+int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3216+ struct cfg80211_csa_settings *params)
3217+{
3218+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3219+ struct ieee80211_local *local = sdata->local;
3220+ struct ieee80211_chanctx_conf *chanctx_conf;
3221+ struct ieee80211_chanctx *chanctx;
3222+ int err, num_chanctx, changed = 0;
3223+
3224+ sdata_assert_lock(sdata);
3225+
3226+ if (!list_empty(&local->roc_list) || local->scanning)
3227+ return -EBUSY;
3228+
3229+ if (sdata->wdev.cac_started)
3230+ return -EBUSY;
3231+
3232+ if (cfg80211_chandef_identical(&params->chandef,
3233+ &sdata->vif.bss_conf.chandef))
3234+ return -EINVAL;
3235+
3236+ rcu_read_lock();
3237+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3238+ if (!chanctx_conf) {
3239+ rcu_read_unlock();
3240+ return -EBUSY;
3241+ }
3242+
3243+ /* don't handle for multi-VIF cases */
3244+ chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
3245+ if (chanctx->refcount > 1) {
3246+ rcu_read_unlock();
3247+ return -EBUSY;
3248+ }
3249+ num_chanctx = 0;
3250+ list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
3251+ num_chanctx++;
3252+ rcu_read_unlock();
3253+
3254+ if (num_chanctx > 1)
3255+ return -EBUSY;
3256+
3257+ /* don't allow another channel switch if one is already active. */
3258+ if (sdata->vif.csa_active)
3259+ return -EBUSY;
3260+
3261+ err = ieee80211_set_csa_beacon(sdata, params, &changed);
3262+ if (err)
3263+ return err;
3264+
32523265 sdata->csa_radar_required = params->radar_required;
32533266
32543267 if (params->block_tx)
net/mac80211/ibss.c+2−10
@@ -991,7 +991,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, · 990 unmodified lines
991991 struct ieee802_11_elems *elems)
992992 {
993993 struct ieee80211_local *local = sdata->local;
994− int freq;
995994 struct cfg80211_bss *cbss;
996995 struct ieee80211_bss *bss;
997996 struct sta_info *sta;
@@ -1003,15 +1002,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, · 5 unmodified lines
10031002 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
10041003 bool rates_updated = false;
10051004
1006− if (elems->ds_params)
1007− freq = ieee80211_channel_to_frequency(elems->ds_params[0],
1008− band);
1009− else
1010− freq = rx_status->freq;
1011−
1012− channel = ieee80211_get_channel(local->hw.wiphy, freq);
1013−
1014− if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
1005+ channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
1006+ if (!channel)
10151007 return;
10161008
10171009 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
net/mac80211/ieee80211_i.h+1−0
@@ -1391,6 +1391,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); · 1390 unmodified lines
13911391 void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
13921392 void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
13931393 __le16 fc, bool acked);
1394+void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);
13941395 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
13951396
13961397 /* IBSS code */
net/mac80211/mlme.c+46−24
@@ -2783,28 +2783,20 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, · 2782 unmodified lines
27832783 struct ieee802_11_elems *elems)
27842784 {
27852785 struct ieee80211_local *local = sdata->local;
2786− int freq;
27872786 struct ieee80211_bss *bss;
27882787 struct ieee80211_channel *channel;
27892788
27902789 sdata_assert_lock(sdata);
27912790
2792− if (elems->ds_params)
2793− freq = ieee80211_channel_to_frequency(elems->ds_params[0],
2794− rx_status->band);
2795− else
2796− freq = rx_status->freq;
2797−
2798− channel = ieee80211_get_channel(local->hw.wiphy, freq);
2799−
2800− if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
2791+ channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
2792+ if (!channel)
28012793 return;
28022794
28032795 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
28042796 channel);
28052797 if (bss) {
2806− ieee80211_rx_bss_put(local, bss);
28072798 sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
2799+ ieee80211_rx_bss_put(local, bss);
28082800 }
28092801 }
28102802
@@ -3599,6 +3591,32 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) · 788 unmodified lines
35993591 }
36003592
36013593 #ifdef CONFIG_PM
3594+void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
3595+{
3596+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3597+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3598+
3599+ sdata_lock(sdata);
3600+
3601+ if (ifmgd->auth_data) {
3602+ /*
3603+ * If we are trying to authenticate while suspending, cfg80211
3604+ * won't know and won't actually abort those attempts, thus we
3605+ * need to do that ourselves.
3606+ */
3607+ ieee80211_send_deauth_disassoc(sdata,
3608+ ifmgd->auth_data->bss->bssid,
3609+ IEEE80211_STYPE_DEAUTH,
3610+ WLAN_REASON_DEAUTH_LEAVING,
3611+ false, frame_buf);
3612+ ieee80211_destroy_auth_data(sdata, false);
3613+ cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
3614+ IEEE80211_DEAUTH_FRAME_LEN);
3615+ }
3616+
3617+ sdata_unlock(sdata);
3618+}
3619+
36023620 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
36033621 {
36043622 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -4417,37 +4435,41 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, · 812 unmodified lines
44174435 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
44184436 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
44194437 bool tx = !req->local_state_change;
4420− bool report_frame = false;
44214438
4422− sdata_info(sdata,
4423− "deauthenticating from %pM by local choice (Reason: %u=%s)\n",
4424− req->bssid, req->reason_code, ieee80211_get_reason_code_string(req->reason_code));
4439+ if (ifmgd->auth_data &&
4440+ ether_addr_equal(ifmgd->auth_data->bss->bssid, req->bssid)) {
4441+ sdata_info(sdata,
4442+ "aborting authentication with %pM by local choice (Reason: %u=%s)\n",
4443+ req->bssid, req->reason_code,
4444+ ieee80211_get_reason_code_string(req->reason_code));
44254445
4426− if (ifmgd->auth_data) {
44274446 drv_mgd_prepare_tx(sdata->local, sdata);
44284447 ieee80211_send_deauth_disassoc(sdata, req->bssid,
44294448 IEEE80211_STYPE_DEAUTH,
44304449 req->reason_code, tx,
44314450 frame_buf);
44324451 ieee80211_destroy_auth_data(sdata, false);
4452+ cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4453+ IEEE80211_DEAUTH_FRAME_LEN);
44334454
4434− report_frame = true;
4435− goto out;
4455+ return 0;
44364456 }
44374457
44384458 if (ifmgd->associated &&
44394459 ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
4460+ sdata_info(sdata,
4461+ "deauthenticating from %pM by local choice (Reason: %u=%s)\n",
4462+ req->bssid, req->reason_code,
4463+ ieee80211_get_reason_code_string(req->reason_code));
4464+
44404465 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
44414466 req->reason_code, tx, frame_buf);
4442− report_frame = true;
4443− }
4444−
4445− out:
4446− if (report_frame)
44474467 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
44484468 IEEE80211_DEAUTH_FRAME_LEN);
4469+ return 0;
4470+ }
44494471
4450− return 0;
4472+ return -ENOTCONN;
44514473 }
44524474
44534475 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
net/mac80211/pm.c+11−3
@@ -100,10 +100,18 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) · 99 unmodified lines
100100
101101 /* remove all interfaces that were created in the driver */
102102 list_for_each_entry(sdata, &local->interfaces, list) {
103− if (!ieee80211_sdata_running(sdata) ||
104− sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
105− sdata->vif.type == NL80211_IFTYPE_MONITOR)
103+ if (!ieee80211_sdata_running(sdata))
106104 continue;
105+ switch (sdata->vif.type) {
106+ case NL80211_IFTYPE_AP_VLAN:
107+ case NL80211_IFTYPE_MONITOR:
108+ continue;
109+ case NL80211_IFTYPE_STATION:
110+ ieee80211_mgd_quiesce(sdata);
111+ break;
112+ default:
113+ break;
114+ }
107115
108116 drv_remove_interface(local, sdata);
109117 }
net/mac80211/rx.c+3−0
@@ -333,6 +333,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, · 332 unmodified lines
333333 /* in VHT, STBC is binary */
334334 if (status->flag & RX_FLAG_STBC_MASK)
335335 *pos |= IEEE80211_RADIOTAP_VHT_FLAG_STBC;
336+ if (status->vht_flag & RX_VHT_FLAG_BF)
337+ *pos |= IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED;
336338 pos++;
337339 /* bandwidth */
338340 if (status->vht_flag & RX_VHT_FLAG_80MHZ)
@@ -1245,6 +1247,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) · 906 unmodified lines
12451247 if (ieee80211_is_data(hdr->frame_control)) {
12461248 sta->last_rx_rate_idx = status->rate_idx;
12471249 sta->last_rx_rate_flag = status->flag;
1250+ sta->last_rx_rate_vht_flag = status->vht_flag;
12481251 sta->last_rx_rate_vht_nss = status->vht_nss;
12491252 }
12501253 }
net/mac80211/scan.c+4−2
@@ -1055,9 +1055,11 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) · 1054 unmodified lines
10551055 /* We don't want to restart sched scan anymore. */
10561056 local->sched_scan_req = NULL;
10571057
1058− if (rcu_access_pointer(local->sched_scan_sdata))
1058+ if (rcu_access_pointer(local->sched_scan_sdata)) {
10591059 ret = drv_sched_scan_stop(local, sdata);
1060−
1060+ if (!ret)
1061+ rcu_assign_pointer(local->sched_scan_sdata, NULL);
1062+ }
10611063 out:
10621064 mutex_unlock(&local->mtx);
10631065
net/mac80211/tx.c+1−1
@@ -2900,7 +2900,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, · 2899 unmodified lines
29002900 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
29012901 }
29022902
2903− if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2903+ if (sdata->vif.type == NL80211_IFTYPE_AP)
29042904 sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
29052905 if (!ieee80211_tx_prepare(sdata, &tx, skb))
29062906 break;
net/wireless/ap.c+5−4
@@ -7,7 +7,7 @@ · 6 unmodified lines
77
88
99 static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
10− struct net_device *dev)
10+ struct net_device *dev, bool notify)
1111 {
1212 struct wireless_dev *wdev = dev->ieee80211_ptr;
1313 int err;
@@ -30,20 +30,21 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, · 16 unmodified lines
3030 memset(&wdev->chandef, 0, sizeof(wdev->chandef));
3131 wdev->ssid_len = 0;
3232 rdev_set_qos_map(rdev, dev, NULL);
33− nl80211_send_ap_stopped(wdev);
33+ if (notify)
34+ nl80211_send_ap_stopped(wdev);
3435 }
3536
3637 return err;
3738 }
3839
3940 int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
40− struct net_device *dev)
41+ struct net_device *dev, bool notify)
4142 {
4243 struct wireless_dev *wdev = dev->ieee80211_ptr;
4344 int err;
4445
4546 wdev_lock(wdev);
46− err = __cfg80211_stop_ap(rdev, dev);
47+ err = __cfg80211_stop_ap(rdev, dev, notify);
4748 wdev_unlock(wdev);
4849
4950 return err;
net/wireless/chan.c+56−0
@@ -490,6 +490,62 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, · 489 unmodified lines
490490 return r;
491491 }
492492
493+static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
494+ u32 center_freq,
495+ u32 bandwidth)
496+{
497+ struct ieee80211_channel *c;
498+ u32 start_freq, end_freq, freq;
499+ unsigned int dfs_cac_ms = 0;
500+
501+ start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
502+ end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
503+
504+ for (freq = start_freq; freq <= end_freq; freq += 20) {
505+ c = ieee80211_get_channel(wiphy, freq);
506+ if (!c)
507+ return 0;
508+
509+ if (c->flags & IEEE80211_CHAN_DISABLED)
510+ return 0;
511+
512+ if (!(c->flags & IEEE80211_CHAN_RADAR))
513+ continue;
514+
515+ if (c->dfs_cac_ms > dfs_cac_ms)
516+ dfs_cac_ms = c->dfs_cac_ms;
517+ }
518+
519+ return dfs_cac_ms;
520+}
521+
522+unsigned int
523+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
524+ const struct cfg80211_chan_def *chandef)
525+{
526+ int width;
527+ unsigned int t1 = 0, t2 = 0;
528+
529+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
530+ return 0;
531+
532+ width = cfg80211_chandef_get_width(chandef);
533+ if (width < 0)
534+ return 0;
535+
536+ t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
537+ chandef->center_freq1,
538+ width);
539+
540+ if (!chandef->center_freq2)
541+ return t1;
542+
543+ t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
544+ chandef->center_freq2,
545+ width);
546+
547+ return max(t1, t2);
548+}
493549
494550 static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
495551 u32 center_freq, u32 bandwidth,
net/wireless/core.c+1−1
@@ -783,7 +783,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, · 782 unmodified lines
783783 break;
784784 case NL80211_IFTYPE_AP:
785785 case NL80211_IFTYPE_P2P_GO:
786− cfg80211_stop_ap(rdev, dev);
786+ cfg80211_stop_ap(rdev, dev, true);
787787 break;
788788 default:
789789 break;
net/wireless/core.h+4−6
@@ -166,7 +166,6 @@ static inline void wdev_unlock(struct wireless_dev *wdev) · 165 unmodified lines
166166 mutex_unlock(&wdev->mtx);
167167 }
168168
169−#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
170169 #define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
171170
172171 static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
@@ -246,10 +245,6 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, · 73 unmodified lines
246245 unsigned long age_secs);
247246
248247 /* IBSS */
249−int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
250− struct net_device *dev,
251− struct cfg80211_ibss_params *params,
252− struct cfg80211_cached_keys *connkeys);
253248 int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
254249 struct net_device *dev,
255250 struct cfg80211_ibss_params *params,
@@ -283,7 +278,7 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, · 27 unmodified lines
283278
284279 /* AP */
285280 int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
286− struct net_device *dev);
281+ struct net_device *dev, bool notify);
287282
288283 /* MLME */
289284 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
@@ -402,6 +397,9 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy, · 112 unmodified lines
402397
403398 void cfg80211_dfs_channels_update_work(struct work_struct *work);
404399
400+unsigned int
401+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
402+ const struct cfg80211_chan_def *chandef);
405403
406404 static inline int
407405 cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
net/wireless/genregdb.awk+7−1
@@ -66,6 +66,7 @@ function parse_reg_rule() · 65 unmodified lines
6666 units = $8
6767 sub(/\)/, "", units)
6868 sub(/,/, "", units)
69+ dfs_cac = $9
6970 if (units == "mW") {
7071 if (power == 100) {
7172 power = 20
@@ -78,7 +79,12 @@ function parse_reg_rule() · 6 unmodified lines
7879 } else {
7980 print "Unknown power value in database!"
8081 }
82+ } else {
83+ dfs_cac = $8
8184 }
85+ sub(/,/, "", dfs_cac)
86+ sub(/\(/, "", dfs_cac)
87+ sub(/\)/, "", dfs_cac)
8288 flagstr = ""
8389 for (i=8; i<=NF; i++)
8490 flagstr = flagstr $i
@@ -111,7 +117,7 @@ function parse_reg_rule() · 26 unmodified lines
111117
112118 }
113119 flags = flags "0"
114− printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags
120+ printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
115121 rules++
116122 }
117123
net/wireless/ibss.c+4−4
@@ -82,10 +82,10 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, · 81 unmodified lines
8282 }
8383 EXPORT_SYMBOL(cfg80211_ibss_joined);
8484
85−int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
86− struct net_device *dev,
87− struct cfg80211_ibss_params *params,
88− struct cfg80211_cached_keys *connkeys)
85+static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
86+ struct net_device *dev,
87+ struct cfg80211_ibss_params *params,
88+ struct cfg80211_cached_keys *connkeys)
8989 {
9090 struct wireless_dev *wdev = dev->ieee80211_ptr;
9191 struct ieee80211_channel *check_chan;
net/wireless/mlme.c+1−1
@@ -778,7 +778,7 @@ void cfg80211_cac_event(struct net_device *netdev, · 777 unmodified lines
778778 switch (event) {
779779 case NL80211_RADAR_CAC_FINISHED:
780780 timeout = wdev->cac_start_time +
781− msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
781+ msecs_to_jiffies(wdev->cac_time_ms);
782782 WARN_ON(!time_after_eq(jiffies, timeout));
783783 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
784784 break;
net/wireless/nl80211.c+21−3
@@ -593,6 +593,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, · 592 unmodified lines
593593 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
594594 time))
595595 goto nla_put_failure;
596+ if (nla_put_u32(msg,
597+ NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
598+ chan->dfs_cac_ms))
599+ goto nla_put_failure;
596600 }
597601 }
598602
@@ -3328,7 +3332,7 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) · 2729 unmodified lines
33283332 struct cfg80211_registered_device *rdev = info->user_ptr[0];
33293333 struct net_device *dev = info->user_ptr[1];
33303334
3331− return cfg80211_stop_ap(rdev, dev);
3335+ return cfg80211_stop_ap(rdev, dev, false);
33323336 }
33333337
33343338 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -4614,6 +4618,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = · 1279 unmodified lines
46144618 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
46154619 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
46164620 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
4621+ [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
46174622 };
46184623
46194624 static int parse_reg_rule(struct nlattr *tb[],
@@ -4649,6 +4654,10 @@ static int parse_reg_rule(struct nlattr *tb[], · 29 unmodified lines
46494654 power_rule->max_antenna_gain =
46504655 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
46514656
4657+ if (tb[NL80211_ATTR_DFS_CAC_TIME])
4658+ reg_rule->dfs_cac_ms =
4659+ nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
4660+
46524661 return 0;
46534662 }
46544663
@@ -5136,7 +5145,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) · 481 unmodified lines
51365145 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
51375146 power_rule->max_antenna_gain) ||
51385147 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
5139− power_rule->max_eirp))
5148+ power_rule->max_eirp) ||
5149+ nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
5150+ reg_rule->dfs_cac_ms))
51405151 goto nla_put_failure_rcu;
51415152
51425153 nla_nest_end(msg, nl_reg_rule);
@@ -5768,6 +5779,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, · 625 unmodified lines
57685779 struct wireless_dev *wdev = dev->ieee80211_ptr;
57695780 struct cfg80211_chan_def chandef;
57705781 enum nl80211_dfs_regions dfs_region;
5782+ unsigned int cac_time_ms;
57715783 int err;
57725784
57735785 dfs_region = reg_get_dfs_region(wdev->wiphy);
@@ -5803,11 +5815,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb, · 29 unmodified lines
58035815 if (err)
58045816 return err;
58055817
5806− err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5818+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
5819+ if (WARN_ON(!cac_time_ms))
5820+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
5821+
5822+ err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef,
5823+ cac_time_ms);
58075824 if (!err) {
58085825 wdev->chandef = chandef;
58095826 wdev->cac_started = true;
58105827 wdev->cac_start_time = jiffies;
5828+ wdev->cac_time_ms = cac_time_ms;
58115829 }
58125830 return err;
58135831 }
net/wireless/reg.c+42−44
@@ -91,10 +91,6 @@ static struct regulatory_request __rcu *last_request = · 90 unmodified lines
9191 /* To trigger userspace events */
9292 static struct platform_device *reg_pdev;
9393
94−static const struct device_type reg_device_type = {
95− .uevent = reg_device_uevent,
96−};
97−
9894 /*
9995 * Central wireless core regulatory domains, we only need two,
10096 * the current one and a world regulatory domain in case we have no
@@ -244,19 +240,21 @@ static char user_alpha2[2]; · 143 unmodified lines
244240 module_param(ieee80211_regdom, charp, 0444);
245241 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
246242
247−static void reg_kfree_last_request(void)
243+static void reg_free_request(struct regulatory_request *lr)
248244 {
249− struct regulatory_request *lr;
250−
251− lr = get_last_request();
252−
253245 if (lr != &core_request_world && lr)
254246 kfree_rcu(lr, rcu_head);
255247 }
256248
257249 static void reg_update_last_request(struct regulatory_request *request)
258250 {
259− reg_kfree_last_request();
251+ struct regulatory_request *lr;
252+
253+ lr = get_last_request();
254+ if (lr == request)
255+ return;
256+
257+ reg_free_request(lr);
260258 rcu_assign_pointer(last_request, request);
261259 }
262260
@@ -487,11 +485,16 @@ static inline void reg_regdb_query(const char *alpha2) {} · 224 unmodified lines
487485
488486 /*
489487 * This lets us keep regulatory code which is updated on a regulatory
490− * basis in userspace. Country information is filled in by
491− * reg_device_uevent
488+ * basis in userspace.
492489 */
493490 static int call_crda(const char *alpha2)
494491 {
492+ char country[12];
493+ char *env[] = { country, NULL };
494+
495+ snprintf(country, sizeof(country), "COUNTRY=%c%c",
496+ alpha2[0], alpha2[1]);
497+
495498 if (!is_world_regdom((char *) alpha2))
496499 pr_info("Calling CRDA for country: %c%c\n",
497500 alpha2[0], alpha2[1]);
@@ -501,7 +504,7 @@ static int call_crda(const char *alpha2) · 3 unmodified lines
501504 /* query internal regulatory database (if it exists) */
502505 reg_regdb_query(alpha2);
503506
504− return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE);
507+ return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, env);
505508 }
506509
507510 static enum reg_request_treatment
@@ -755,6 +758,9 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, · 247 unmodified lines
755758 power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
756759 power_rule2->max_antenna_gain);
757760
761+ intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms,
762+ rule2->dfs_cac_ms);
763+
758764 if (!is_valid_reg_rule(intersected_rule))
759765 return -EINVAL;
760766
@@ -1077,6 +1083,14 @@ static void handle_channel(struct wiphy *wiphy, · 316 unmodified lines
10771083 min_t(int, chan->orig_mag,
10781084 MBI_TO_DBI(power_rule->max_antenna_gain));
10791085 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
1086+
1087+ if (chan->flags & IEEE80211_CHAN_RADAR) {
1088+ if (reg_rule->dfs_cac_ms)
1089+ chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
1090+ else
1091+ chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
1092+ }
1093+
10801094 if (chan->orig_mpwr) {
10811095 /*
10821096 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
@@ -2255,9 +2269,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) · 1172 unmodified lines
22552269 const struct ieee80211_reg_rule *reg_rule = NULL;
22562270 const struct ieee80211_freq_range *freq_range = NULL;
22572271 const struct ieee80211_power_rule *power_rule = NULL;
2258− char bw[32];
2272+ char bw[32], cac_time[32];
22592273
2260− pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n");
2274+ pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
22612275
22622276 for (i = 0; i < rd->n_reg_rules; i++) {
22632277 reg_rule = &rd->reg_rules[i];
@@ -2272,23 +2286,32 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd) · 8 unmodified lines
22722286 snprintf(bw, sizeof(bw), "%d KHz",
22732287 freq_range->max_bandwidth_khz);
22742288
2289+ if (reg_rule->flags & NL80211_RRF_DFS)
2290+ scnprintf(cac_time, sizeof(cac_time), "%u s",
2291+ reg_rule->dfs_cac_ms/1000);
2292+ else
2293+ scnprintf(cac_time, sizeof(cac_time), "N/A");
2294+
2295+
22752296 /*
22762297 * There may not be documentation for max antenna gain
22772298 * in certain regions
22782299 */
22792300 if (power_rule->max_antenna_gain)
2280− pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm)\n",
2301+ pr_info(" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
22812302 freq_range->start_freq_khz,
22822303 freq_range->end_freq_khz,
22832304 bw,
22842305 power_rule->max_antenna_gain,
2285− power_rule->max_eirp);
2306+ power_rule->max_eirp,
2307+ cac_time);
22862308 else
2287− pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm)\n",
2309+ pr_info(" (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
22882310 freq_range->start_freq_khz,
22892311 freq_range->end_freq_khz,
22902312 bw,
2291− power_rule->max_eirp);
2313+ power_rule->max_eirp,
2314+ cac_time);
22922315 }
22932316 }
22942317
@@ -2361,9 +2384,6 @@ static int reg_set_rd_user(const struct ieee80211_regdomain *rd, · 66 unmodified lines
23612384 {
23622385 const struct ieee80211_regdomain *intersected_rd = NULL;
23632386
2364− if (is_world_regdom(rd->alpha2))
2365− return -EINVAL;
2366−
23672387 if (!regdom_changes(rd->alpha2))
23682388 return -EALREADY;
23692389
@@ -2552,26 +2572,6 @@ int set_regdom(const struct ieee80211_regdomain *rd) · 182 unmodified lines
25522572 return 0;
25532573 }
25542574
2555−int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2556−{
2557− struct regulatory_request *lr;
2558− u8 alpha2[2];
2559− bool add = false;
2560−
2561− rcu_read_lock();
2562− lr = get_last_request();
2563− if (lr && !lr->processed) {
2564− memcpy(alpha2, lr->alpha2, 2);
2565− add = true;
2566− }
2567− rcu_read_unlock();
2568−
2569− if (add)
2570− return add_uevent_var(env, "COUNTRY=%c%c",
2571− alpha2[0], alpha2[1]);
2572− return 0;
2573−}
2574−
25752575 void wiphy_regulatory_register(struct wiphy *wiphy)
25762576 {
25772577 struct regulatory_request *lr;
@@ -2622,8 +2622,6 @@ int __init regulatory_init(void) · 44 unmodified lines
26222622 if (IS_ERR(reg_pdev))
26232623 return PTR_ERR(reg_pdev);
26242624
2625− reg_pdev->dev.type = &reg_device_type;
2626−
26272625 spin_lock_init(&reg_requests_lock);
26282626 spin_lock_init(&reg_pending_beacons_lock);
26292627
net/wireless/reg.h+0−1
@@ -26,7 +26,6 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy); · 25 unmodified lines
2626 int regulatory_hint_user(const char *alpha2,
2727 enum nl80211_user_reg_hint_type user_reg_hint_type);
2828
29−int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env);
3029 void wiphy_regulatory_register(struct wiphy *wiphy);
3130 void wiphy_regulatory_deregister(struct wiphy *wiphy);
3231
net/wireless/scan.c+19−12
@@ -659,9 +659,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, · 658 unmodified lines
659659 continue;
660660 if (ssidlen && ie[1] != ssidlen)
661661 continue;
662− /* that would be odd ... */
663− if (bss->pub.beacon_ies)
664− continue;
665662 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
666663 continue;
667664 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
@@ -680,7 +677,8 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev, · 12 unmodified lines
680677 /* Returned bss is reference counted and must be cleaned up appropriately. */
681678 static struct cfg80211_internal_bss *
682679 cfg80211_bss_update(struct cfg80211_registered_device *dev,
683− struct cfg80211_internal_bss *tmp)
680+ struct cfg80211_internal_bss *tmp,
681+ bool signal_valid)
684682 {
685683 struct cfg80211_internal_bss *found = NULL;
686684
@@ -765,7 +763,12 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, · 78 unmodified lines
765763 }
766764
767765 found->pub.beacon_interval = tmp->pub.beacon_interval;
768− found->pub.signal = tmp->pub.signal;
766+ /*
767+ * don't update the signal if beacon was heard on
768+ * adjacent channel.
769+ */
770+ if (signal_valid)
771+ found->pub.signal = tmp->pub.signal;
769772 found->pub.capability = tmp->pub.capability;
770773 found->ts = tmp->ts;
771774 } else {
@@ -869,13 +872,14 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, · 97 unmodified lines
869872 /* Returned bss is reference counted and must be cleaned up appropriately. */
870873 struct cfg80211_bss*
871874 cfg80211_inform_bss_width(struct wiphy *wiphy,
872− struct ieee80211_channel *channel,
875+ struct ieee80211_channel *rx_channel,
873876 enum nl80211_bss_scan_width scan_width,
874877 const u8 *bssid, u64 tsf, u16 capability,
875878 u16 beacon_interval, const u8 *ie, size_t ielen,
876879 s32 signal, gfp_t gfp)
877880 {
878881 struct cfg80211_bss_ies *ies;
882+ struct ieee80211_channel *channel;
879883 struct cfg80211_internal_bss tmp = {}, *res;
880884
881885 if (WARN_ON(!wiphy))
@@ -885,7 +889,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, · 3 unmodified lines
885889 (signal < 0 || signal > 100)))
886890 return NULL;
887891
888− channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
892+ channel = cfg80211_get_bss_channel(wiphy, ie, ielen, rx_channel);
889893 if (!channel)
890894 return NULL;
891895
@@ -913,7 +917,8 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, · 21 unmodified lines
913917 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
914918 rcu_assign_pointer(tmp.pub.ies, ies);
915919
916− res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
920+ res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
921+ rx_channel == channel);
917922 if (!res)
918923 return NULL;
919924
@@ -929,20 +934,21 @@ EXPORT_SYMBOL(cfg80211_inform_bss_width); · 9 unmodified lines
929934 /* Returned bss is reference counted and must be cleaned up appropriately. */
930935 struct cfg80211_bss *
931936 cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
932− struct ieee80211_channel *channel,
937+ struct ieee80211_channel *rx_channel,
933938 enum nl80211_bss_scan_width scan_width,
934939 struct ieee80211_mgmt *mgmt, size_t len,
935940 s32 signal, gfp_t gfp)
936941 {
937942 struct cfg80211_internal_bss tmp = {}, *res;
938943 struct cfg80211_bss_ies *ies;
944+ struct ieee80211_channel *channel;
939945 size_t ielen = len - offsetof(struct ieee80211_mgmt,
940946 u.probe_resp.variable);
941947
942948 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
943949 offsetof(struct ieee80211_mgmt, u.beacon.variable));
944950
945− trace_cfg80211_inform_bss_width_frame(wiphy, channel, scan_width, mgmt,
951+ trace_cfg80211_inform_bss_width_frame(wiphy, rx_channel, scan_width, mgmt,
946952 len, signal);
947953
948954 if (WARN_ON(!mgmt))
@@ -959,7 +965,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, · 10 unmodified lines
959965 return NULL;
960966
961967 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
962− ielen, channel);
968+ ielen, rx_channel);
963969 if (!channel)
964970 return NULL;
965971
@@ -983,7 +989,8 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, · 17 unmodified lines
983989 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
984990 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
985991
986− res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
992+ res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
993+ rx_channel == channel);
987994 if (!res)
988995 return NULL;
989996
net/wireless/sme.c+0−1
@@ -64,7 +64,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) · 63 unmodified lines
6464 int n_channels, err;
6565
6666 ASSERT_RTNL();
67− ASSERT_RDEV_LOCK(rdev);
6867 ASSERT_WDEV_LOCK(wdev);
6968
7069 if (rdev->scan_req || rdev->scan_msg)
net/wireless/util.c+2−3
@@ -838,7 +838,6 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) · 837 unmodified lines
838838 struct wireless_dev *wdev;
839839
840840 ASSERT_RTNL();
841− ASSERT_RDEV_LOCK(rdev);
842841
843842 list_for_each_entry(wdev, &rdev->wdev_list, list)
844843 cfg80211_process_wdev_events(wdev);
@@ -851,7 +850,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, · 6 unmodified lines
851850 int err;
852851 enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
853852
854− ASSERT_RDEV_LOCK(rdev);
853+ ASSERT_RTNL();
855854
856855 /* don't support changing VLANs, you just re-create them */
857856 if (otype == NL80211_IFTYPE_AP_VLAN)
@@ -886,7 +885,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, · 28 unmodified lines
886885
887886 switch (otype) {
888887 case NL80211_IFTYPE_AP:
889− cfg80211_stop_ap(rdev, dev);
888+ cfg80211_stop_ap(rdev, dev, true);
890889 break;
891890 case NL80211_IFTYPE_ADHOC:
892891 cfg80211_leave_ibss(rdev, dev, false);
net/wireless/wext-sme.c+1−1
@@ -21,7 +21,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, · 20 unmodified lines
2121 const u8 *prev_bssid = NULL;
2222 int err, i;
2323
24− ASSERT_RDEV_LOCK(rdev);
24+ ASSERT_RTNL();
2525 ASSERT_WDEV_LOCK(wdev);
2626
2727 if (!netif_running(wdev->netdev))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t