mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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>
This commit is contained in:
commit
00f7763a26
33 files changed
+1041
-227
No files matched your search
@@ -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
|
||||
|
||||
+23
-1
@@ -137,6 +137,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.
|
||||
@@ -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;
|
||||
|
||||
+59
-16
@@ -302,19 +302,6 @@ struct cfg80211_he_bss_color {
|
||||
bool partial;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
@@ -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
|
||||
|
||||
+33
-2
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -5323,6 +5323,26 @@ ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
|
||||
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().
|
||||
@@ -5881,6 +5901,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
|
||||
*
|
||||
|
||||
@@ -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 */
|
||||
@@ -69,6 +69,16 @@ enum rfkill_operation {
|
||||
RFKILL_OP_CHANGE_ALL,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -76,6 +86,8 @@ enum rfkill_operation {
|
||||
* @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));
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
+17
-5
@@ -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, ¶ms->he_obss_pd,
|
||||
sizeof(struct ieee80211_he_obss_pd));
|
||||
memcpy(&sdata->vif.bss_conf.he_bss_color, ¶ms->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(¶ms->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,
|
||||
};
|
||||
+67
-4
@@ -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_CHANCTX_CHANGE_WIDTH);
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
|
||||
@@ -362,6 +415,9 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
|
||||
local->_oper_chandef = *chandef;
|
||||
ieee80211_hw_config(local, 0);
|
||||
}
|
||||
|
||||
if (chandef->width > width)
|
||||
ieee80211_chan_bw_change(local, ctx);
|
||||
}
|
||||
|
||||
static struct ieee80211_chanctx *
|
||||
@@ -1051,8 +1107,14 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
|
||||
if (WARN_ON(!chandef))
|
||||
return -EINVAL;
|
||||
|
||||
if (old_ctx->conf.def.width > new_ctx->conf.def.width)
|
||||
ieee80211_chan_bw_change(local, new_ctx);
|
||||
|
||||
ieee80211_change_chanctx(local, new_ctx, chandef);
|
||||
|
||||
if (old_ctx->conf.def.width < new_ctx->conf.def.width)
|
||||
ieee80211_chan_bw_change(local, new_ctx);
|
||||
|
||||
vif_chsw[0].vif = &sdata->vif;
|
||||
vif_chsw[0].old_ctx = &old_ctx->conf;
|
||||
vif_chsw[0].new_ctx = &new_ctx->conf;
|
||||
@@ -1443,6 +1505,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
|
||||
ieee80211_recalc_smps_chanctx(local, ctx);
|
||||
ieee80211_recalc_radar_chanctx(local, ctx);
|
||||
ieee80211_recalc_chanctx_min_def(local, ctx);
|
||||
ieee80211_chan_bw_change(local, ctx);
|
||||
|
||||
list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
|
||||
reserved_chanctx_list) {
|
||||
|
||||
@@ -53,7 +53,7 @@ static const struct file_operations name## _ops = { \
|
||||
DEBUGFS_READONLY_FILE_OPS(name)
|
||||
|
||||
#define DEBUGFS_ADD(name) \
|
||||
debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
|
||||
debugfs_create_file(#name, 0400, phyd, local, &name## _ops)
|
||||
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
debugfs_create_file(#name, mode, phyd, local, &name## _ops);
|
||||
|
||||
@@ -319,7 +319,7 @@ KEY_OPS(key);
|
||||
|
||||
#define DEBUGFS_ADD(name) \
|
||||
debugfs_create_file(#name, 0400, key->debugfs.dir, \
|
||||
key, &key_##name##_ops);
|
||||
key, &key_##name##_ops)
|
||||
#define DEBUGFS_ADD_W(name) \
|
||||
debugfs_create_file(#name, 0600, key->debugfs.dir, \
|
||||
key, &key_##name##_ops);
|
||||
|
||||
@@ -642,7 +642,7 @@ IEEE80211_IF_FILE(dot11MeshConnectedToAuthServer,
|
||||
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
|
||||
sdata, &name##_ops);
|
||||
sdata, &name##_ops)
|
||||
|
||||
#define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
|
||||
|
||||
@@ -711,7 +711,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
||||
struct dentry *dir = debugfs_create_dir("mesh_stats",
|
||||
sdata->vif.debugfs_dir);
|
||||
#define MESHSTATS_ADD(name)\
|
||||
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
|
||||
debugfs_create_file(#name, 0400, dir, sdata, &name##_ops)
|
||||
|
||||
MESHSTATS_ADD(fwded_mcast);
|
||||
MESHSTATS_ADD(fwded_unicast);
|
||||
@@ -728,7 +728,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
||||
sdata->vif.debugfs_dir);
|
||||
|
||||
#define MESHPARAMS_ADD(name) \
|
||||
debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
|
||||
debugfs_create_file(#name, 0600, dir, sdata, &name##_ops)
|
||||
|
||||
MESHPARAMS_ADD(dot11MeshMaxRetries);
|
||||
MESHPARAMS_ADD(dot11MeshRetryTimeout);
|
||||
|
||||
@@ -985,7 +985,7 @@ STA_OPS(he_capa);
|
||||
|
||||
#define DEBUGFS_ADD(name) \
|
||||
debugfs_create_file(#name, 0400, \
|
||||
sta->debugfs_dir, sta, &sta_ ##name## _ops);
|
||||
sta->debugfs_dir, sta, &sta_ ##name## _ops)
|
||||
|
||||
#define DEBUGFS_ADD_COUNTER(name, field) \
|
||||
debugfs_create_ulong(#name, 0400, sta->debugfs_dir, &sta->field);
|
||||
|
||||
@@ -452,7 +452,9 @@ struct ieee80211_if_managed {
|
||||
unsigned long probe_timeout;
|
||||
int probe_send_count;
|
||||
bool nullfunc_failed;
|
||||
bool connection_loss;
|
||||
u8 connection_loss:1,
|
||||
driver_disconnect:1,
|
||||
reconnect:1;
|
||||
|
||||
struct cfg80211_bss *associated;
|
||||
struct ieee80211_mgd_auth_data *auth_data;
|
||||
@@ -1587,13 +1589,8 @@ ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
|
||||
{
|
||||
WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START &&
|
||||
status->flag & RX_FLAG_MACTIME_END);
|
||||
if (status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END))
|
||||
return true;
|
||||
/* can't handle non-legacy preamble yet */
|
||||
if (status->flag & RX_FLAG_MACTIME_PLCP_START &&
|
||||
status->encoding == RX_ENC_LEGACY)
|
||||
return true;
|
||||
return false;
|
||||
return !!(status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END |
|
||||
RX_FLAG_MACTIME_PLCP_START));
|
||||
}
|
||||
|
||||
void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata);
|
||||
@@ -2280,7 +2277,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
|
||||
enum ieee80211_chanctx_mode chanmode,
|
||||
u8 radar_detect);
|
||||
int ieee80211_max_num_channels(struct ieee80211_local *local);
|
||||
enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta);
|
||||
void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
|
||||
struct ieee80211_chanctx *ctx);
|
||||
|
||||
|
||||
@@ -1300,3 +1300,52 @@ ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
|
||||
return &key->conf;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_add);
|
||||
|
||||
void ieee80211_key_mic_failure(struct ieee80211_key_conf *keyconf)
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
|
||||
key = container_of(keyconf, struct ieee80211_key, conf);
|
||||
|
||||
switch (key->conf.cipher) {
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
||||
key->u.aes_cmac.icverrors++;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||
key->u.aes_gmac.icverrors++;
|
||||
break;
|
||||
default:
|
||||
/* ignore the others for now, we don't keep counters now */
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_key_mic_failure);
|
||||
|
||||
void ieee80211_key_replay(struct ieee80211_key_conf *keyconf)
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
|
||||
key = container_of(keyconf, struct ieee80211_key, conf);
|
||||
|
||||
switch (key->conf.cipher) {
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||
key->u.ccmp.replays++;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
||||
key->u.aes_cmac.replays++;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||
key->u.aes_gmac.replays++;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
key->u.gcmp.replays++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_key_replay);
|
||||
+88
-35
@@ -1417,6 +1417,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
}
|
||||
|
||||
if (sdata->vif.bss_conf.chandef.chan->band !=
|
||||
csa_ie.chandef.chan->band) {
|
||||
sdata_info(sdata,
|
||||
"AP %pM switches to different band (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
|
||||
ifmgd->associated->bssid,
|
||||
csa_ie.chandef.chan->center_freq,
|
||||
csa_ie.chandef.width, csa_ie.chandef.center_freq1,
|
||||
csa_ie.chandef.center_freq2);
|
||||
goto lock_and_drop_connection;
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
|
||||
IEEE80211_CHAN_DISABLED)) {
|
||||
sdata_info(sdata,
|
||||
@@ -1429,9 +1440,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
csa_ie.chandef.width, csa_ie.chandef.center_freq1,
|
||||
csa_ie.chandef.freq1_offset,
|
||||
csa_ie.chandef.center_freq2);
|
||||
ieee80211_queue_work(&local->hw,
|
||||
&ifmgd->csa_connection_drop_work);
|
||||
return;
|
||||
goto lock_and_drop_connection;
|
||||
}
|
||||
|
||||
if (cfg80211_chandef_identical(&csa_ie.chandef,
|
||||
@@ -1493,6 +1502,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->csa_chandef = csa_ie.chandef;
|
||||
sdata->csa_block_tx = csa_ie.mode;
|
||||
ifmgd->csa_ignored_same_chan = false;
|
||||
ifmgd->beacon_crc_valid = false;
|
||||
|
||||
if (sdata->csa_block_tx)
|
||||
ieee80211_stop_vif_queues(local, sdata,
|
||||
@@ -1500,7 +1510,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
|
||||
csa_ie.count);
|
||||
csa_ie.count, csa_ie.mode);
|
||||
|
||||
if (local->ops->channel_switch) {
|
||||
/* use driver's channel switch callback */
|
||||
@@ -1516,6 +1526,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
TU_TO_EXP_TIME((csa_ie.count - 1) *
|
||||
cbss->beacon_interval));
|
||||
return;
|
||||
lock_and_drop_connection:
|
||||
mutex_lock(&local->mtx);
|
||||
mutex_lock(&local->chanctx_mtx);
|
||||
drop_connection:
|
||||
/*
|
||||
* This is just so that the disconnect flow will know that
|
||||
@@ -1560,9 +1573,17 @@ ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
|
||||
chan_increment = 1;
|
||||
break;
|
||||
case NL80211_BAND_5GHZ:
|
||||
case NL80211_BAND_6GHZ:
|
||||
chan_increment = 4;
|
||||
break;
|
||||
case NL80211_BAND_6GHZ:
|
||||
/*
|
||||
* In the 6 GHz band, the "maximum transmit power level"
|
||||
* field in the triplets is reserved, and thus will be
|
||||
* zero and we shouldn't use it to control TX power.
|
||||
* The actual TX power will be given in the transmit
|
||||
* power envelope element instead.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/* find channel */
|
||||
@@ -2382,6 +2403,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
/* clear bssid only after building the needed mgmt frames */
|
||||
eth_zero_addr(ifmgd->bssid);
|
||||
|
||||
sdata->vif.bss_conf.ssid_len = 0;
|
||||
|
||||
/* remove AP and TDLS peers */
|
||||
sta_info_flush(sdata);
|
||||
|
||||
@@ -2720,7 +2743,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get);
|
||||
|
||||
static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *buf, size_t len, bool tx,
|
||||
u16 reason)
|
||||
u16 reason, bool reconnect)
|
||||
{
|
||||
struct ieee80211_event event = {
|
||||
.type = MLME_EVENT,
|
||||
@@ -2729,7 +2752,7 @@ static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||
};
|
||||
|
||||
if (tx)
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect);
|
||||
else
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
||||
|
||||
@@ -2751,13 +2774,18 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
||||
|
||||
tx = !sdata->csa_block_tx;
|
||||
|
||||
/* AP is probably out of range (or not reachable for another reason) so
|
||||
* remove the bss struct for that AP.
|
||||
*/
|
||||
cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
if (!ifmgd->driver_disconnect) {
|
||||
/*
|
||||
* AP is probably out of range (or not reachable for another
|
||||
* reason) so remove the bss struct for that AP.
|
||||
*/
|
||||
cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
}
|
||||
|
||||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
ifmgd->driver_disconnect ?
|
||||
WLAN_REASON_DEAUTH_LEAVING :
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
tx, frame_buf);
|
||||
mutex_lock(&local->mtx);
|
||||
sdata->vif.csa_active = false;
|
||||
@@ -2770,7 +2798,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
ifmgd->reconnect);
|
||||
ifmgd->reconnect = false;
|
||||
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
@@ -2789,6 +2819,13 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
|
||||
sdata_info(sdata, "Connection to AP %pM lost\n",
|
||||
ifmgd->bssid);
|
||||
__ieee80211_disconnect(sdata);
|
||||
ifmgd->connection_loss = false;
|
||||
} else if (ifmgd->driver_disconnect) {
|
||||
sdata_info(sdata,
|
||||
"Driver requested disconnection from AP %pM\n",
|
||||
ifmgd->bssid);
|
||||
__ieee80211_disconnect(sdata);
|
||||
ifmgd->driver_disconnect = false;
|
||||
} else {
|
||||
ieee80211_mgd_probe_ap(sdata, true);
|
||||
}
|
||||
@@ -2827,6 +2864,21 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_connection_loss);
|
||||
|
||||
void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
struct ieee80211_hw *hw = &sdata->local->hw;
|
||||
|
||||
trace_api_disconnect(sdata, reconnect);
|
||||
|
||||
if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
|
||||
return;
|
||||
|
||||
sdata->u.mgd.driver_disconnect = true;
|
||||
sdata->u.mgd.reconnect = reconnect;
|
||||
ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_disconnect);
|
||||
|
||||
static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
||||
bool assoc)
|
||||
@@ -3130,7 +3182,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
|
||||
reason_code);
|
||||
reason_code, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3179,7 +3231,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
||||
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code,
|
||||
false);
|
||||
}
|
||||
|
||||
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
@@ -3199,8 +3252,8 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
*have_higher_than_11mbit = true;
|
||||
|
||||
/*
|
||||
* Skip HT, VHT and HE BSS membership selectors since they're
|
||||
* not rates.
|
||||
* Skip HT, VHT, HE and SAE H2E only BSS membership selectors
|
||||
* since they're not rates.
|
||||
*
|
||||
* Note: Even though the membership selector and the basic
|
||||
* rate flag share the same bit, they are not exactly
|
||||
@@ -3208,7 +3261,8 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
*/
|
||||
if (supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY) ||
|
||||
supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY) ||
|
||||
supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY))
|
||||
supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY) ||
|
||||
supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < sband->n_bitrates; j++) {
|
||||
@@ -3494,14 +3548,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
le32_get_bits(elems->he_operation->he_oper_params,
|
||||
IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
|
||||
|
||||
bss_conf->multi_sta_back_32bit =
|
||||
sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP;
|
||||
|
||||
bss_conf->ack_enabled =
|
||||
sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN;
|
||||
|
||||
bss_conf->uora_exists = !!elems->uora_element;
|
||||
if (elems->uora_element)
|
||||
bss_conf->uora_ocw_range = elems->uora_element[0];
|
||||
@@ -4199,7 +4245,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
true, deauth_buf);
|
||||
ieee80211_report_disconnect(sdata, deauth_buf,
|
||||
sizeof(deauth_buf), true,
|
||||
WLAN_REASON_DEAUTH_LEAVING);
|
||||
WLAN_REASON_DEAUTH_LEAVING,
|
||||
false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4344,7 +4391,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
|
||||
tx, frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
reason);
|
||||
reason, false);
|
||||
}
|
||||
|
||||
static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
|
||||
@@ -4716,7 +4763,8 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
||||
IEEE80211_DEAUTH_FRAME_LEN);
|
||||
IEEE80211_DEAUTH_FRAME_LEN,
|
||||
false);
|
||||
}
|
||||
|
||||
/* This is a bit of a hack - we should find a better and more generic
|
||||
@@ -5430,7 +5478,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
WLAN_REASON_UNSPECIFIED);
|
||||
WLAN_REASON_UNSPECIFIED,
|
||||
false);
|
||||
}
|
||||
|
||||
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
||||
@@ -5471,6 +5520,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgd_assoc_data *assoc_data;
|
||||
const struct cfg80211_bss_ies *beacon_ies;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
||||
const u8 *ssidie, *ht_ie, *vht_ie;
|
||||
int i, err;
|
||||
bool override = false;
|
||||
@@ -5488,6 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
|
||||
assoc_data->ssid_len = ssidie[1];
|
||||
memcpy(bss_conf->ssid, assoc_data->ssid, assoc_data->ssid_len);
|
||||
bss_conf->ssid_len = assoc_data->ssid_len;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ifmgd->associated) {
|
||||
@@ -5502,7 +5554,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
WLAN_REASON_UNSPECIFIED);
|
||||
WLAN_REASON_UNSPECIFIED,
|
||||
false);
|
||||
}
|
||||
|
||||
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
||||
@@ -5801,7 +5854,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
req->reason_code);
|
||||
req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5821,7 +5874,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
req->reason_code);
|
||||
req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5836,7 +5889,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
req->reason_code, tx, frame_buf);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
req->reason_code);
|
||||
req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5869,7 +5922,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
req->reason_code);
|
||||
req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+5
-15
@@ -32,16 +32,6 @@
|
||||
#include "wme.h"
|
||||
#include "rate.h"
|
||||
|
||||
static inline void ieee80211_rx_stats(struct net_device *dev, u32 len)
|
||||
{
|
||||
struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
|
||||
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->rx_packets++;
|
||||
tstats->rx_bytes += len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
}
|
||||
|
||||
/*
|
||||
* monitor mode reception
|
||||
*
|
||||
@@ -842,7 +832,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
|
||||
if (skb) {
|
||||
skb->dev = sdata->dev;
|
||||
ieee80211_rx_stats(skb->dev, skb->len);
|
||||
dev_sw_netstats_rx_add(skb->dev, skb->len);
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
}
|
||||
@@ -1757,7 +1747,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
||||
} else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
|
||||
sta->rx_stats.last_rx = jiffies;
|
||||
} else if (!ieee80211_is_s1g_beacon(hdr->frame_control) &&
|
||||
is_multicast_ether_addr(hdr->addr1)) {
|
||||
!is_multicast_ether_addr(hdr->addr1)) {
|
||||
/*
|
||||
* Mesh beacons will update last_rx when if they are found to
|
||||
* match the current local configuration when processed.
|
||||
@@ -2559,7 +2549,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
|
||||
skb = rx->skb;
|
||||
xmit_skb = NULL;
|
||||
|
||||
ieee80211_rx_stats(dev, skb->len);
|
||||
dev_sw_netstats_rx_add(dev, skb->len);
|
||||
|
||||
if (rx->sta) {
|
||||
/* The seqno index has the same property as needed
|
||||
@@ -3698,7 +3688,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
||||
}
|
||||
|
||||
prev_dev = sdata->dev;
|
||||
ieee80211_rx_stats(sdata->dev, skb->len);
|
||||
dev_sw_netstats_rx_add(sdata->dev, skb->len);
|
||||
}
|
||||
|
||||
if (prev_dev) {
|
||||
@@ -4411,7 +4401,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
|
||||
skb->dev = fast_rx->dev;
|
||||
|
||||
ieee80211_rx_stats(fast_rx->dev, skb->len);
|
||||
dev_sw_netstats_rx_add(fast_rx->dev, skb->len);
|
||||
|
||||
/* The seqno index has the same property as needed
|
||||
* for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
|
||||
|
||||
+22
-1
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Portions of this file
|
||||
* Copyright(c) 2016-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
|
||||
@@ -2086,6 +2086,27 @@ TRACE_EVENT(api_connection_loss,
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(api_disconnect,
|
||||
TP_PROTO(struct ieee80211_sub_if_data *sdata, bool reconnect),
|
||||
|
||||
TP_ARGS(sdata, reconnect),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
VIF_ENTRY
|
||||
__field(int, reconnect)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
VIF_ASSIGN;
|
||||
__entry->reconnect = reconnect;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
VIF_PR_FMT " reconnect:%d",
|
||||
VIF_PR_ARG, __entry->reconnect
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(api_cqm_rssi_notify,
|
||||
TP_PROTO(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_cqm_rssi_threshold_event rssi_event,
|
||||
|
||||
+3
-13
@@ -38,16 +38,6 @@
|
||||
|
||||
/* misc utils */
|
||||
|
||||
static inline void ieee80211_tx_stats(struct net_device *dev, u32 len)
|
||||
{
|
||||
struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
|
||||
|
||||
u64_stats_update_begin(&tstats->syncp);
|
||||
tstats->tx_packets++;
|
||||
tstats->tx_bytes += len;
|
||||
u64_stats_update_end(&tstats->syncp);
|
||||
}
|
||||
|
||||
static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
|
||||
struct sk_buff *skb, int group_addr,
|
||||
int next_frag_len)
|
||||
@@ -3386,7 +3376,7 @@ static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
|
||||
if (key)
|
||||
info->control.hw_key = &key->conf;
|
||||
|
||||
ieee80211_tx_stats(skb->dev, skb->len);
|
||||
dev_sw_netstats_tx_add(skb->dev, 1, skb->len);
|
||||
|
||||
if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
|
||||
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
@@ -4004,7 +3994,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ieee80211_tx_stats(dev, skb->len);
|
||||
dev_sw_netstats_tx_add(dev, 1, skb->len);
|
||||
|
||||
ieee80211_xmit(sdata, sta, skb);
|
||||
}
|
||||
@@ -4231,7 +4221,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
|
||||
|
||||
ieee80211_tx_stats(dev, skb->len);
|
||||
dev_sw_netstats_tx_add(dev, 1, skb->len);
|
||||
|
||||
sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
|
||||
sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
|
||||
|
||||
Loaded 20 of 33 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user