summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2020-12-12 10:07:56 -0800
committerJakub Kicinski <kuba@kernel.org>2020-12-12 10:07:56 -0800
commit00f7763a26cbf6673bceca7d69f931df31e48144 (patch)
tree7806e38b5bb27b3c950a1d283ecef83bab798321
parent46d5e62dd3c34770f3bfd0642daa9a7772a00362 (diff)
parentc534e093d865d926d042e0a3f228d1152627ccab (diff)
downloadlinux-00f7763a26cbf6673bceca7d69f931df31e48144.tar.gz
linux-00f7763a26cbf6673bceca7d69f931df31e48144.tar.bz2
linux-00f7763a26cbf6673bceca7d69f931df31e48144.zip
Merge tag 'mac80211-next-for-net-next-2020-12-11' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says: ==================== A new set of wireless changes: * validate key indices for key deletion * more preamble support in mac80211 * various 6 GHz scan fixes/improvements * a common SAR power limitations API * various small fixes & code improvements * tag 'mac80211-next-for-net-next-2020-12-11' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next: (35 commits) mac80211: add ieee80211_set_sar_specs nl80211: add common API to configure SAR power limitations mac80211: fix a mistake check for rx_stats update mac80211: mlme: save ssid info to ieee80211_bss_conf while assoc mac80211: Update rate control on channel change mac80211: don't filter out beacons once we start CSA mac80211: Fix calculation of minimal channel width mac80211: ignore country element TX power on 6 GHz mac80211: use bitfield helpers for BA session action frames mac80211: support Rx timestamp calculation for all preamble types mac80211: don't set set TDLS STA bandwidth wider than possible mac80211: support driver-based disconnect with reconnect hint cfg80211: support immediate reconnect request hint mac80211: use struct assignment for he_obss_pd cfg80211: remove struct ieee80211_he_bss_color nl80211: validate key indexes for cfg80211_registered_device cfg80211: include block-tx flag in channel switch started event mac80211: disallow band-switch during CSA ieee80211: update reduced neighbor report TBTT info length cfg80211: Save the regulatory domain when setting custom regulatory ... ==================== Link: https://lore.kernel.org/r/20201211142552.209018-1-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--include/linux/ieee80211.h9
-rw-r--r--include/linux/rfkill.h24
-rw-r--r--include/net/cfg80211.h75
-rw-r--r--include/net/mac80211.h35
-rw-r--r--include/uapi/linux/nl80211.h114
-rw-r--r--include/uapi/linux/rfkill.h16
-rw-r--r--net/mac80211/agg-rx.c8
-rw-r--r--net/mac80211/agg-tx.c12
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/chan.c71
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/debugfs_key.c2
-rw-r--r--net/mac80211/debugfs_netdev.c6
-rw-r--r--net/mac80211/debugfs_sta.c2
-rw-r--r--net/mac80211/ieee80211_i.h14
-rw-r--r--net/mac80211/key.c49
-rw-r--r--net/mac80211/mlme.c123
-rw-r--r--net/mac80211/rx.c20
-rw-r--r--net/mac80211/trace.h23
-rw-r--r--net/mac80211/tx.c16
-rw-r--r--net/mac80211/util.c66
-rw-r--r--net/mac80211/vht.c14
-rw-r--r--net/rfkill/core.c41
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mlme.c26
-rw-r--r--net/wireless/nl80211.c239
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/rdev-ops.h12
-rw-r--r--net/wireless/reg.c10
-rw-r--r--net/wireless/scan.c21
-rw-r--r--net/wireless/trace.h31
-rw-r--r--net/wireless/util.c52
-rw-r--r--net/wireless/wext-compat.c103
33 files changed, 1041 insertions, 227 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 5e8cc9c3d45a..72ff75fb1971 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1261,6 +1261,7 @@ struct ieee80211_mgmt {
#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
#define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122
+#define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123
/* mgmt header + 1 byte category code */
#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
@@ -3835,15 +3836,15 @@ static inline bool for_each_element_completed(const struct element *element,
#define WLAN_RSNX_CAPA_SAE_H2E BIT(5)
/*
- * reduced neighbor report, based on Draft P802.11ax_D5.0,
- * section 9.4.2.170
+ * reduced neighbor report, based on Draft P802.11ax_D6.1,
+ * section 9.4.2.170 and accepted contributions.
*/
#define IEEE80211_AP_INFO_TBTT_HDR_TYPE 0x03
#define IEEE80211_AP_INFO_TBTT_HDR_FILTERED 0x04
#define IEEE80211_AP_INFO_TBTT_HDR_COLOC 0x08
#define IEEE80211_AP_INFO_TBTT_HDR_COUNT 0xF0
-#define IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM 8
-#define IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM 12
+#define IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM 9
+#define IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM 13
#define IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED 0x01
#define IEEE80211_RNR_TBTT_PARAMS_SAME_SSID 0x02
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 8ad2487a86d5..231e06b74b50 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -138,6 +138,17 @@ void rfkill_unregister(struct rfkill *rfkill);
void rfkill_destroy(struct rfkill *rfkill);
/**
+ * rfkill_set_hw_state_reason - Set the internal rfkill hardware block state
+ * with a reason
+ * @rfkill: pointer to the rfkill class to modify.
+ * @blocked: the current hardware block state to set
+ * @reason: one of &enum rfkill_hard_block_reasons
+ *
+ * Prefer to use rfkill_set_hw_state if you don't need any special reason.
+ */
+bool rfkill_set_hw_state_reason(struct rfkill *rfkill,
+ bool blocked, unsigned long reason);
+/**
* rfkill_set_hw_state - Set the internal rfkill hardware block state
* @rfkill: pointer to the rfkill class to modify.
* @blocked: the current hardware block state to set
@@ -156,7 +167,11 @@ void rfkill_destroy(struct rfkill *rfkill);
* should be blocked) so that drivers need not keep track of the soft
* block state -- which they might not be able to.
*/
-bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
+static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
+{
+ return rfkill_set_hw_state_reason(rfkill, blocked,
+ RFKILL_HARD_BLOCK_SIGNAL);
+}
/**
* rfkill_set_sw_state - Set the internal rfkill software block state
@@ -256,6 +271,13 @@ static inline void rfkill_destroy(struct rfkill *rfkill)
{
}
+static inline bool rfkill_set_hw_state_reason(struct rfkill *rfkill,
+ bool blocked,
+ unsigned long reason)
+{
+ return blocked;
+}
+
static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
{
return blocked;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 78c763dfc99a..9a4bbccddc7f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -303,19 +303,6 @@ struct cfg80211_he_bss_color {
};
/**
- * struct ieee80211_he_bss_color - AP settings for BSS coloring
- *
- * @color: the current color.
- * @disabled: is the feature disabled.
- * @partial: define the AID equation.
- */
-struct ieee80211_he_bss_color {
- u8 color;
- bool disabled;
- bool partial;
-};
-
-/**
* struct ieee80211_sta_ht_cap - STA's HT capabilities
*
* This structure describes most essential parameters needed
@@ -1187,6 +1174,7 @@ enum cfg80211_ap_settings_flags {
* @vht_required: stations must support VHT
* @twt_responder: Enable Target Wait Time
* @he_required: stations must support HE
+ * @sae_h2e_required: stations must support direct H2E technique in SAE
* @flags: flags, as defined in enum cfg80211_ap_settings_flags
* @he_obss_pd: OBSS Packet Detection settings
* @he_bss_color: BSS Color settings
@@ -1218,7 +1206,7 @@ struct cfg80211_ap_settings {
const struct ieee80211_vht_cap *vht_cap;
const struct ieee80211_he_cap_elem *he_cap;
const struct ieee80211_he_operation *he_oper;
- bool ht_required, vht_required, he_required;
+ bool ht_required, vht_required, he_required, sae_h2e_required;
bool twt_responder;
u32 flags;
struct ieee80211_he_obss_pd he_obss_pd;
@@ -1744,6 +1732,54 @@ struct station_info {
u8 connected_to_as;
};
+/**
+ * struct cfg80211_sar_sub_specs - sub specs limit
+ * @power: power limitation in 0.25dbm
+ * @freq_range_index: index the power limitation applies to
+ */
+struct cfg80211_sar_sub_specs {
+ s32 power;
+ u32 freq_range_index;
+};
+
+/**
+ * struct cfg80211_sar_specs - sar limit specs
+ * @type: it's set with power in 0.25dbm or other types
+ * @num_sub_specs: number of sar sub specs
+ * @sub_specs: memory to hold the sar sub specs
+ */
+struct cfg80211_sar_specs {
+ enum nl80211_sar_type type;
+ u32 num_sub_specs;
+ struct cfg80211_sar_sub_specs sub_specs[];
+};
+
+
+/**
+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges
+ * @start_freq: start range edge frequency
+ * @end_freq: end range edge frequency
+ */
+struct cfg80211_sar_freq_ranges {
+ u32 start_freq;
+ u32 end_freq;
+};
+
+/**
+ * struct cfg80211_sar_capa - sar limit capability
+ * @type: it's set via power in 0.25dbm or other types
+ * @num_freq_ranges: number of frequency ranges
+ * @freq_ranges: memory to hold the freq ranges.
+ *
+ * Note: WLAN driver may append new ranges or split an existing
+ * range to small ones and then append them.
+ */
+struct cfg80211_sar_capa {
+ enum nl80211_sar_type type;
+ u32 num_freq_ranges;
+ const struct cfg80211_sar_freq_ranges *freq_ranges;
+};
+
#if IS_ENABLED(CONFIG_CFG80211)
/**
* cfg80211_get_station - retrieve information about a given station
@@ -4261,6 +4297,8 @@ struct cfg80211_ops {
struct cfg80211_tid_config *tid_conf);
int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u8 tids);
+ int (*set_sar_specs)(struct wiphy *wiphy,
+ struct cfg80211_sar_specs *sar);
};
/*
@@ -5029,6 +5067,8 @@ struct wiphy {
u8 max_data_retry_count;
+ const struct cfg80211_sar_capa *sar_capa;
+
char priv[] __aligned(NETDEV_ALIGN);
};
@@ -6418,13 +6458,15 @@ void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
* @dev: network device
* @buf: 802.11 frame (header + body)
* @len: length of the frame data
+ * @reconnect: immediate reconnect is desired (include the nl80211 attribute)
*
* This function is called whenever deauthentication has been processed in
* station mode. This includes both received deauthentication frames and
* locally generated ones. This function may sleep. The caller must hold the
* corresponding wdev's mutex.
*/
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
+ bool reconnect);
/**
* cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame
@@ -7531,6 +7573,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
* @dev: the device on which the channel switch started
* @chandef: the future channel definition
* @count: the number of TBTTs until the channel switch happens
+ * @quiet: whether or not immediate quiet was requested by the AP
*
* Inform the userspace about the channel switch that has just
* started, so that it can take appropriate actions (eg. starting
@@ -7538,7 +7581,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
*/
void cfg80211_ch_switch_started_notify(struct net_device *dev,
struct cfg80211_chan_def *chandef,
- u8 count);
+ u8 count, bool quiet);
/**
* ieee80211_operating_class_to_band - convert operating class to band
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 05c7524bab26..d315740581f1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -635,9 +635,7 @@ struct ieee80211_fils_discovery {
struct ieee80211_bss_conf {
const u8 *bssid;
u8 htc_trig_based_pkt_ext;
- bool multi_sta_back_32bit;
bool uora_exists;
- bool ack_enabled;
u8 uora_ocw_range;
u16 frame_time_rts_th;
bool he_support;
@@ -4197,6 +4195,8 @@ struct ieee80211_ops {
struct ieee80211_vif *vif);
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enabled);
+ int (*set_sar_specs)(struct ieee80211_hw *hw,
+ const struct cfg80211_sar_specs *sar);
};
/**
@@ -5324,6 +5324,26 @@ void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
const u8 *replay_ctr, gfp_t gfp);
/**
+ * ieee80211_key_mic_failure - increment MIC failure counter for the key
+ *
+ * Note: this is really only safe if no other RX function is called
+ * at the same time.
+ *
+ * @keyconf: the key in question
+ */
+void ieee80211_key_mic_failure(struct ieee80211_key_conf *keyconf);
+
+/**
+ * ieee80211_key_replay - increment replay counter for the key
+ *
+ * Note: this is really only safe if no other RX function is called
+ * at the same time.
+ *
+ * @keyconf: the key in question
+ */
+void ieee80211_key_replay(struct ieee80211_key_conf *keyconf);
+
+/**
* ieee80211_wake_queue - wake specific queue
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @queue: queue number (counted from zero).
@@ -5882,6 +5902,17 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
void ieee80211_connection_loss(struct ieee80211_vif *vif);
/**
+ * ieee80211_disconnect - request disconnection
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @reconnect: immediate reconnect is desired
+ *
+ * Request disconnection from the current network and, if enabled, send a
+ * hint to the higher layers that immediate reconnect is desired.
+ */
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect);
+
+/**
* ieee80211_resume_disconnect - disconnect from AP after resume
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 3e0d4a038ab6..40832d13c2f1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1178,6 +1178,10 @@
* includes the contents of the frame. %NL80211_ATTR_ACK flag is included
* if the recipient acknowledged the frame.
*
+ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
+ * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
+ * specify the wiphy index to be applied to.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1408,6 +1412,8 @@ enum nl80211_commands {
NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
+ NL80211_CMD_SET_SAR_SPECS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2079,7 +2085,8 @@ enum nl80211_commands {
* until the channel switch event.
* @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
* must be blocked on the current channel (before the channel switch
- * operation).
+ * operation). Also included in the channel switch started event if quiet
+ * was requested by the AP.
* @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
* for the time while performing a channel switch.
* @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
@@ -2534,6 +2541,15 @@ enum nl80211_commands {
* This is a u8 attribute that encapsulates one of the values from
* &enum nl80211_sae_pwe_mechanism.
*
+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
+ * used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
+ * of %nl80211_sar_attrs which specifies the sar type and related
+ * sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
+ *
+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
+ * disassoc events to indicate that an immediate reconnect to the AP
+ * is desired.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3025,6 +3041,10 @@ enum nl80211_attrs {
NL80211_ATTR_SAE_PWE,
+ NL80211_ATTR_RECONNECT_REQUESTED,
+
+ NL80211_ATTR_SAR_SPEC,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -7156,4 +7176,96 @@ enum nl80211_sae_pwe_mechanism {
NL80211_SAE_PWE_HASH_TO_ELEMENT,
NL80211_SAE_PWE_BOTH,
};
+
+/**
+ * enum nl80211_sar_type - type of SAR specs
+ *
+ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
+ *
+ */
+enum nl80211_sar_type {
+ NL80211_SAR_TYPE_POWER,
+
+ /* add new type here */
+
+ /* Keep last */
+ NUM_NL80211_SAR_TYPE,
+};
+
+/**
+ * enum nl80211_sar_attrs - Attributes for SAR spec
+ *
+ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
+ *
+ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
+ * limit specifications. Each specification contains a set
+ * of %nl80211_sar_specs_attrs.
+ *
+ * For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER
+ * and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX.
+ *
+ * For sar_capa dump, it contains array of
+ * %NL80211_SAR_ATTR_SPECS_START_FREQ
+ * and %NL80211_SAR_ATTR_SPECS_END_FREQ.
+ *
+ * @__NL80211_SAR_ATTR_LAST: Internal
+ * @NL80211_SAR_ATTR_MAX: highest sar attribute
+ *
+ * These attributes are used with %NL80211_CMD_SET_SAR_SPEC
+ */
+enum nl80211_sar_attrs {
+ __NL80211_SAR_ATTR_INVALID,
+
+ NL80211_SAR_ATTR_TYPE,
+ NL80211_SAR_ATTR_SPECS,
+
+ __NL80211_SAR_ATTR_LAST,
+ NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1,
+};
+
+/**
+ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
+ *
+ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
+ * power limit value in units of 0.25 dBm if type is
+ * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
+ * 0 means userspace doesn't have SAR limitation on this associated range.
+ *
+ * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the
+ * index of exported freq range table and the associated power limitation
+ * is applied to this range.
+ *
+ * Userspace isn't required to set all the ranges advertised by WLAN driver,
+ * and userspace can skip some certain ranges. These skipped ranges don't
+ * have SAR limitations, and they are same as setting the
+ * %NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any
+ * value higher than regulatory allowed value just means SAR power
+ * limitation is removed, but it's required to set at least one range.
+ * It's not allowed to set duplicated range in one SET operation.
+ *
+ * Every SET operation overwrites previous SET operation.
+ *
+ * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start
+ * frequency of this range edge when registering SAR capability to wiphy.
+ * It's not a channel center frequency. The unit is kHz.
+ *
+ * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end
+ * frequency of this range edge when registering SAR capability to wiphy.
+ * It's not a channel center frequency. The unit is kHz.
+ *
+ * @__NL80211_SAR_ATTR_SPECS_LAST: Internal
+ * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute
+ */
+enum nl80211_sar_specs_attrs {
+ __NL80211_SAR_ATTR_SPECS_INVALID,
+
+ NL80211_SAR_ATTR_SPECS_POWER,
+ NL80211_SAR_ATTR_SPECS_RANGE_INDEX,
+ NL80211_SAR_ATTR_SPECS_START_FREQ,
+ NL80211_SAR_ATTR_SPECS_END_FREQ,
+
+ __NL80211_SAR_ATTR_SPECS_LAST,
+ NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/include/uapi/linux/rfkill.h b/include/uapi/linux/rfkill.h
index 2e00dcebebd0..03e8af87b364 100644
--- a/include/uapi/linux/rfkill.h
+++ b/include/uapi/linux/rfkill.h
@@ -70,12 +70,24 @@ enum rfkill_operation {
};
/**
+ * enum rfkill_hard_block_reasons - hard block reasons
+ * @RFKILL_HARD_BLOCK_SIGNAL: the hardware rfkill signal is active
+ * @RFKILL_HARD_BLOCK_NOT_OWNER: the NIC is not owned by the host
+ */
+enum rfkill_hard_block_reasons {
+ RFKILL_HARD_BLOCK_SIGNAL = 1 << 0,
+ RFKILL_HARD_BLOCK_NOT_OWNER = 1 << 1,
+};
+
+/**
* struct rfkill_event - events for userspace on /dev/rfkill
* @idx: index of dev rfkill
* @type: type of the rfkill struct
* @op: operation code
* @hard: hard state (0/1)
* @soft: soft state (0/1)
+ * @hard_block_reasons: valid if hard is set. One or several reasons from
+ * &enum rfkill_hard_block_reasons.
*
* Structure used for userspace communication on /dev/rfkill,
* used for events from the kernel and control to the kernel.
@@ -84,7 +96,9 @@ struct rfkill_event {
__u32 idx;
__u8 type;
__u8 op;
- __u8 soft, hard;
+ __u8 soft;
+ __u8 hard;
+ __u8 hard_block_reasons;
} __attribute__((packed));
/*
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index cd4cf84a7f99..cce28e3b2232 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -250,10 +250,10 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
- capab = (u16)(amsdu << 0); /* bit 0 A-MSDU support */
- capab |= (u16)(policy << 1); /* bit 1 aggregation policy */
- capab |= (u16)(tid << 2); /* bit 5:2 TID number */
- capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
+ capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
+ capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
+ capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
+ capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index b37c8a983d88..430a58587538 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -95,10 +95,10 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
mgmt->u.action.u.addba_req.dialog_token = dialog_token;
- capab = (u16)(1 << 0); /* bit 0 A-MSDU support */
- capab |= (u16)(1 << 1); /* bit 1 aggregation policy */
- capab |= (u16)(tid << 2); /* bit 5:2 TID number */
- capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
+ capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK;
+ capab |= IEEE80211_ADDBA_PARAM_POLICY_MASK;
+ capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
+ capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
@@ -950,8 +950,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
- tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
- buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
+ tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK);
+ buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
txq = sta->sta.txq[tid];
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 454432ced0c9..c4c70e30ad7f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -405,6 +405,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
case WLAN_CIPHER_SUITE_WEP104:
if (WARN_ON_ONCE(fips_enabled))
return -EINVAL;
+ break;
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_CCMP_256:
case WLAN_CIPHER_SUITE_AES_CMAC:
@@ -1121,10 +1122,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata->vif.bss_conf.enable_beacon = true;
sdata->vif.bss_conf.allow_p2p_go_ps = sdata->vif.p2p;
sdata->vif.bss_conf.twt_responder = params->twt_responder;
- memcpy(&sdata->vif.bss_conf.he_obss_pd, &params->he_obss_pd,
- sizeof(struct ieee80211_he_obss_pd));
- memcpy(&sdata->vif.bss_conf.he_bss_color, &params->he_bss_color,
- sizeof(struct ieee80211_he_bss_color));
+ sdata->vif.bss_conf.he_obss_pd = params->he_obss_pd;
+ sdata->vif.bss_conf.he_bss_color = params->he_bss_color;
sdata->vif.bss_conf.s1g = params->chandef.chan->band ==
NL80211_BAND_S1GHZ;
@@ -3297,6 +3296,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
if (cfg80211_get_chandef_type(&params->chandef) !=
cfg80211_get_chandef_type(&sdata->u.ibss.chandef))
return -EINVAL;
+ break;
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_20_NOHT:
@@ -3448,7 +3448,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
IEEE80211_QUEUE_STOP_REASON_CSA);
cfg80211_ch_switch_started_notify(sdata->dev, &sdata->csa_chandef,
- params->count);
+ params->count, params->block_tx);
if (changed) {
ieee80211_bss_info_change_notify(sdata, changed);
@@ -4073,6 +4073,17 @@ static int ieee80211_reset_tid_config(struct wiphy *wiphy,
return ret;
}
+static int ieee80211_set_sar_specs(struct wiphy *wiphy,
+ struct cfg80211_sar_specs *sar)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+
+ if (!local->ops->set_sar_specs)
+ return -EOPNOTSUPP;
+
+ return local->ops->set_sar_specs(&local->hw, sar);
+}
+
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -4175,4 +4186,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.probe_mesh_link = ieee80211_probe_mesh_link,
.set_tid_config = ieee80211_set_tid_config,
.reset_tid_config = ieee80211_reset_tid_config,
+ .set_sar_specs = ieee80211_set_sar_specs,
};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index b6c80a45b9f5..907bb1f748a1 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -9,6 +9,7 @@
#include <net/cfg80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
+#include "rate.h"
static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
struct ieee80211_chanctx *ctx)
@@ -191,11 +192,13 @@ ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
return NULL;
}
-enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
+static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta)
{
- switch (sta->bandwidth) {
+ enum ieee80211_sta_rx_bandwidth width = ieee80211_sta_cap_rx_bw(sta);
+
+ switch (width) {
case IEEE80211_STA_RX_BW_20:
- if (sta->ht_cap.ht_supported)
+ if (sta->sta.ht_cap.ht_supported)
return NL80211_CHAN_WIDTH_20;
else
return NL80211_CHAN_WIDTH_20_NOHT;
@@ -232,7 +235,7 @@ ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
!(sta->sdata->bss && sta->sdata->bss == sdata->bss))
continue;
- max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
+ max_bw = max(max_bw, ieee80211_get_sta_bw(sta));
}
rcu_read_unlock();
@@ -343,10 +346,42 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
}
+static void ieee80211_chan_bw_change(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx)
+{
+ struct sta_info *sta;
+ struct ieee80211_supported_band *sband =
+ local->hw.wiphy->bands[ctx->conf.def.chan->band];
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sta, &local->sta_list,
+ list) {
+ enum ieee80211_sta_rx_bandwidth new_sta_bw;
+
+ if (!ieee80211_sdata_running(sta->sdata))
+ continue;
+
+ if (rcu_access_pointer(sta->sdata->vif.chanctx_conf) !=
+ &ctx->conf)
+ continue;
+
+ new_sta_bw = ieee80211_sta_cur_vht_bw(sta);
+ if (new_sta_bw == sta->sta.bandwidth)
+ continue;
+
+ sta->sta.bandwidth = new_sta_bw;
+ rate_control_rate_update(local, sband, sta,
+ IEEE80211_RC_BW_CHANGED);
+ }
+ rcu_read_unlock();
+}
+
static void ieee80211_change_chanctx(struct ieee80211_local *local,
struct ieee80211_chanctx *ctx,
const struct cfg80211_chan_def *chandef)
{
+ enum nl80211_chan_width width;
+
if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
ieee80211_recalc_chanctx_min_def(local, ctx);
return;
@@ -354,7 +389,25 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+ width = ctx->conf.def.width;
ctx->conf.def = *chandef;
+
+ /* expected to handle only 20/40/80/160 channel widths */
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ case NL80211_CHAN_WIDTH_40:
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_80P80:
+ case NL80211_CHAN_WIDTH_160:
+ break;
+ default:
+ WARN_ON(1);
+ }
+
+ if (chandef->width < width)
+ ieee80211_chan_bw_change(local, ctx);
+
drv_change_chanctx(local, ctx, IEEE80211