mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 18:56:24 +00:00
Another set of changes, including
* many 6 GHz changes, though it's not _quite_ complete (I left out scanning for now, we're still discussing) * allow userspace SA-query processing for operating channel validation * TX status for control port TX, for AP-side operation * more per-STA/TID control options * move to kHz for channels, for future S1G operation * various other small changes -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl7TfecACgkQB8qZga/f l8Tx6hAAgRizfdHb9xxp001AAzKnsdU46srOKOhwV2d6w+S+qHbLtwa0Xz43pBvX LxpQs7dBQBLYh11xJhDlKY6duYV989xGcsHm7suO43jbjDo8KXfz4MaP65em6EKt pdD0mD1sKkfR4FhYNbUEe8Ug/185jdk+gX+aI1Nrz6XlkUoiY+czSnGFyAvpvau2 I+NGqyKG5D6ureq7p7dQcgN+t2D4Ou9stVhpQ+jP0Ep720gvfTEzeFuMJbb3JZ1y KSgOOWS1HQj1FdlJDs3KAmgUXpkU/lxZhNxl06MMYo3tB7Y0vmLoy/ZNcb5eW4Sw a0SHgG5yhDysCyINz6q7llG3esDcppGiNuMjd/qR2qPOZPHNtlYaHtcoKBcKdS0k 03DyURZpA0B33cr9FTV8tXaM7IMY/2qaq/DqkeNtuDzGdh4jEwkVJ4fNtUAdgcOv 4JEz3A7fY3isy8tzi7Dom4U/2hR1di5gZloAC5PPYRvnbmY9HoIqG06k1Wtn1Yj4 pbquqvdJ5ONcaAaXz7zVQUZm1JzrK81Pl3pdih7USasc8z2MEzWQPSR+hxtwG5TY KbDI1Nel8ZLbL2MWDakh3+lPoJAMuyadRlVVWEMj4l/afYHgcy5hEbaMbaZnxmAg G4I6R5JZTJZuVdKi/U/Q9n7jR83qfIRNbxMLY8HFZ4caJ5qhZGs= =wdaG -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-davem-2020-05-31' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== Another set of changes, including * many 6 GHz changes, though it's not _quite_ complete (I left out scanning for now, we're still discussing) * allow userspace SA-query processing for operating channel validation * TX status for control port TX, for AP-side operation * more per-STA/TID control options * move to kHz for channels, for future S1G operation * various other small changes ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
1079a34c56
@ -3054,6 +3054,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_SUPPORTS_5_10_MHZ |
|
||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
|
||||
NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
|
||||
|
@ -105,6 +105,51 @@
|
||||
|
||||
/* extension, added by 802.11ad */
|
||||
#define IEEE80211_STYPE_DMG_BEACON 0x0000
|
||||
#define IEEE80211_STYPE_S1G_BEACON 0x0010
|
||||
|
||||
/* bits unique to S1G beacon */
|
||||
#define IEEE80211_S1G_BCN_NEXT_TBTT 0x100
|
||||
|
||||
/* see 802.11ah-2016 9.9 NDP CMAC frames */
|
||||
#define IEEE80211_S1G_1MHZ_NDP_BITS 25
|
||||
#define IEEE80211_S1G_1MHZ_NDP_BYTES 4
|
||||
#define IEEE80211_S1G_2MHZ_NDP_BITS 37
|
||||
#define IEEE80211_S1G_2MHZ_NDP_BYTES 5
|
||||
|
||||
#define IEEE80211_NDP_FTYPE_CTS 0
|
||||
#define IEEE80211_NDP_FTYPE_CF_END 0
|
||||
#define IEEE80211_NDP_FTYPE_PS_POLL 1
|
||||
#define IEEE80211_NDP_FTYPE_ACK 2
|
||||
#define IEEE80211_NDP_FTYPE_PS_POLL_ACK 3
|
||||
#define IEEE80211_NDP_FTYPE_BA 4
|
||||
#define IEEE80211_NDP_FTYPE_BF_REPORT_POLL 5
|
||||
#define IEEE80211_NDP_FTYPE_PAGING 6
|
||||
#define IEEE80211_NDP_FTYPE_PREQ 7
|
||||
|
||||
#define SM64(f, v) ((((u64)v) << f##_S) & f)
|
||||
|
||||
/* NDP CMAC frame fields */
|
||||
#define IEEE80211_NDP_FTYPE 0x0000000000000007
|
||||
#define IEEE80211_NDP_FTYPE_S 0x0000000000000000
|
||||
|
||||
/* 1M Probe Request 11ah 9.9.3.1.1 */
|
||||
#define IEEE80211_NDP_1M_PREQ_ANO 0x0000000000000008
|
||||
#define IEEE80211_NDP_1M_PREQ_ANO_S 3
|
||||
#define IEEE80211_NDP_1M_PREQ_CSSID 0x00000000000FFFF0
|
||||
#define IEEE80211_NDP_1M_PREQ_CSSID_S 4
|
||||
#define IEEE80211_NDP_1M_PREQ_RTYPE 0x0000000000100000
|
||||
#define IEEE80211_NDP_1M_PREQ_RTYPE_S 20
|
||||
#define IEEE80211_NDP_1M_PREQ_RSV 0x0000000001E00000
|
||||
#define IEEE80211_NDP_1M_PREQ_RSV 0x0000000001E00000
|
||||
/* 2M Probe Request 11ah 9.9.3.1.2 */
|
||||
#define IEEE80211_NDP_2M_PREQ_ANO 0x0000000000000008
|
||||
#define IEEE80211_NDP_2M_PREQ_ANO_S 3
|
||||
#define IEEE80211_NDP_2M_PREQ_CSSID 0x0000000FFFFFFFF0
|
||||
#define IEEE80211_NDP_2M_PREQ_CSSID_S 4
|
||||
#define IEEE80211_NDP_2M_PREQ_RTYPE 0x0000001000000000
|
||||
#define IEEE80211_NDP_2M_PREQ_RTYPE_S 36
|
||||
|
||||
#define IEEE80211_ANO_NETTYPE_WILD 15
|
||||
|
||||
/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */
|
||||
#define IEEE80211_CTL_EXT_POLL 0x2000
|
||||
@ -121,6 +166,21 @@
|
||||
#define IEEE80211_MAX_SN IEEE80211_SN_MASK
|
||||
#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1)
|
||||
|
||||
|
||||
/* PV1 Layout 11ah 9.8.3.1 */
|
||||
#define IEEE80211_PV1_FCTL_VERS 0x0003
|
||||
#define IEEE80211_PV1_FCTL_FTYPE 0x001c
|
||||
#define IEEE80211_PV1_FCTL_STYPE 0x00e0
|
||||
#define IEEE80211_PV1_FCTL_TODS 0x0100
|
||||
#define IEEE80211_PV1_FCTL_MOREFRAGS 0x0200
|
||||
#define IEEE80211_PV1_FCTL_PM 0x0400
|
||||
#define IEEE80211_PV1_FCTL_MOREDATA 0x0800
|
||||
#define IEEE80211_PV1_FCTL_PROTECTED 0x1000
|
||||
#define IEEE80211_PV1_FCTL_END_SP 0x2000
|
||||
#define IEEE80211_PV1_FCTL_RELAYED 0x4000
|
||||
#define IEEE80211_PV1_FCTL_ACK_POLICY 0x8000
|
||||
#define IEEE80211_PV1_FCTL_CTL_EXT 0x0f00
|
||||
|
||||
static inline bool ieee80211_sn_less(u16 sn1, u16 sn2)
|
||||
{
|
||||
return ((sn1 - sn2) & IEEE80211_SN_MASK) > (IEEE80211_SN_MODULO >> 1);
|
||||
@ -148,6 +208,7 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2)
|
||||
#define IEEE80211_MAX_FRAG_THRESHOLD 2352
|
||||
#define IEEE80211_MAX_RTS_THRESHOLD 2353
|
||||
#define IEEE80211_MAX_AID 2007
|
||||
#define IEEE80211_MAX_AID_S1G 8191
|
||||
#define IEEE80211_MAX_TIM_LEN 251
|
||||
#define IEEE80211_MAX_MESH_PEERINGS 63
|
||||
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
|
||||
@ -371,6 +432,17 @@ static inline bool ieee80211_is_data(__le16 fc)
|
||||
cpu_to_le16(IEEE80211_FTYPE_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_ext - check if type is IEEE80211_FTYPE_EXT
|
||||
* @fc: frame control bytes in little-endian byteorder
|
||||
*/
|
||||
static inline bool ieee80211_is_ext(__le16 fc)
|
||||
{
|
||||
return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
|
||||
cpu_to_le16(IEEE80211_FTYPE_EXT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set
|
||||
* @fc: frame control bytes in little-endian byteorder
|
||||
@ -469,6 +541,18 @@ static inline bool ieee80211_is_beacon(__le16 fc)
|
||||
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_s1g_beacon - check if IEEE80211_FTYPE_EXT &&
|
||||
* IEEE80211_STYPE_S1G_BEACON
|
||||
* @fc: frame control bytes in little-endian byteorder
|
||||
*/
|
||||
static inline bool ieee80211_is_s1g_beacon(__le16 fc)
|
||||
{
|
||||
return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE |
|
||||
IEEE80211_FCTL_STYPE)) ==
|
||||
cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM
|
||||
* @fc: frame control bytes in little-endian byteorder
|
||||
@ -716,7 +800,7 @@ struct ieee80211_msrment_ie {
|
||||
u8 token;
|
||||
u8 mode;
|
||||
u8 type;
|
||||
u8 request[0];
|
||||
u8 request[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@ -900,6 +984,59 @@ struct ieee80211_addba_ext_ie {
|
||||
u8 data;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ieee80211_s1g_bcn_compat_ie
|
||||
*
|
||||
* S1G Beacon Compatibility element
|
||||
*/
|
||||
struct ieee80211_s1g_bcn_compat_ie {
|
||||
__le16 compat_info;
|
||||
__le16 beacon_int;
|
||||
__le32 tsf_completion;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ieee80211_s1g_oper_ie
|
||||
*
|
||||
* S1G Operation element
|
||||
*/
|
||||
struct ieee80211_s1g_oper_ie {
|
||||
u8 ch_width;
|
||||
u8 oper_class;
|
||||
u8 primary_ch;
|
||||
u8 oper_ch;
|
||||
__le16 basic_mcs_nss;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct ieee80211_aid_response_ie
|
||||
*
|
||||
* AID Response element
|
||||
*/
|
||||
struct ieee80211_aid_response_ie {
|
||||
__le16 aid;
|
||||
u8 switch_count;
|
||||
__le16 response_int;
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_s1g_cap {
|
||||
u8 capab_info[10];
|
||||
u8 supp_mcs_nss[5];
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_ext {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
union {
|
||||
struct {
|
||||
u8 sa[ETH_ALEN];
|
||||
__le32 timestamp;
|
||||
u8 change_seq;
|
||||
u8 variable[0];
|
||||
} __packed s1g_beacon;
|
||||
} u;
|
||||
} __packed __aligned(2);
|
||||
|
||||
struct ieee80211_mgmt {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
@ -1644,7 +1781,7 @@ struct ieee80211_he_operation {
|
||||
__le32 he_oper_params;
|
||||
__le16 he_mcs_nss_set;
|
||||
/* Optional 0,1,3,4,5,7 or 8 bytes: depends on @he_oper_params */
|
||||
u8 optional[0];
|
||||
u8 optional[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@ -1656,7 +1793,7 @@ struct ieee80211_he_operation {
|
||||
struct ieee80211_he_spr {
|
||||
u8 he_sr_control;
|
||||
/* Optional 0 to 19 bytes: depends on @he_sr_control */
|
||||
u8 optional[0];
|
||||
u8 optional[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
@ -1821,6 +1958,8 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
||||
#define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40
|
||||
#define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80
|
||||
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3
|
||||
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
@ -1842,6 +1981,9 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
|
||||
#define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING 0x40
|
||||
#define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX 0x80
|
||||
|
||||
#define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20
|
||||
#define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16
|
||||
|
||||
/* 802.11ax HE PHY capabilities */
|
||||
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02
|
||||
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x04
|
||||
@ -2067,6 +2209,28 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
|
||||
#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000
|
||||
#define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000
|
||||
|
||||
/**
|
||||
* ieee80211_he_6ghz_oper - HE 6 GHz operation Information field
|
||||
* @primary: primary channel
|
||||
* @control: control flags
|
||||
* @ccfs0: channel center frequency segment 0
|
||||
* @ccfs1: channel center frequency segment 1
|
||||
* @minrate: minimum rate (in 1 Mbps units)
|
||||
*/
|
||||
struct ieee80211_he_6ghz_oper {
|
||||
u8 primary;
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH 0x3
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ 0
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ 1
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ 2
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ 3
|
||||
#define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON 0x4
|
||||
u8 control;
|
||||
u8 ccfs0;
|
||||
u8 ccfs1;
|
||||
u8 minrate;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size
|
||||
* @he_oper_ie: byte data of the He Operations IE, stating from the byte
|
||||
@ -2093,7 +2257,7 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
|
||||
oper_len++;
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)
|
||||
oper_len += 4;
|
||||
oper_len += sizeof(struct ieee80211_he_6ghz_oper);
|
||||
|
||||
/* Add the first byte (extension ID) to the total length */
|
||||
oper_len++;
|
||||
@ -2101,6 +2265,34 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
|
||||
return oper_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_he_6ghz_oper - obtain 6 GHz operation field
|
||||
* @he_oper: HE operation element (must be pre-validated for size)
|
||||
* but may be %NULL
|
||||
*
|
||||
* Return: a pointer to the 6 GHz operation field, or %NULL
|
||||
*/
|
||||
static inline const struct ieee80211_he_6ghz_oper *
|
||||
ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper)
|
||||
{
|
||||
const u8 *ret = (void *)&he_oper->optional;
|
||||
u32 he_oper_params;
|
||||
|
||||
if (!he_oper)
|
||||
return NULL;
|
||||
|
||||
he_oper_params = le32_to_cpu(he_oper->he_oper_params);
|
||||
|
||||
if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO))
|
||||
return NULL;
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)
|
||||
ret += 3;
|
||||
if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
|
||||
ret++;
|
||||
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
/* HE Spatial Reuse defines */
|
||||
#define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT 0x4
|
||||
#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT 0x8
|
||||
@ -2137,6 +2329,86 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
|
||||
return spr_len;
|
||||
}
|
||||
|
||||
/* S1G Capabilities Information field */
|
||||
#define S1G_CAPAB_B0_S1G_LONG BIT(0)
|
||||
#define S1G_CAPAB_B0_SGI_1MHZ BIT(1)
|
||||
#define S1G_CAPAB_B0_SGI_2MHZ BIT(2)
|
||||
#define S1G_CAPAB_B0_SGI_4MHZ BIT(3)
|
||||
#define S1G_CAPAB_B0_SGI_8MHZ BIT(4)
|
||||
#define S1G_CAPAB_B0_SGI_16MHZ BIT(5)
|
||||
#define S1G_CAPAB_B0_SUPP_CH_WIDTH_MASK (BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B0_SUPP_CH_WIDTH_SHIFT 6
|
||||
|
||||
#define S1G_CAPAB_B1_RX_LDPC BIT(0)
|
||||
#define S1G_CAPAB_B1_TX_STBC BIT(1)
|
||||
#define S1G_CAPAB_B1_RX_STBC BIT(2)
|
||||
#define S1G_CAPAB_B1_SU_BFER BIT(3)
|
||||
#define S1G_CAPAB_B1_SU_BFEE BIT(4)
|
||||
#define S1G_CAPAB_B1_BFEE_STS_MASK (BIT(5) | BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B1_BFEE_STS_SHIFT 5
|
||||
|
||||
#define S1G_CAPAB_B2_SOUNDING_DIMENSIONS_MASK (BIT(0) | BIT(1) | BIT(2))
|
||||
#define S1G_CAPAB_B2_SOUNDING_DIMENSIONS_SHIFT 0
|
||||
#define S1G_CAPAB_B2_MU_BFER BIT(3)
|
||||
#define S1G_CAPAB_B2_MU_BFEE BIT(4)
|
||||
#define S1G_CAPAB_B2_PLUS_HTC_VHT BIT(5)
|
||||
#define S1G_CAPAB_B2_TRAVELING_PILOT_MASK (BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B2_TRAVELING_PILOT_SHIFT 6
|
||||
|
||||
#define S1G_CAPAB_B3_RD_RESPONDER BIT(0)
|
||||
#define S1G_CAPAB_B3_HT_DELAYED_BA BIT(1)
|
||||
#define S1G_CAPAB_B3_MAX_MPDU_LEN BIT(2)
|
||||
#define S1G_CAPAB_B3_MAX_AMPDU_LEN_EXP_MASK (BIT(3) | BIT(4))
|
||||
#define S1G_CAPAB_B3_MAX_AMPDU_LEN_EXP_SHIFT 3
|
||||
#define S1G_CAPAB_B3_MIN_MPDU_START_MASK (BIT(5) | BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B3_MIN_MPDU_START_SHIFT 5
|
||||
|
||||
#define S1G_CAPAB_B4_UPLINK_SYNC BIT(0)
|
||||
#define S1G_CAPAB_B4_DYNAMIC_AID BIT(1)
|
||||
#define S1G_CAPAB_B4_BAT BIT(2)
|
||||
#define S1G_CAPAB_B4_TIME_ADE BIT(3)
|
||||
#define S1G_CAPAB_B4_NON_TIM BIT(4)
|
||||
#define S1G_CAPAB_B4_GROUP_AID BIT(5)
|
||||
#define S1G_CAPAB_B4_STA_TYPE_MASK (BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B4_STA_TYPE_SHIFT 6
|
||||
|
||||
#define S1G_CAPAB_B5_CENT_AUTH_CONTROL BIT(0)
|
||||
#define S1G_CAPAB_B5_DIST_AUTH_CONTROL BIT(1)
|
||||
#define S1G_CAPAB_B5_AMSDU BIT(2)
|
||||
#define S1G_CAPAB_B5_AMPDU BIT(3)
|
||||
#define S1G_CAPAB_B5_ASYMMETRIC_BA BIT(4)
|
||||
#define S1G_CAPAB_B5_FLOW_CONTROL BIT(5)
|
||||
#define S1G_CAPAB_B5_SECTORIZED_BEAM_MASK (BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B5_SECTORIZED_BEAM_SHIFT 6
|
||||
|
||||
#define S1G_CAPAB_B6_OBSS_MITIGATION BIT(0)
|
||||
#define S1G_CAPAB_B6_FRAGMENT_BA BIT(1)
|
||||
#define S1G_CAPAB_B6_NDP_PS_POLL BIT(2)
|
||||
#define S1G_CAPAB_B6_RAW_OPERATION BIT(3)
|
||||
#define S1G_CAPAB_B6_PAGE_SLICING BIT(4)
|
||||
#define S1G_CAPAB_B6_TXOP_SHARING_IMP_ACK BIT(5)
|
||||
#define S1G_CAPAB_B6_VHT_LINK_ADAPT_MASK (BIT(6) | BIT(7))
|
||||
#define S1G_CAPAB_B6_VHT_LINK_ADAPT_SHIFT 6
|
||||
|
||||
#define S1G_CAPAB_B7_TACK_AS_PS_POLL BIT(0)
|
||||
#define S1G_CAPAB_B7_DUP_1MHZ BIT(1)
|
||||
#define S1G_CAPAB_B7_MCS_NEGOTIATION BIT(2)
|
||||
#define S1G_CAPAB_B7_1MHZ_CTL_RESPONSE_PREAMBLE BIT(3)
|
||||
#define S1G_CAPAB_B7_NDP_BFING_REPORT_POLL BIT(4)
|
||||
#define S1G_CAPAB_B7_UNSOLICITED_DYN_AID BIT(5)
|
||||
#define S1G_CAPAB_B7_SECTOR_TRAINING_OPERATION BIT(6)
|
||||
#define S1G_CAPAB_B7_TEMP_PS_MODE_SWITCH BIT(7)
|
||||
|
||||
#define S1G_CAPAB_B8_TWT_GROUPING BIT(0)
|
||||
#define S1G_CAPAB_B8_BDT BIT(1)
|
||||
#define S1G_CAPAB_B8_COLOR_MASK (BIT(2) | BIT(3) | BIT(4))
|
||||
#define S1G_CAPAB_B8_COLOR_SHIFT 2
|
||||
#define S1G_CAPAB_B8_TWT_REQUEST BIT(5)
|
||||
#define S1G_CAPAB_B8_TWT_RESPOND BIT(6)
|
||||
#define S1G_CAPAB_B8_PV1_FRAME BIT(7)
|
||||
|
||||
#define S1G_CAPAB_B9_LINK_ADAPT_PER_CONTROL_RESPONSE BIT(0)
|
||||
|
||||
/* Authentication algorithms */
|
||||
#define WLAN_AUTH_OPEN 0
|
||||
#define WLAN_AUTH_SHARED_KEY 1
|
||||
@ -2532,8 +2804,14 @@ enum ieee80211_eid {
|
||||
WLAN_EID_QUIET_CHANNEL = 198,
|
||||
WLAN_EID_OPMODE_NOTIF = 199,
|
||||
|
||||
WLAN_EID_REDUCED_NEIGHBOR_REPORT = 201,
|
||||
|
||||
WLAN_EID_S1G_BCN_COMPAT = 213,
|
||||
WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
|
||||
WLAN_EID_S1G_CAPABILITIES = 217,
|
||||
WLAN_EID_VENDOR_SPECIFIC = 221,
|
||||
WLAN_EID_QOS_PARAMETER = 222,
|
||||
WLAN_EID_S1G_OPERATION = 232,
|
||||
WLAN_EID_CAG_NUMBER = 237,
|
||||
WLAN_EID_AP_CSN = 239,
|
||||
WLAN_EID_FILS_INDICATION = 240,
|
||||
@ -2561,9 +2839,19 @@ enum ieee80211_eid_ext {
|
||||
WLAN_EID_EXT_UORA = 37,
|
||||
WLAN_EID_EXT_HE_MU_EDCA = 38,
|
||||
WLAN_EID_EXT_HE_SPR = 39,
|
||||
WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET = 41,
|
||||
WLAN_EID_EXT_BSS_COLOR_CHG_ANN = 42,
|
||||
WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP = 43,
|
||||
WLAN_EID_EXT_ESS_REPORT = 45,
|
||||
WLAN_EID_EXT_OPS = 46,
|
||||
WLAN_EID_EXT_HE_BSS_LOAD = 47,
|
||||
WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
|
||||
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
|
||||
WLAN_EID_EXT_NON_INHERITANCE = 56,
|
||||
WLAN_EID_EXT_KNOWN_BSSID = 57,
|
||||
WLAN_EID_EXT_SHORT_SSID_LIST = 58,
|
||||
WLAN_EID_EXT_HE_6GHZ_CAPA = 59,
|
||||
WLAN_EID_EXT_UL_MU_POWER_CAPA = 60,
|
||||
};
|
||||
|
||||
/* Action category code */
|
||||
@ -2794,7 +3082,7 @@ enum ieee80211_tdls_actioncode {
|
||||
#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7)
|
||||
|
||||
/* Defines support for enhanced multi-bssid advertisement*/
|
||||
#define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(1)
|
||||
#define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(3)
|
||||
|
||||
/* TDLS specific payload type in the LLC/SNAP header */
|
||||
#define WLAN_TDLS_SNAP_RFTYPE 0x2
|
||||
@ -3106,6 +3394,24 @@ struct ieee80211_tspec_ie {
|
||||
__le16 medium_time;
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_he_6ghz_capa {
|
||||
/* uses IEEE80211_HE_6GHZ_CAP_* below */
|
||||
__le16 capa;
|
||||
} __packed;
|
||||
|
||||
/* HE 6 GHz band capabilities */
|
||||
/* uses enum ieee80211_min_mpdu_spacing values */
|
||||
#define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x0007
|
||||
/* uses enum ieee80211_vht_max_ampdu_length_exp values */
|
||||
#define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x0038
|
||||
/* uses IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_* values */
|
||||
#define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x00c0
|
||||
/* WLAN_HT_CAP_SM_PS_* values */
|
||||
#define IEEE80211_HE_6GHZ_CAP_SM_PS 0x0600
|
||||
#define IEEE80211_HE_6GHZ_CAP_RD_RESPONDER 0x0800
|
||||
#define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS 0x1000
|
||||
#define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS 0x2000
|
||||
|
||||
/**
|
||||
* ieee80211_get_qos_ctl - get pointer to qos control bytes
|
||||
* @hdr: the frame
|
||||
@ -3333,6 +3639,8 @@ static inline int ieee80211_get_tdls_action(struct sk_buff *skb, u32 hdr_size)
|
||||
/* convert frequencies */
|
||||
#define MHZ_TO_KHZ(freq) ((freq) * 1000)
|
||||
#define KHZ_TO_MHZ(freq) ((freq) / 1000)
|
||||
#define PR_KHZ(f) KHZ_TO_MHZ(f), f % 1000
|
||||
#define KHZ_F "%d.%03d"
|
||||
|
||||
/* convert powers */
|
||||
#define DBI_TO_MBI(gain) ((gain) * 100)
|
||||
@ -3447,4 +3755,30 @@ static inline bool for_each_element_completed(const struct element *element,
|
||||
#define WLAN_RSNX_CAPA_PROTECTED_TWT BIT(4)
|
||||
#define WLAN_RSNX_CAPA_SAE_H2E BIT(5)
|
||||
|
||||
/*
|
||||
* reduced neighbor report, based on Draft P802.11ax_D5.0,
|
||||
* section 9.4.2.170
|
||||
*/
|
||||
#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_RNR_TBTT_PARAMS_OCT_RECOMMENDED 0x01
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_SAME_SSID 0x02
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID 0x04
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID 0x08
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS 0x10
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20
|
||||
#define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40
|
||||
|
||||
struct ieee80211_neighbor_ap_info {
|
||||
u8 tbtt_info_hdr;
|
||||
u8 tbtt_info_len;
|
||||
u8 op_class;
|
||||
u8 channel;
|
||||
} __packed;
|
||||
|
||||
#endif /* LINUX_IEEE80211_H */
|
||||
|
@ -354,10 +354,13 @@ struct ieee80211_sta_he_cap {
|
||||
*
|
||||
* @types_mask: interface types mask
|
||||
* @he_cap: holds the HE capabilities
|
||||
* @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a
|
||||
* 6 GHz band channel (and 0 may be valid value).
|
||||
*/
|
||||
struct ieee80211_sband_iftype_data {
|
||||
u16 types_mask;
|
||||
struct ieee80211_sta_he_cap he_cap;
|
||||
struct ieee80211_he_6ghz_capa he_6ghz_capa;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -509,6 +512,26 @@ ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
|
||||
return ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_STATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_get_he_6ghz_capa - return HE 6 GHz capabilities
|
||||
* @sband: the sband to search for the STA on
|
||||
* @iftype: the iftype to search for
|
||||
*
|
||||
* Return: the 6GHz capabilities
|
||||
*/
|
||||
static inline __le16
|
||||
ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband,
|
||||
enum nl80211_iftype iftype)
|
||||
{
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
ieee80211_get_sband_iftype_data(sband, iftype);
|
||||
|
||||
if (WARN_ON(!data || !data->he_cap.has_he))
|
||||
return 0;
|
||||
|
||||
return data->he_6ghz_capa.capa;
|
||||
}
|
||||
|
||||
/**
|
||||
* wiphy_read_of_freq_limits - read frequency limits from device tree
|
||||
*
|
||||
@ -630,6 +653,19 @@ struct cfg80211_chan_def {
|
||||
u16 freq1_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* cfg80211_bitrate_mask - masks for bitrate control
|
||||
*/
|
||||
struct cfg80211_bitrate_mask {
|
||||
struct {
|
||||
u32 legacy;
|
||||
u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
|
||||
u16 vht_mcs[NL80211_VHT_NSS_MAX];
|
||||
enum nl80211_txrate_gi gi;
|
||||
} control[NUM_NL80211_BANDS];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct cfg80211_tid_cfg - TID specific configuration
|
||||
* @config_override: Flag to notify driver to reset TID configuration
|
||||
@ -640,17 +676,23 @@ struct cfg80211_chan_def {
|
||||
* @noack: noack configuration value for the TID
|
||||
* @retry_long: retry count value
|
||||
* @retry_short: retry count value
|
||||
* @ampdu: Enable/Disable aggregation
|
||||
* @ampdu: Enable/Disable MPDU aggregation
|
||||
* @rtscts: Enable/Disable RTS/CTS
|
||||
* @amsdu: Enable/Disable MSDU aggregation
|
||||
* @txrate_type: Tx bitrate mask type
|
||||
* @txrate_mask: Tx bitrate to be applied for the TID
|
||||
*/
|
||||
struct cfg80211_tid_cfg {
|
||||
bool config_override;
|
||||
u8 tids;
|
||||
u32 mask;
|
||||
u64 mask;
|
||||
enum nl80211_tid_config noack;
|
||||
u8 retry_long, retry_short;
|
||||
enum nl80211_tid_config ampdu;
|
||||
enum nl80211_tid_config rtscts;
|
||||
enum nl80211_tid_config amsdu;
|
||||
enum nl80211_tx_rate_setting txrate_type;
|
||||
struct cfg80211_bitrate_mask txrate_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1005,18 +1047,6 @@ struct cfg80211_acl_data {
|
||||
struct mac_address mac_addrs[];
|
||||
};
|
||||
|
||||
/*
|
||||
* cfg80211_bitrate_mask - masks for bitrate control
|
||||
*/
|
||||
struct cfg80211_bitrate_mask {
|
||||
struct {
|
||||
u32 legacy;
|
||||
u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
|
||||
u16 vht_mcs[NL80211_VHT_NSS_MAX];
|
||||
enum nl80211_txrate_gi gi;
|
||||
} control[NUM_NL80211_BANDS];
|
||||
};
|
||||
|
||||
/**
|
||||
* enum cfg80211_ap_settings_flags - AP settings flags
|
||||
*
|
||||
@ -1231,6 +1261,7 @@ struct sta_txpwr {
|
||||
* @he_capa_len: the length of the HE capabilities
|
||||
* @airtime_weight: airtime scheduler weight for this station
|
||||
* @txpwr: transmit power for an associated station
|
||||
* @he_6ghz_capa: HE 6 GHz Band capabilities of station
|
||||
*/
|
||||
struct station_parameters {
|
||||
const u8 *supported_rates;
|
||||
@ -1263,6 +1294,7 @@ struct station_parameters {
|
||||
u8 he_capa_len;
|
||||
u16 airtime_weight;
|
||||
struct sta_txpwr txpwr;
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2035,7 +2067,7 @@ struct cfg80211_scan_request {
|
||||
bool no_cck;
|
||||
|
||||
/* keep last */
|
||||
struct ieee80211_channel *channels[0];
|
||||
struct ieee80211_channel *channels[];
|
||||
};
|
||||
|
||||
static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask)
|
||||
@ -2181,7 +2213,7 @@ struct cfg80211_sched_scan_request {
|
||||
struct list_head list;
|
||||
|
||||
/* keep last */
|
||||
struct ieee80211_channel *channels[0];
|
||||
struct ieee80211_channel *channels[];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2303,7 +2335,7 @@ struct cfg80211_bss {
|
||||
u8 bssid_index;
|
||||
u8 max_bssid_indicator;
|
||||
|
||||
u8 priv[0] __aligned(sizeof(void *));
|
||||
u8 priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2904,12 +2936,17 @@ struct cfg80211_wowlan_wakeup {
|
||||
|
||||
/**
|
||||
* struct cfg80211_gtk_rekey_data - rekey data
|
||||
* @kek: key encryption key (NL80211_KEK_LEN bytes)
|
||||
* @kck: key confirmation key (NL80211_KCK_LEN bytes)
|
||||
* @kek: key encryption key (@kek_len bytes)
|
||||
* @kck: key confirmation key (@kck_len bytes)
|
||||
* @replay_ctr: replay counter (NL80211_REPLAY_CTR_LEN bytes)
|
||||
* @kek_len: length of kek
|
||||
* @kck_len length of kck
|
||||
* @akm: akm (oui, id)
|
||||
*/
|
||||
struct cfg80211_gtk_rekey_data {
|
||||
const u8 *kek, *kck, *replay_ctr;
|
||||
u32 akm;
|
||||
u8 kek_len, kck_len;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4067,7 +4104,8 @@ struct cfg80211_ops {
|
||||
struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, const __be16 proto,
|
||||
const bool noencrypt);
|
||||
const bool noencrypt,
|
||||
u64 *cookie);
|
||||
|
||||
int (*get_ftm_responder_stats)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
@ -4133,9 +4171,10 @@ struct cfg80211_ops {
|
||||
* beaconing mode (AP, IBSS, Mesh, ...).
|
||||
* @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation
|
||||
* before connection.
|
||||
* @WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK: The device supports bigger kek and kck keys
|
||||
*/
|
||||
enum wiphy_flags {
|
||||
/* use hole at 0 */
|
||||
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0),
|
||||
/* use hole at 1 */
|
||||
/* use hole at 2 */
|
||||
WIPHY_FLAG_NETNS_OK = BIT(3),
|
||||
@ -4850,7 +4889,7 @@ struct wiphy {
|
||||
|
||||
u8 max_data_retry_count;
|
||||
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
char priv[] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
static inline struct net *wiphy_net(struct wiphy *wiphy)
|
||||
@ -5269,6 +5308,21 @@ ieee80211_get_channel(struct wiphy *wiphy, int freq)
|
||||
return ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(freq));
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_channel_is_psc - Check if the channel is a 6 GHz PSC
|
||||
* @chan: control channel to check
|
||||
*
|
||||
* The Preferred Scanning Channels (PSC) are defined in
|
||||
* Draft IEEE P802.11ax/D5.0, 26.17.2.3.3
|
||||
*/
|
||||
static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan)
|
||||
{
|
||||
if (chan->band != NL80211_BAND_6GHZ)
|
||||
return false;
|
||||
|
||||
return ieee80211_frequency_to_channel(chan->center_freq) % 16 == 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_get_response_rate - get basic rate for a given rate
|
||||
*
|
||||
@ -6986,6 +7040,26 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
|
||||
enum nl80211_connect_failed_reason reason,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_mgmt_khz - notification of received, unprocessed management frame
|
||||
* @wdev: wireless device receiving the frame
|
||||
* @freq: Frequency on which the frame was received in KHz
|
||||
* @sig_dbm: signal strength in dBm, or 0 if unknown
|
||||
* @buf: Management frame (header + body)
|
||||
* @len: length of the frame data
|
||||
* @flags: flags, as defined in enum nl80211_rxmgmt_flags
|
||||
*
|
||||
* This function is called whenever an Action frame is received for a station
|
||||
* mode interface, but is not processed in kernel.
|
||||
*
|
||||
* Return: %true if a user space application has registered for this frame.
|
||||
* For action frames, that makes it responsible for rejecting unrecognized
|
||||
* action frames; %false otherwise, in which case for action frames the
|
||||
* driver is responsible for rejecting the frame.
|
||||
*/
|
||||
bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
const u8 *buf, size_t len, u32 flags);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_mgmt - notification of received, unprocessed management frame
|
||||
* @wdev: wireless device receiving the frame
|
||||
@ -7003,8 +7077,13 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
|
||||
* action frames; %false otherwise, in which case for action frames the
|
||||
* driver is responsible for rejecting the frame.
|
||||
*/
|
||||
bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
const u8 *buf, size_t len, u32 flags);
|
||||
static inline bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq,
|
||||
int sig_dbm, const u8 *buf, size_t len,
|
||||
u32 flags)
|
||||
{
|
||||
return cfg80211_rx_mgmt_khz(wdev, MHZ_TO_KHZ(freq), sig_dbm, buf, len,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_mgmt_tx_status - notification of TX status for management frame
|
||||
@ -7022,6 +7101,23 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_control_port_tx_status - notification of TX status for control
|
||||
* port frames
|
||||
* @wdev: wireless device receiving the frame
|
||||
* @cookie: Cookie returned by cfg80211_ops::tx_control_port()
|
||||
* @buf: Data frame (header + body)
|
||||
* @len: length of the frame data
|
||||
* @ack: Whether frame was acknowledged
|
||||
* @gfp: context flags
|
||||
*
|
||||
* This function is called whenever a control port frame was requested to be
|
||||
* transmitted with cfg80211_ops::tx_control_port() to report the TX status of
|
||||
* the transmission attempt.
|
||||
*/
|
||||
void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_control_port - notification about a received control port frame
|
||||
@ -7202,6 +7298,21 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
u64 cookie, bool acked, s32 ack_signal,
|
||||
bool is_valid_ack_signal, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_report_obss_beacon_khz - report beacon from other APs
|
||||
* @wiphy: The wiphy that received the beacon
|
||||
* @frame: the frame
|
||||
* @len: length of the frame
|
||||
* @freq: frequency the frame was received on in KHz
|
||||
* @sig_dbm: signal strength in dBm, or 0 if unknown
|
||||
*
|
||||
* Use this function to report to userspace when a beacon was
|
||||
* received. It is not useful to call this when there is no
|
||||
* netdev that is in AP/GO mode.
|
||||
*/
|
||||
void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
|
||||
size_t len, int freq, int sig_dbm);
|
||||
|
||||
/**
|
||||
* cfg80211_report_obss_beacon - report beacon from other APs
|
||||
* @wiphy: The wiphy that received the beacon
|
||||
@ -7214,9 +7325,13 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
* received. It is not useful to call this when there is no
|
||||
* netdev that is in AP/GO mode.
|
||||
*/
|
||||
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
const u8 *frame, size_t len,
|
||||
int freq, int sig_dbm);
|
||||
static inline void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
const u8 *frame, size_t len,
|
||||
int freq, int sig_dbm)
|
||||
{
|
||||
cfg80211_report_obss_beacon_khz(wiphy, frame, len, MHZ_TO_KHZ(freq),
|
||||
sig_dbm);
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_reg_can_beacon - check if beaconing is allowed
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef MAC80211_H
|
||||
@ -230,7 +230,7 @@ struct ieee80211_chanctx_conf {
|
||||
|
||||
bool radar_enabled;
|
||||
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1670,7 +1670,7 @@ struct ieee80211_vif {
|
||||
bool txqs_stopped[IEEE80211_NUM_ACS];
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
|
||||
@ -1798,7 +1798,7 @@ struct ieee80211_key_conf {
|
||||
s8 keyidx;
|
||||
u16 flags;
|
||||
u8 keylen;
|
||||
u8 key[0];
|
||||
u8 key[];
|
||||
};
|
||||
|
||||
#define IEEE80211_MAX_PN_LEN 16
|
||||
@ -1977,6 +1977,7 @@ struct ieee80211_sta_txpwr {
|
||||
* @ht_cap: HT capabilities of this STA; restricted to our own capabilities
|
||||
* @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
|
||||
* @he_cap: HE capabilities of this STA
|
||||
* @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities
|
||||
* @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU
|
||||
* that this station is allowed to transmit to us.
|
||||
* Can be modified by driver.
|
||||
@ -2016,6 +2017,7 @@ struct ieee80211_sta {
|
||||
struct ieee80211_sta_ht_cap ht_cap;
|
||||
struct ieee80211_sta_vht_cap vht_cap;
|
||||
struct ieee80211_sta_he_cap he_cap;
|
||||
struct ieee80211_he_6ghz_capa he_6ghz_capa;
|
||||
u16 max_rx_aggregation_subframes;
|
||||
bool wme;
|
||||
u8 uapsd_queues;
|
||||
@ -2053,7 +2055,7 @@ struct ieee80211_sta {
|
||||
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1];
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2099,7 +2101,7 @@ struct ieee80211_txq {
|
||||
u8 ac;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -296,13 +296,14 @@
|
||||
* to get a list of all present wiphys.
|
||||
* @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
|
||||
* %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
|
||||
* %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the
|
||||
* attributes determining the channel width; this is used for setting
|
||||
* monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT,
|
||||
* %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
|
||||
* and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
|
||||
* However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
|
||||
* instead, the support here is for backward compatibility only.
|
||||
* %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
|
||||
* %NL80211_ATTR_WIPHY_FREQ_OFFSET (and the attributes determining the
|
||||
* channel width; this is used for setting monitor mode channel),
|
||||
* %NL80211_ATTR_WIPHY_RETRY_SHORT, %NL80211_ATTR_WIPHY_RETRY_LONG,
|
||||
* %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, and/or
|
||||
* %NL80211_ATTR_WIPHY_RTS_THRESHOLD. However, for setting the channel,
|
||||
* see %NL80211_CMD_SET_CHANNEL instead, the support here is for backward
|
||||
* compatibility only.
|
||||
* @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
|
||||
* or rename notification. Has attributes %NL80211_ATTR_WIPHY and
|
||||
* %NL80211_ATTR_WIPHY_NAME.
|
||||
@ -351,7 +352,8 @@
|
||||
* %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
|
||||
* %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
|
||||
* The channel to use can be set on the interface or be given using the
|
||||
* %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
|
||||
* %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_FREQ_OFFSET, and the
|
||||
* attributes determining channel width.
|
||||
* @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
|
||||
* @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
|
||||
* @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
|
||||
@ -536,11 +538,12 @@
|
||||
* interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
|
||||
* BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
|
||||
* the SSID (mainly for association, but is included in authentication
|
||||
* request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
|
||||
* to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
|
||||
* is used to specify the authentication type. %NL80211_ATTR_IE is used to
|
||||
* define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
|
||||
* to be added to the frame.
|
||||
* request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ +
|
||||
* %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequence of the
|
||||
* channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the
|
||||
* authentication type. %NL80211_ATTR_IE is used to define IEs
|
||||
* (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added
|
||||
* to the frame.
|
||||
* When used as an event, this reports reception of an Authentication
|
||||
* frame in station and IBSS modes when the local MLME processed the
|
||||
* frame, i.e., it was for the local STA and was received in correct
|
||||
@ -595,8 +598,9 @@
|
||||
* requests to connect to a specified network but without separating
|
||||
* auth and assoc steps. For this, you need to specify the SSID in a
|
||||
* %NL80211_ATTR_SSID attribute, and can optionally specify the association
|
||||
* IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
|
||||
* %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
|
||||
* IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE,
|
||||
* %NL80211_ATTR_USE_MFP, %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ,
|
||||
* %NL80211_ATTR_WIPHY_FREQ_OFFSET, %NL80211_ATTR_CONTROL_PORT,
|
||||
* %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
|
||||
* %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
|
||||
* %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and
|
||||
@ -1160,6 +1164,12 @@
|
||||
* dropped because it did not include a valid MME MIC while beacon
|
||||
* protection was enabled (BIGTK configured in station mode).
|
||||
*
|
||||
* @NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS: Report TX status of a control
|
||||
* port frame transmitted with %NL80211_CMD_CONTROL_PORT_FRAME.
|
||||
* %NL80211_ATTR_COOKIE identifies the TX command and %NL80211_ATTR_FRAME
|
||||
* includes the contents of the frame. %NL80211_ATTR_ACK flag is included
|
||||
* if the recipient acknowledged the frame.
|
||||
*
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
*/
|
||||
@ -1388,6 +1398,8 @@ enum nl80211_commands {
|
||||
|
||||
NL80211_CMD_UNPROT_BEACON,
|
||||
|
||||
NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
@ -1433,7 +1445,8 @@ enum nl80211_commands {
|
||||
* of &enum nl80211_chan_width, describing the channel width. See the
|
||||
* documentation of the enum for more information.
|
||||
* @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the
|
||||
* channel, used for anything but 20 MHz bandwidth
|
||||
* channel, used for anything but 20 MHz bandwidth. In S1G this is the
|
||||
* operating channel center frequency.
|
||||
* @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the
|
||||
* channel, used only for 80+80 MHz bandwidth
|
||||
* @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
|
||||
@ -2480,9 +2493,17 @@ enum nl80211_commands {
|
||||
* entry without having to force a disconnection after the PMK timeout. If
|
||||
* no roaming occurs between the reauth threshold and PMK expiration,
|
||||
* disassociation is still forced.
|
||||
*
|
||||
* @NL80211_ATTR_RECEIVE_MULTICAST: multicast flag for the
|
||||
* %NL80211_CMD_REGISTER_FRAME command, see the description there.
|
||||
* @NL80211_ATTR_WIPHY_FREQ_OFFSET: offset of the associated
|
||||
* %NL80211_ATTR_WIPHY_FREQ in positive KHz. Only valid when supplied with
|
||||
* an %NL80211_ATTR_WIPHY_FREQ_OFFSET.
|
||||
* @NL80211_ATTR_CENTER_FREQ1_OFFSET: Center frequency offset in KHz for the
|
||||
* first channel segment specified in %NL80211_ATTR_CENTER_FREQ1.
|
||||
* @NL80211_ATTR_SCAN_FREQ_KHZ: nested attribute with KHz frequencies
|
||||
*
|
||||
* @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
|
||||
* association request when used with NL80211_CMD_NEW_STATION).
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
@ -2960,6 +2981,11 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_PMK_REAUTH_THRESHOLD,
|
||||
|
||||
NL80211_ATTR_RECEIVE_MULTICAST,
|
||||
NL80211_ATTR_WIPHY_FREQ_OFFSET,
|
||||
NL80211_ATTR_CENTER_FREQ1_OFFSET,
|
||||
NL80211_ATTR_SCAN_FREQ_KHZ,
|
||||
|
||||
NL80211_ATTR_HE_6GHZ_CAPABILITY,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
@ -3539,6 +3565,8 @@ enum nl80211_mpath_info {
|
||||
* defined in HE capabilities IE
|
||||
* @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently
|
||||
* defined
|
||||
* @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16),
|
||||
* given for all 6 GHz band channels
|
||||
* @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
enum nl80211_band_iftype_attr {
|
||||
@ -3549,6 +3577,7 @@ enum nl80211_band_iftype_attr {
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
|
||||
NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
|
||||
@ -3682,6 +3711,7 @@ enum nl80211_wmm_rule {
|
||||
* (see &enum nl80211_wmm_rule)
|
||||
* @NL80211_FREQUENCY_ATTR_NO_HE: HE operation is not allowed on this channel
|
||||
* in current regulatory domain.
|
||||
* @NL80211_FREQUENCY_ATTR_OFFSET: frequency offset in KHz
|
||||
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
|
||||
* currently defined
|
||||
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
|
||||
@ -3712,6 +3742,7 @@ enum nl80211_frequency_attr {
|
||||
NL80211_FREQUENCY_ATTR_NO_10MHZ,
|
||||
NL80211_FREQUENCY_ATTR_WMM,
|
||||
NL80211_FREQUENCY_ATTR_NO_HE,
|
||||
NL80211_FREQUENCY_ATTR_OFFSET,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
|
||||
@ -4482,6 +4513,7 @@ enum nl80211_bss_scan_width {
|
||||
* @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update.
|
||||
* Contains a nested array of signal strength attributes (u8, dBm),
|
||||
* using the nesting index as the antenna number.
|
||||
* @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
|
||||
* @__NL80211_BSS_AFTER_LAST: internal
|
||||
* @NL80211_BSS_MAX: highest BSS attribute
|
||||
*/
|
||||
@ -4506,6 +4538,7 @@ enum nl80211_bss {
|
||||
NL80211_BSS_PARENT_TSF,
|
||||
NL80211_BSS_PARENT_BSSID,
|
||||
NL80211_BSS_CHAIN_SIGNAL,
|
||||
NL80211_BSS_FREQUENCY_OFFSET,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_BSS_AFTER_LAST,
|
||||
@ -4816,6 +4849,17 @@ enum nl80211_tid_config {
|
||||
NL80211_TID_CONFIG_DISABLE,
|
||||
};
|
||||
|
||||
/* enum nl80211_tx_rate_setting - TX rate configuration type
|
||||
* @NL80211_TX_RATE_AUTOMATIC: automatically determine TX rate
|
||||
* @NL80211_TX_RATE_LIMITED: limit the TX rate by the TX rate parameter
|
||||
* @NL80211_TX_RATE_FIXED: fix TX rate to the TX rate parameter
|
||||
*/
|
||||
enum nl80211_tx_rate_setting {
|
||||
NL80211_TX_RATE_AUTOMATIC,
|
||||
NL80211_TX_RATE_LIMITED,
|
||||
NL80211_TX_RATE_FIXED,
|
||||
};
|
||||
|
||||
/* enum nl80211_tid_config_attr - TID specific configuration.
|
||||
* @NL80211_TID_CONFIG_ATTR_PAD: pad attribute for 64-bit values
|
||||
* @NL80211_TID_CONFIG_ATTR_VIF_SUPP: a bitmap (u64) of attributes supported
|
||||
@ -4823,12 +4867,10 @@ enum nl80211_tid_config {
|
||||
* (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
|
||||
* @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
|
||||
* per peer instead.
|
||||
* @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if no peer
|
||||
* is selected, if set indicates that the new configuration overrides
|
||||
* all previous peer configurations, otherwise previous peer specific
|
||||
* configurations should be left untouched. If peer is selected then
|
||||
* it will reset particular TID configuration of that peer and it will
|
||||
* not accept other TID config attributes along with peer.
|
||||
* @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if set indicates
|
||||
* that the new configuration overrides all previous peer
|
||||
* configurations, otherwise previous peer specific configurations
|
||||
* should be left untouched.
|
||||
* @NL80211_TID_CONFIG_ATTR_TIDS: a bitmask value of TIDs (bit 0 to 7)
|
||||
* Its type is u16.
|
||||
* @NL80211_TID_CONFIG_ATTR_NOACK: Configure ack policy for the TID.
|
||||
@ -4844,12 +4886,23 @@ enum nl80211_tid_config {
|
||||
* &NL80211_CMD_SET_TID_CONFIG. Its type is u8, min value is 1 and
|
||||
* the max value is advertised by the driver in this attribute on
|
||||
* output in wiphy capabilities.
|
||||
* @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable aggregation for the TIDs
|
||||
* specified in %NL80211_TID_CONFIG_ATTR_TIDS. Its type is u8, using
|
||||
* the values from &nl80211_tid_config.
|
||||
* @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable MPDU aggregation
|
||||
* for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS.
|
||||
* Its type is u8, using the values from &nl80211_tid_config.
|
||||
* @NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL: Enable/Disable RTS_CTS for the TIDs
|
||||
* specified in %NL80211_TID_CONFIG_ATTR_TIDS. It is u8 type, using
|
||||
* the values from &nl80211_tid_config.
|
||||
* @NL80211_TID_CONFIG_ATTR_AMSDU_CTRL: Enable/Disable MSDU aggregation
|
||||
* for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS.
|
||||
* Its type is u8, using the values from &nl80211_tid_config.
|
||||
* @NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE: This attribute will be useful
|
||||
* to notfiy the driver that what type of txrate should be used
|
||||
* for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS. using
|
||||
* the values form &nl80211_tx_rate_setting.
|
||||
* @NL80211_TID_CONFIG_ATTR_TX_RATE: Data frame TX rate mask should be applied
|
||||
* with the parameters passed through %NL80211_ATTR_TX_RATES.
|
||||
* configuration is applied to the data frame for the tid to that connected
|
||||
* station.
|
||||
*/
|
||||
enum nl80211_tid_config_attr {
|
||||
__NL80211_TID_CONFIG_ATTR_INVALID,
|
||||
@ -4863,6 +4916,9 @@ enum nl80211_tid_config_attr {
|
||||
NL80211_TID_CONFIG_ATTR_RETRY_LONG,
|
||||
NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
|
||||
NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
|
||||
NL80211_TID_CONFIG_ATTR_AMSDU_CTRL,
|
||||
NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE,
|
||||
NL80211_TID_CONFIG_ATTR_TX_RATE,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_TID_CONFIG_ATTR_AFTER_LAST,
|
||||
@ -5340,6 +5396,8 @@ enum plink_actions {
|
||||
|
||||
#define NL80211_KCK_LEN 16
|
||||
#define NL80211_KEK_LEN 16
|
||||
#define NL80211_KCK_EXT_LEN 24
|
||||
#define NL80211_KEK_EXT_LEN 32
|
||||
#define NL80211_REPLAY_CTR_LEN 8
|
||||
|
||||
/**
|
||||
@ -5348,6 +5406,7 @@ enum plink_actions {
|
||||
* @NL80211_REKEY_DATA_KEK: key encryption key (binary)
|
||||
* @NL80211_REKEY_DATA_KCK: key confirmation key (binary)
|
||||
* @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary)
|
||||
* @NL80211_REKEY_DATA_AKM: AKM data (OUI, suite type)
|
||||
* @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal)
|
||||
* @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal)
|
||||
*/
|
||||
@ -5356,6 +5415,7 @@ enum nl80211_rekey_data {
|
||||
NL80211_REKEY_DATA_KEK,
|
||||
NL80211_REKEY_DATA_KCK,
|
||||
NL80211_REKEY_DATA_REPLAY_CTR,
|
||||
NL80211_REKEY_DATA_AKM,
|
||||
|
||||
/* keep last */
|
||||
NUM_NL80211_REKEY_DATA,
|
||||
@ -5705,6 +5765,14 @@ enum nl80211_feature_flags {
|
||||
* @NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS: management frame registrations
|
||||
* are possible for multicast frames and those will be reported properly.
|
||||
*
|
||||
* @NL80211_EXT_FEATURE_SCAN_FREQ_KHZ: This driver supports receiving and
|
||||
* reporting scan request with %NL80211_ATTR_SCAN_FREQ_KHZ. In order to
|
||||
* report %NL80211_ATTR_SCAN_FREQ_KHZ, %NL80211_SCAN_FLAG_FREQ_KHZ must be
|
||||
* included in the scan request.
|
||||
*
|
||||
* @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS: The driver
|
||||
* can report tx status for control port over nl80211 tx operations.
|
||||
*
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@ -5758,6 +5826,8 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_DEL_IBSS_STA,
|
||||
NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
|
||||
NL80211_EXT_FEATURE_SCAN_FREQ_KHZ,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
@ -5869,6 +5939,9 @@ enum nl80211_timeout_reason {
|
||||
* @NL80211_SCAN_FLAG_MIN_PREQ_CONTENT: minimize probe request content to
|
||||
* only have supported rates and no additional capabilities (unless
|
||||
* added by userspace explicitly.)
|
||||
* @NL80211_SCAN_FLAG_FREQ_KHZ: report scan results with
|
||||
* %NL80211_ATTR_SCAN_FREQ_KHZ. This also means
|
||||
* %NL80211_ATTR_SCAN_FREQUENCIES will not be included.
|
||||
*/
|
||||
enum nl80211_scan_flags {
|
||||
NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
|
||||
@ -5884,6 +5957,7 @@ enum nl80211_scan_flags {
|
||||
NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
|
||||
NL80211_SCAN_FLAG_RANDOM_SN = 1<<11,
|
||||
NL80211_SCAN_FLAG_MIN_PREQ_CONTENT = 1<<12,
|
||||
NL80211_SCAN_FLAG_FREQ_KHZ = 1<<13,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,11 @@
|
||||
#include <linux/socket.h> /* for "struct sockaddr" et al */
|
||||
#include <linux/if.h> /* for IFNAMSIZ and co... */
|
||||
|
||||
#include <stddef.h> /* for offsetof */
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/stddef.h> /* for offsetof */
|
||||
#else
|
||||
# include <stddef.h> /* for offsetof */
|
||||
#endif
|
||||
|
||||
/***************************** VERSION *****************************/
|
||||
/*
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007-2010, Intel Corporation
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -292,7 +292,8 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!sta->sta.ht_cap.ht_supported) {
|
||||
if (!sta->sta.ht_cap.ht_supported &&
|
||||
sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) {
|
||||
ht_dbg(sta->sdata,
|
||||
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
|
||||
sta->sta.addr, tid);
|
||||
|
@ -593,7 +593,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
|
||||
"Requested to start BA session on reserved tid=%d", tid))
|
||||
return -EINVAL;
|
||||
|
||||
if (!pubsta->ht_cap.ht_supported)
|
||||
if (!pubsta->ht_cap.ht_supported &&
|
||||
sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON_ONCE(!local->ops->ampdu_action))
|
||||
|
@ -1520,7 +1520,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
if (params->he_capa)
|
||||
ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
|
||||
(void *)params->he_capa,
|
||||
params->he_capa_len, sta);
|
||||
params->he_capa_len,
|
||||
(void *)params->he_6ghz_capa,
|
||||
sta);
|
||||
|
||||
if (params->opmode_notif_used) {
|
||||
/* returned value is only needed for rc update, but the
|
||||
@ -2196,7 +2198,8 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
if (!sdata->vif.bss_conf.use_short_slot &&
|
||||
sband->band == NL80211_BAND_5GHZ) {
|
||||
(sband->band == NL80211_BAND_5GHZ ||
|
||||
sband->band == NL80211_BAND_6GHZ)) {
|
||||
sdata->vif.bss_conf.use_short_slot = true;
|
||||
changed |= BSS_CHANGED_ERP_SLOT;
|
||||
}
|
||||
@ -3957,7 +3960,7 @@ static int ieee80211_set_tid_config(struct wiphy *wiphy,
|
||||
|
||||
static int ieee80211_reset_tid_config(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *peer, u8 tid)
|
||||
const u8 *peer, u8 tids)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sta_info *sta;
|
||||
@ -3967,7 +3970,7 @@ static int ieee80211_reset_tid_config(struct wiphy *wiphy,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!peer)
|
||||
return drv_reset_tid_config(sdata->local, sdata, NULL, tid);
|
||||
return drv_reset_tid_config(sdata->local, sdata, NULL, tids);
|
||||
|
||||
mutex_lock(&sdata->local->sta_mtx);
|
||||
sta = sta_info_get_bss(sdata, peer);
|
||||
@ -3976,7 +3979,7 @@ static int ieee80211_reset_tid_config(struct wiphy *wiphy,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tid);
|
||||
ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tids);
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
|
||||
return ret;
|
||||
|
@ -1375,12 +1375,12 @@ static inline int drv_set_tid_config(struct ieee80211_local *local,
|
||||
|
||||
static inline int drv_reset_tid_config(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta *sta, u8 tid)
|
||||
struct ieee80211_sta *sta, u8 tids)
|
||||
{
|
||||
int ret;
|
||||
|
||||
might_sleep();
|
||||
ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tid);
|
||||
ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
|
@ -8,10 +8,55 @@
|
||||
|
||||
#include "ieee80211_i.h"
|
||||
|
||||
static void
|
||||
ieee80211_update_from_he_6ghz_capa(const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
|
||||
if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
||||
switch (le16_get_bits(he_6ghz_capa->capa,
|
||||
IEEE80211_HE_6GHZ_CAP_SM_PS)) {
|
||||
case WLAN_HT_CAP_SM_PS_INVALID:
|
||||
case WLAN_HT_CAP_SM_PS_STATIC:
|
||||
smps_mode = IEEE80211_SMPS_STATIC;
|
||||
break;
|
||||
case WLAN_HT_CAP_SM_PS_DYNAMIC:
|
||||
smps_mode = IEEE80211_SMPS_DYNAMIC;
|
||||
break;
|
||||
case WLAN_HT_CAP_SM_PS_DISABLED:
|
||||
smps_mode = IEEE80211_SMPS_OFF;
|
||||
break;
|
||||
}
|
||||
|
||||
sta->sta.smps_mode = smps_mode;
|
||||
} else {
|
||||
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
|
||||
}
|
||||
|
||||
switch (le16_get_bits(he_6ghz_capa->capa,
|
||||
IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) {
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
|
||||
sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
|
||||
break;
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
|
||||
sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991;
|
||||
break;
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
|
||||
default:
|
||||
sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895;
|
||||
break;
|
||||
}
|
||||
|
||||
sta->sta.he_6ghz_capa = *he_6ghz_capa;
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_supported_band *sband,
|
||||
const u8 *he_cap_ie, u8 he_cap_len,
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap;
|
||||
@ -53,6 +98,9 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta);
|
||||
sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
|
||||
|
||||
if (sband->band == NL80211_BAND_6GHZ && he_6ghz_capa)
|
||||
ieee80211_update_from_he_6ghz_capa(he_6ghz_capa, sta);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018-2019 Intel Corporation
|
||||
* Copyright(c) 2018-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@ -781,6 +781,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_channel_type ch_type;
|
||||
int err;
|
||||
u32 sta_flags;
|
||||
u32 vht_cap_info = 0;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
@ -798,9 +799,13 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
break;
|
||||
}
|
||||
|
||||
if (elems->vht_cap_elem)
|
||||
vht_cap_info = le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
err = ieee80211_parse_ch_switch_ie(sdata, elems,
|
||||
ifibss->chandef.chan->band,
|
||||
vht_cap_info,
|
||||
sta_flags, ifibss->bssid, &csa_ie);
|
||||
/* can't switch to destination channel, fail */
|
||||
if (err < 0)
|
||||
@ -1060,8 +1065,10 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
||||
/* we both use VHT */
|
||||
struct ieee80211_vht_cap cap_ie;
|
||||
struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap;
|
||||
u32 vht_cap_info =
|
||||
le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
|
||||
|
||||
ieee80211_chandef_vht_oper(&local->hw,
|
||||
ieee80211_chandef_vht_oper(&local->hw, vht_cap_info,
|
||||
elems->vht_operation,
|
||||
elems->ht_operation,
|
||||
&chandef);
|
||||
|
@ -111,6 +111,8 @@ struct ieee80211_bss {
|
||||
size_t supp_rates_len;
|
||||
struct ieee80211_rate *beacon_rate;
|
||||
|
||||
u32 vht_cap_info;
|
||||
|
||||
/*
|
||||
* During association, we save an ERP value from a probe response so
|
||||
* that we can feed ERP info to the driver when handling the
|
||||
@ -267,7 +269,7 @@ struct probe_resp {
|
||||
struct rcu_head rcu_head;
|
||||
int len;
|
||||
u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
struct ps_data {
|
||||
@ -1494,6 +1496,7 @@ struct ieee802_11_elems {
|
||||
const struct ieee80211_he_operation *he_operation;
|
||||
const struct ieee80211_he_spr *he_spr;
|
||||
const struct ieee80211_mu_edca_param_set *mu_edca_param_set;
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa;
|
||||
const u8 *uora_element;
|
||||
const u8 *mesh_id;
|
||||
const u8 *peering;
|
||||
@ -1783,7 +1786,8 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags,
|
||||
u32 ctrl_flags);
|
||||
u32 ctrl_flags,
|
||||
u64 *cookie);
|
||||
void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
|
||||
struct sk_buff_head *skbs);
|
||||
struct sk_buff *
|
||||
@ -1800,7 +1804,8 @@ void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_clear_fast_xmit(struct sta_info *sta);
|
||||
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, __be16 proto, bool unencrypted);
|
||||
const u8 *dest, __be16 proto, bool unencrypted,
|
||||
u64 *cookie);
|
||||
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len);
|
||||
|
||||
@ -1894,6 +1899,7 @@ void
|
||||
ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_supported_band *sband,
|
||||
const u8 *he_cap_ie, u8 he_cap_len,
|
||||
const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
|
||||
struct sta_info *sta);
|
||||
void
|
||||
ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif,
|
||||
@ -1912,6 +1918,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
|
||||
* @sdata: the sdata of the interface which has received the frame
|
||||
* @elems: parsed 802.11 elements received with the frame
|
||||
* @current_band: indicates the current band
|
||||
* @vht_cap_info: VHT capabilities of the transmitter
|
||||
* @sta_flags: contains information about own capabilities and restrictions
|
||||
* to decide which channel switch announcements can be accepted. Only the
|
||||
* following subset of &enum ieee80211_sta_flags are evaluated:
|
||||
@ -1926,6 +1933,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
|
||||
int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee802_11_elems *elems,
|
||||
enum nl80211_band current_band,
|
||||
u32 vht_cap_info,
|
||||
u32 sta_flags, u8 *bssid,
|
||||
struct ieee80211_csa_ie *csa_ie);
|
||||
|
||||
@ -2136,7 +2144,7 @@ enum {
|
||||
IEEE80211_PROBE_FLAG_RANDOM_SN = BIT(2),
|
||||
};
|
||||
|
||||
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
|
||||
int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer,
|
||||
size_t buffer_len,
|
||||
struct ieee80211_scan_ies *ie_desc,
|
||||
const u8 *ie, size_t ie_len,
|
||||
@ -2174,7 +2182,9 @@ u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
|
||||
u8 *ieee80211_ie_build_he_cap(u8 *pos,
|
||||
const struct ieee80211_sta_he_cap *he_cap,
|
||||
u8 *end);
|
||||
u8 *ieee80211_ie_build_he_oper(u8 *pos);
|
||||
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb);
|
||||
u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef);
|
||||
int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
|
||||
const struct ieee80211_supported_band *sband,
|
||||
const u8 *srates, int srates_len, u32 *rates);
|
||||
@ -2189,10 +2199,13 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo);
|
||||
/* channel management */
|
||||
bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
|
||||
bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
|
||||
const struct ieee80211_vht_operation *oper,
|
||||
const struct ieee80211_ht_operation *htop,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
|
||||
const struct ieee80211_he_operation *he_oper,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
|
||||
|
||||
int __must_check
|
||||
|
@ -596,6 +596,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_SCAN_FREQ_KHZ);
|
||||
|
||||
if (!ops->hw_scan) {
|
||||
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 open80211s Ltd.
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
* Authors: Luis Carlos Cobo <luisca@cozybit.com>
|
||||
* Javier Cardona <javier@cozybit.com>
|
||||
*/
|
||||
@ -63,6 +63,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
u32 basic_rates = 0;
|
||||
struct cfg80211_chan_def sta_chan_def;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 vht_cap_info = 0;
|
||||
|
||||
/*
|
||||
* As support for each feature is added, check for matching
|
||||
@ -96,9 +97,14 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
cfg80211_chandef_create(&sta_chan_def, sdata->vif.bss_conf.chandef.chan,
|
||||
NL80211_CHAN_NO_HT);
|
||||
ieee80211_chandef_ht_oper(ie->ht_operation, &sta_chan_def);
|
||||
ieee80211_chandef_vht_oper(&sdata->local->hw,
|
||||
|
||||
if (ie->vht_cap_elem)
|
||||
vht_cap_info = le32_to_cpu(ie->vht_cap_elem->vht_cap_info);
|
||||
|
||||
ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
|
||||
ie->vht_operation, ie->ht_operation,
|
||||
&sta_chan_def);
|
||||
ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, &sta_chan_def);
|
||||
|
||||
if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
|
||||
&sta_chan_def))
|
||||
@ -415,6 +421,10 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
/* HT not allowed in 6 GHz */
|
||||
if (sband->band == NL80211_BAND_6GHZ)
|
||||
return 0;
|
||||
|
||||
if (!sband->ht_cap.ht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -452,6 +462,10 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
sband = local->hw.wiphy->bands[channel->band];
|
||||
ht_cap = &sband->ht_cap;
|
||||
|
||||
/* HT not allowed in 6 GHz */
|
||||
if (sband->band == NL80211_BAND_6GHZ)
|
||||
return 0;
|
||||
|
||||
if (!ht_cap->ht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -479,6 +493,10 @@ int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
/* VHT not allowed in 6 GHz */
|
||||
if (sband->band == NL80211_BAND_6GHZ)
|
||||
return 0;
|
||||
|
||||
if (!sband->vht_cap.vht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -516,6 +534,10 @@ int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
sband = local->hw.wiphy->bands[channel->band];
|
||||
vht_cap = &sband->vht_cap;
|
||||
|
||||
/* VHT not allowed in 6 GHz */
|
||||
if (sband->band == NL80211_BAND_6GHZ)
|
||||
return 0;
|
||||
|
||||
if (!vht_cap->vht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -565,6 +587,7 @@ int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 len;
|
||||
u8 *pos;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
@ -578,15 +601,26 @@ int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
|
||||
return 0;
|
||||
|
||||
if (skb_tailroom(skb) < 2 + 1 + sizeof(struct ieee80211_he_operation))
|
||||
len = 2 + 1 + sizeof(struct ieee80211_he_operation);
|
||||
if (sdata->vif.bss_conf.chandef.chan->band == NL80211_BAND_6GHZ)
|
||||
len += sizeof(struct ieee80211_he_6ghz_oper);
|
||||
|
||||
if (skb_tailroom(skb) < len)
|
||||
return -ENOMEM;
|
||||
|
||||
pos = skb_put(skb, 2 + 1 + sizeof(struct ieee80211_he_operation));
|
||||
ieee80211_ie_build_he_oper(pos);
|
||||
pos = skb_put(skb, len);
|
||||
ieee80211_ie_build_he_oper(pos, &sdata->vif.bss_conf.chandef);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ieee80211_ie_build_he_6ghz_cap(sdata, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_mesh_path_timer(struct timer_list *t)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
@ -766,6 +800,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
2 + sizeof(struct ieee80211_vht_operation) +
|
||||
ie_len_he_cap +
|
||||
2 + 1 + sizeof(struct ieee80211_he_operation) +
|
||||
sizeof(struct ieee80211_he_6ghz_oper) +
|
||||
2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
|
||||
ifmsh->ie_len;
|
||||
|
||||
bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL);
|
||||
@ -885,6 +921,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
mesh_add_vht_oper_ie(sdata, skb) ||
|
||||
mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
|
||||
mesh_add_he_oper_ie(sdata, skb) ||
|
||||
mesh_add_he_6ghz_cap_ie(sdata, skb) ||
|
||||
mesh_add_vendor_ies(sdata, skb))
|
||||
goto out_free;
|
||||
|
||||
@ -1045,7 +1082,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
struct ieee80211_supported_band *sband;
|
||||
int err;
|
||||
u32 sta_flags;
|
||||
u32 sta_flags, vht_cap_info = 0;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
@ -1068,8 +1105,13 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
||||
break;
|
||||
}
|
||||
|
||||
if (elems->vht_cap_elem)
|
||||
vht_cap_info =
|
||||
le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band,
|
||||
vht_cap_info,
|
||||
sta_flags, sdata->vif.addr,
|
||||
&csa_ie);
|
||||
if (err < 0)
|
||||
|
@ -222,6 +222,8 @@ int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u8 ie_len);
|
||||
int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb);
|
||||
int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb);
|
||||
void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
|
||||
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211s_init(void);
|
||||
|
@ -238,6 +238,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
|
||||
2 + sizeof(struct ieee80211_vht_operation) +
|
||||
ie_len_he_cap +
|
||||
2 + 1 + sizeof(struct ieee80211_he_operation) +
|
||||
sizeof(struct ieee80211_he_6ghz_oper) +
|
||||
2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
|
||||
2 + 8 + /* peering IE */
|
||||
sdata->u.mesh.ie_len);
|
||||
if (!skb)
|
||||
@ -328,7 +330,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
|
||||
mesh_add_vht_cap_ie(sdata, skb) ||
|
||||
mesh_add_vht_oper_ie(sdata, skb) ||
|
||||
mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
|
||||
mesh_add_he_oper_ie(sdata, skb))
|
||||
mesh_add_he_oper_ie(sdata, skb) ||
|
||||
mesh_add_he_6ghz_cap_ie(sdata, skb))
|
||||
goto free;
|
||||
}
|
||||
|
||||
@ -441,7 +444,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
||||
elems->vht_cap_elem, sta);
|
||||
|
||||
ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap,
|
||||
elems->he_cap_len, sta);
|
||||
elems->he_cap_len,
|
||||
elems->he_6ghz_capa,
|
||||
sta);
|
||||
|
||||
if (bw != sta->sta.bandwidth)
|
||||
changed |= IEEE80211_RC_BW_CHANGED;
|
||||
|
@ -145,6 +145,7 @@ static u32
|
||||
ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_channel *channel,
|
||||
u32 vht_cap_info,
|
||||
const struct ieee80211_ht_operation *ht_oper,
|
||||
const struct ieee80211_vht_operation *vht_oper,
|
||||
const struct ieee80211_he_operation *he_oper,
|
||||
@ -155,15 +156,24 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta_ht_cap sta_ht_cap;
|
||||
u32 ht_cfreq, ret;
|
||||
|
||||
memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
|
||||
ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
|
||||
|
||||
memset(chandef, 0, sizeof(struct cfg80211_chan_def));
|
||||
chandef->chan = channel;
|
||||
chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
chandef->center_freq1 = channel->center_freq;
|
||||
chandef->freq1_offset = channel->freq_offset;
|
||||
|
||||
if (channel->band == NL80211_BAND_6GHZ) {
|
||||
if (!ieee80211_chandef_he_6ghz_oper(sdata, he_oper, chandef))
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
vht_chandef = *chandef;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
|
||||
ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
|
||||
|
||||
if (!ht_oper || !sta_ht_cap.ht_supported) {
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT |
|
||||
@ -223,7 +233,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
memcpy(&he_oper_vht_cap, he_oper->optional, 3);
|
||||
he_oper_vht_cap.basic_mcs_set = cpu_to_le16(0);
|
||||
|
||||
if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
|
||||
if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
|
||||
&he_oper_vht_cap, ht_oper,
|
||||
&vht_chandef)) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
|
||||
@ -232,8 +242,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
||||
ret = IEEE80211_STA_DISABLE_HE;
|
||||
goto out;
|
||||
}
|
||||
} else if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_oper,
|
||||
ht_oper, &vht_chandef)) {
|
||||
} else if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
|
||||
vht_cap_info,
|
||||
vht_oper, ht_oper,
|
||||
&vht_chandef)) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
sdata_info(sdata,
|
||||
"AP VHT information is invalid, disable VHT\n");
|
||||
@ -329,6 +341,7 @@ out:
|
||||
static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
const struct ieee80211_ht_cap *ht_cap,
|
||||
const struct ieee80211_vht_cap *vht_cap,
|
||||
const struct ieee80211_ht_operation *ht_oper,
|
||||
const struct ieee80211_vht_operation *vht_oper,
|
||||
const struct ieee80211_he_operation *he_oper,
|
||||
@ -343,6 +356,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
|
||||
u16 ht_opmode;
|
||||
u32 flags;
|
||||
enum ieee80211_sta_rx_bandwidth new_sta_bw;
|
||||
u32 vht_cap_info = 0;
|
||||
int ret;
|
||||
|
||||
/* if HT was/is disabled, don't track any bandwidth changes */
|
||||
@ -371,8 +385,11 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
|
||||
}
|
||||
|
||||
if (vht_cap)
|
||||
vht_cap_info = le32_to_cpu(vht_cap->vht_cap_info);
|
||||
|
||||
/* calculate new channel (type) based on HT/VHT/HE operation IEs */
|
||||
flags = ieee80211_determine_chantype(sdata, sband, chan,
|
||||
flags = ieee80211_determine_chantype(sdata, sband, chan, vht_cap_info,
|
||||
ht_oper, vht_oper, he_oper,
|
||||
&chandef, true);
|
||||
|
||||
@ -658,6 +675,8 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
|
||||
he_cap->he_cap_elem.phy_cap_info);
|
||||
pos = skb_put(skb, he_cap_size);
|
||||
ieee80211_ie_build_he_cap(pos, he_cap, pos + he_cap_size);
|
||||
|
||||
ieee80211_ie_build_he_6ghz_cap(sdata, skb);
|
||||
}
|
||||
|
||||
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
@ -731,6 +750,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
2 + 1 + sizeof(struct ieee80211_he_cap_elem) + /* HE */
|
||||
sizeof(struct ieee80211_he_mcs_nss_supp) +
|
||||
IEEE80211_HE_PPE_THRES_MAX_LEN +
|
||||
2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
|
||||
assoc_data->ie_len + /* extra IEs */
|
||||
(assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) +
|
||||
9, /* WMM */
|
||||
@ -903,7 +923,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
if (sband->band != NL80211_BAND_6GHZ &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
|
||||
sband, chan, sdata->smps_mode);
|
||||
|
||||
@ -957,7 +978,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
offset = noffset;
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
if (sband->band != NL80211_BAND_6GHZ &&
|
||||
!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
ieee80211_add_vht_ie(sdata, skb, sband,
|
||||
&assoc_data->ap_vht_cap);
|
||||
|
||||
@ -1324,6 +1346,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_band current_band;
|
||||
struct ieee80211_csa_ie csa_ie;
|
||||
struct ieee80211_channel_switch ch_switch;
|
||||
struct ieee80211_bss *bss;
|
||||
int res;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
@ -1335,7 +1358,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
|
||||
current_band = cbss->channel->band;
|
||||
bss = (void *)cbss->priv;
|
||||
res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
|
||||
bss->vht_cap_info,
|
||||
ifmgd->flags,
|
||||
ifmgd->associated->bssid, &csa_ie);
|
||||
|
||||
@ -1508,6 +1533,7 @@ 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;
|
||||
}
|
||||
@ -2145,7 +2171,8 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
|
||||
if (sband->band == NL80211_BAND_5GHZ)
|
||||
if (sband->band == NL80211_BAND_5GHZ ||
|
||||
sband->band == NL80211_BAND_6GHZ)
|
||||
use_short_slot = true;
|
||||
|
||||
if (use_protection != bss_conf->use_cts_prot) {
|
||||
@ -3234,6 +3261,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
||||
const struct cfg80211_bss_ies *bss_ies = NULL;
|
||||
struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
|
||||
bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
|
||||
u32 changed = 0;
|
||||
int err;
|
||||
bool ret;
|
||||
@ -3275,11 +3303,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
* 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
|
||||
* "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
|
||||
*/
|
||||
if ((assoc_data->wmm && !elems->wmm_param) ||
|
||||
(!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
|
||||
(!elems->ht_cap_elem || !elems->ht_operation)) ||
|
||||
(!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
||||
(!elems->vht_cap_elem || !elems->vht_operation))) {
|
||||
if (!is_6ghz &&
|
||||
((assoc_data->wmm && !elems->wmm_param) ||
|
||||
(!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
|
||||
(!elems->ht_cap_elem || !elems->ht_operation)) ||
|
||||
(!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
||||
(!elems->vht_cap_elem || !elems->vht_operation)))) {
|
||||
const struct cfg80211_bss_ies *ies;
|
||||
struct ieee802_11_elems bss_elems;
|
||||
|
||||
@ -3337,7 +3366,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
* We previously checked these in the beacon/probe response, so
|
||||
* they should be present here. This is just a safety net.
|
||||
*/
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
|
||||
if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
|
||||
(!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
|
||||
sdata_info(sdata,
|
||||
"HT AP is missing WMM params or HT capability/operation\n");
|
||||
@ -3345,7 +3374,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
||||
if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
||||
(!elems->vht_cap_elem || !elems->vht_operation)) {
|
||||
sdata_info(sdata,
|
||||
"VHT AP is missing VHT capability/operation\n");
|
||||
@ -3353,6 +3382,14 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
|
||||
!elems->he_6ghz_capa) {
|
||||
sdata_info(sdata,
|
||||
"HE 6 GHz AP is missing HE 6 GHz band capability\n");
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&sdata->local->sta_mtx);
|
||||
/*
|
||||
* station info was already allocated and inserted before
|
||||
@ -3395,6 +3432,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
|
||||
elems->he_cap,
|
||||
elems->he_cap_len,
|
||||
elems->he_6ghz_capa,
|
||||
sta);
|
||||
|
||||
bss_conf->he_support = sta->sta.he_cap.has_he;
|
||||
@ -4094,8 +4132,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
|
||||
|
||||
if (ieee80211_config_bw(sdata, sta,
|
||||
elems.ht_cap_elem, elems.ht_operation,
|
||||
if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem,
|
||||
elems.vht_cap_elem, elems.ht_operation,
|
||||
elems.vht_operation, elems.he_operation,
|
||||
bssid, &changed)) {
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
@ -4812,6 +4850,8 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
const struct ieee80211_he_operation *he_oper = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct cfg80211_chan_def chandef;
|
||||
bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
|
||||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
int ret;
|
||||
u32 i;
|
||||
bool have_80mhz;
|
||||
@ -4823,21 +4863,23 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
IEEE80211_STA_DISABLE_160MHZ);
|
||||
|
||||
/* disable HT/VHT/HE if we don't support them */
|
||||
if (!sband->ht_cap.ht_supported) {
|
||||
if (!sband->ht_cap.ht_supported && !is_6ghz) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
if (!sband->vht_cap.vht_supported)
|
||||
if (!sband->vht_cap.vht_supported && !is_6ghz) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
if (!ieee80211_get_he_sta_cap(sband))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) {
|
||||
const u8 *ht_oper_ie, *ht_cap_ie;
|
||||
|
||||
ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
|
||||
@ -4854,7 +4896,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && !is_6ghz) {
|
||||
const u8 *vht_oper_ie, *vht_cap;
|
||||
|
||||
vht_oper_ie = ieee80211_bss_get_ie(cbss,
|
||||
@ -4910,6 +4952,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
|
||||
cbss->channel,
|
||||
bss->vht_cap_info,
|
||||
ht_oper, vht_oper, he_oper,
|
||||
&chandef, false);
|
||||
|
||||
@ -4918,6 +4961,11 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ifmgd->flags & IEEE80211_STA_DISABLE_HE && is_6ghz) {
|
||||
sdata_info(sdata, "Rejecting non-HE 6/7 GHz connection");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* will change later if needed */
|
||||
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
||||
|
||||
@ -5299,6 +5347,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
||||
int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_assoc_request *req)
|
||||
{
|
||||
bool is_6ghz = req->bss->channel->band == NL80211_BAND_6GHZ;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss *bss = (void *)req->bss->priv;
|
||||
@ -5441,14 +5490,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation))
|
||||
assoc_data->ap_ht_param =
|
||||
((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
|
||||
else
|
||||
else if (!is_6ghz)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
|
||||
vht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_VHT_CAPABILITY);
|
||||
if (vht_ie && vht_ie[1] >= sizeof(struct ieee80211_vht_cap))
|
||||
memcpy(&assoc_data->ap_vht_cap, vht_ie + 2,
|
||||
sizeof(struct ieee80211_vht_cap));
|
||||
else
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
else if (!is_6ghz)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (WARN((sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD) &&
|
||||
@ -5549,7 +5599,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
assoc_data->timeout_started = true;
|
||||
assoc_data->need_beacon = true;
|
||||
} else if (beacon_ies) {
|
||||
const u8 *ie;
|
||||
const struct element *elem;
|
||||
u8 dtim_count = 0;
|
||||
|
||||
ieee80211_get_dtim(beacon_ies, &dtim_count,
|
||||
@ -5566,15 +5616,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->vif.bss_conf.sync_dtim_count = dtim_count;
|
||||
}
|
||||
|
||||
ie = cfg80211_find_ext_ie(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION,
|
||||
beacon_ies->data, beacon_ies->len);
|
||||
if (ie && ie[1] >= 3)
|
||||
sdata->vif.bss_conf.profile_periodicity = ie[4];
|
||||
elem = cfg80211_find_ext_elem(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION,
|
||||
beacon_ies->data, beacon_ies->len);
|
||||
if (elem && elem->datalen >= 3)
|
||||
sdata->vif.bss_conf.profile_periodicity = elem->data[2];
|
||||
|
||||
ie = cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY,
|
||||
beacon_ies->data, beacon_ies->len);
|
||||
if (ie && ie[1] >= 11 &&
|
||||
(ie[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
|
||||
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
|
||||
beacon_ies->data, beacon_ies->len);
|
||||
if (elem && elem->datalen >= 11 &&
|
||||
(elem->data[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
|
||||
sdata->vif.bss_conf.ema_ap = true;
|
||||
} else {
|
||||
assoc_data->timeout = jiffies;
|
||||
|
@ -93,13 +93,44 @@ static u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
|
||||
* This function cleans up the SKB, i.e. it removes all the stuff
|
||||
* only useful for monitoring.
|
||||
*/
|
||||
static void remove_monitor_info(struct sk_buff *skb,
|
||||
unsigned int present_fcs_len,
|
||||
unsigned int rtap_space)
|
||||
static struct sk_buff *ieee80211_clean_skb(struct sk_buff *skb,
|
||||
unsigned int present_fcs_len,
|
||||
unsigned int rtap_space)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
unsigned int hdrlen;
|
||||
__le16 fc;
|
||||
|
||||
if (present_fcs_len)
|
||||
__pskb_trim(skb, skb->len - present_fcs_len);
|
||||
__pskb_pull(skb, rtap_space);
|
||||
|
||||
hdr = (void *)skb->data;
|
||||
fc = hdr->frame_control;
|
||||
|
||||
/*
|
||||
* Remove the HT-Control field (if present) on management
|
||||
* frames after we've sent the frame to monitoring. We
|
||||
* (currently) don't need it, and don't properly parse
|
||||
* frames with it present, due to the assumption of a
|
||||
* fixed management header length.
|
||||
*/
|
||||
if (likely(!ieee80211_is_mgmt(fc) || !ieee80211_has_order(fc)))
|
||||
return skb;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(fc);
|
||||
hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_ORDER);
|
||||
|
||||
if (!pskb_may_pull(skb, hdrlen)) {
|
||||
dev_kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memmove(skb->data + IEEE80211_HT_CTL_LEN, skb->data,
|
||||
hdrlen - IEEE80211_HT_CTL_LEN);
|
||||
__pskb_pull(skb, IEEE80211_HT_CTL_LEN);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,
|
||||
@ -827,8 +858,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
remove_monitor_info(origskb, present_fcs_len, rtap_space);
|
||||
return origskb;
|
||||
return ieee80211_clean_skb(origskb, present_fcs_len,
|
||||
rtap_space);
|
||||
}
|
||||
|
||||
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space);
|
||||
@ -871,8 +902,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
if (!origskb)
|
||||
return NULL;
|
||||
|
||||
remove_monitor_info(origskb, present_fcs_len, rtap_space);
|
||||
return origskb;
|
||||
return ieee80211_clean_skb(origskb, present_fcs_len, rtap_space);
|
||||
}
|
||||
|
||||
static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
|
||||
@ -3095,9 +3125,10 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
|
||||
!(status->flag & RX_FLAG_NO_SIGNAL_VAL))
|
||||
sig = status->signal;
|
||||
|
||||
cfg80211_report_obss_beacon(rx->local->hw.wiphy,
|
||||
rx->skb->data, rx->skb->len,
|
||||
status->freq, sig);
|
||||
cfg80211_report_obss_beacon_khz(rx->local->hw.wiphy,
|
||||
rx->skb->data, rx->skb->len,
|
||||
ieee80211_rx_status_to_khz(status),
|
||||
sig);
|
||||
rx->flags |= IEEE80211_RX_BEACON_REPORTED;
|
||||
}
|
||||
|
||||
@ -3353,19 +3384,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WLAN_CATEGORY_SA_QUERY:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.sa_query)))
|
||||
break;
|
||||
|
||||
switch (mgmt->u.action.u.sa_query.action) {
|
||||
case WLAN_ACTION_SA_QUERY_REQUEST:
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||
break;
|
||||
ieee80211_process_sa_query_req(sdata, mgmt, len);
|
||||
goto handled;
|
||||
}
|
||||
break;
|
||||
case WLAN_CATEGORY_SELF_PROTECTED:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.self_prot.action_code)))
|
||||
@ -3443,8 +3461,9 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
|
||||
!(status->flag & RX_FLAG_NO_SIGNAL_VAL))
|
||||
sig = status->signal;
|
||||
|
||||
if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig,
|
||||
rx->skb->data, rx->skb->len, 0)) {
|
||||
if (cfg80211_rx_mgmt_khz(&rx->sdata->wdev,
|
||||
ieee80211_rx_status_to_khz(status), sig,
|
||||
rx->skb->data, rx->skb->len, 0)) {
|
||||
if (rx->sta)
|
||||
rx->sta->rx_stats.packets++;
|
||||
dev_kfree_skb(rx->skb);
|
||||
@ -3454,6 +3473,41 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_action_post_userspace(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
|
||||
int len = rx->skb->len;
|
||||
|
||||
if (!ieee80211_is_action(mgmt->frame_control))
|
||||
return RX_CONTINUE;
|
||||
|
||||
switch (mgmt->u.action.category) {
|
||||
case WLAN_CATEGORY_SA_QUERY:
|
||||
if (len < (IEEE80211_MIN_ACTION_SIZE +
|
||||
sizeof(mgmt->u.action.u.sa_query)))
|
||||
break;
|
||||
|
||||
switch (mgmt->u.action.u.sa_query.action) {
|
||||
case WLAN_ACTION_SA_QUERY_REQUEST:
|
||||
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||
break;
|
||||
ieee80211_process_sa_query_req(sdata, mgmt, len);
|
||||
goto handled;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return RX_CONTINUE;
|
||||
|
||||
handled:
|
||||
if (rx->sta)
|
||||
rx->sta->rx_stats.packets++;
|
||||
dev_kfree_skb(rx->skb);
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
@ -3734,6 +3788,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
||||
CALL_RXH(ieee80211_rx_h_mgmt_check);
|
||||
CALL_RXH(ieee80211_rx_h_action);
|
||||
CALL_RXH(ieee80211_rx_h_userspace_mgmt);
|
||||
CALL_RXH(ieee80211_rx_h_action_post_userspace);
|
||||
CALL_RXH(ieee80211_rx_h_action_return);
|
||||
CALL_RXH(ieee80211_rx_h_mgmt);
|
||||
|
||||
|
@ -132,6 +132,12 @@ ieee80211_update_bss_from_elems(struct ieee80211_local *local,
|
||||
bss->beacon_rate =
|
||||
&sband->bitrates[rx_status->rate_idx];
|
||||
}
|
||||
|
||||
if (elems->vht_cap_elem)
|
||||
bss->vht_cap_info =
|
||||
le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
|
||||
else
|
||||
bss->vht_cap_info = 0;
|
||||
}
|
||||
|
||||
struct ieee80211_bss *
|
||||
@ -307,8 +313,9 @@ ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef,
|
||||
}
|
||||
|
||||
/* return false if no more work */
|
||||
static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
|
||||
static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct cfg80211_scan_request *req;
|
||||
struct cfg80211_chan_def chandef;
|
||||
u8 bands_used = 0;
|
||||
@ -355,7 +362,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
|
||||
if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT)
|
||||
flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT;
|
||||
|
||||
ielen = ieee80211_build_preq_ies(local,
|
||||
ielen = ieee80211_build_preq_ies(sdata,
|
||||
(u8 *)local->hw_scan_req->req.ie,
|
||||
local->hw_scan_ies_bufsize,
|
||||
&local->hw_scan_req->ies,
|
||||
@ -395,9 +402,12 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
if (WARN_ON(!local->scan_req))
|
||||
return;
|
||||
|
||||
scan_sdata = rcu_dereference_protected(local->scan_sdata,
|
||||
lockdep_is_held(&local->mtx));
|
||||
|
||||
if (hw_scan && !aborted &&
|
||||
!ieee80211_hw_check(&local->hw, SINGLE_SCAN_ON_ALL_BANDS) &&
|
||||
ieee80211_prep_hw_scan(local)) {
|
||||
ieee80211_prep_hw_scan(scan_sdata)) {
|
||||
int rc;
|
||||
|
||||
rc = drv_hw_scan(local,
|
||||
@ -426,9 +436,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
cfg80211_scan_done(scan_req, &local->scan_info);
|
||||
}
|
||||
RCU_INIT_POINTER(local->scan_req, NULL);
|
||||
|
||||
scan_sdata = rcu_dereference_protected(local->scan_sdata,
|
||||
lockdep_is_held(&local->mtx));
|
||||
RCU_INIT_POINTER(local->scan_sdata, NULL);
|
||||
|
||||
local->scanning = 0;
|
||||
@ -770,7 +777,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_recalc_idle(local);
|
||||
|
||||
if (hw_scan) {
|
||||
WARN_ON(!ieee80211_prep_hw_scan(local));
|
||||
WARN_ON(!ieee80211_prep_hw_scan(sdata));
|
||||
rc = drv_hw_scan(local, sdata, local->hw_scan_req);
|
||||
} else {
|
||||
rc = ieee80211_start_sw_scan(local, sdata);
|
||||
@ -1268,7 +1275,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
|
||||
|
||||
ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
|
||||
ieee80211_build_preq_ies(sdata, ie, num_bands * iebufsz,
|
||||
&sched_scan_ies, req->ie,
|
||||
req->ie_len, bands_used, rate_masks, &chandef,
|
||||
flags);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2007-2008, Intel Corporation
|
||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018, 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/ieee80211.h>
|
||||
@ -22,6 +22,7 @@
|
||||
int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee802_11_elems *elems,
|
||||
enum nl80211_band current_band,
|
||||
u32 vht_cap_info,
|
||||
u32 sta_flags, u8 *bssid,
|
||||
struct ieee80211_csa_ie *csa_ie)
|
||||
{
|
||||
@ -150,6 +151,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
/* ignore if parsing fails */
|
||||
if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
|
||||
vht_cap_info,
|
||||
&vht_oper, &ht_oper,
|
||||
&new_vht_chandef))
|
||||
new_vht_chandef.chan = NULL;
|
||||
|
@ -649,10 +649,17 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
|
||||
info->status.ack_signal,
|
||||
info->status.is_valid_ack_signal,
|
||||
GFP_ATOMIC);
|
||||
else
|
||||
else if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
cfg80211_mgmt_tx_status(&sdata->wdev, cookie,
|
||||
skb->data, skb->len,
|
||||
acked, GFP_ATOMIC);
|
||||
else
|
||||
cfg80211_control_port_tx_status(&sdata->wdev,
|
||||
cookie,
|
||||
skb->data,
|
||||
skb->len,
|
||||
acked,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
/* disable bottom halves when entering the Tx path */
|
||||
local_bh_disable();
|
||||
__ieee80211_subif_start_xmit(skb, dev, flags, 0);
|
||||
__ieee80211_subif_start_xmit(skb, dev, flags, 0, NULL);
|
||||
local_bh_enable();
|
||||
|
||||
return ret;
|
||||
|
@ -2436,13 +2436,19 @@ int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_store_ack_skb(struct ieee80211_local *local,
|
||||
static u16 ieee80211_store_ack_skb(struct ieee80211_local *local,
|
||||
struct sk_buff *skb,
|
||||
u32 *info_flags)
|
||||
u32 *info_flags,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct sk_buff *ack_skb = skb_clone_sk(skb);
|
||||
struct sk_buff *ack_skb;
|
||||
u16 info_id = 0;
|
||||
|
||||
if (skb->sk)
|
||||
ack_skb = skb_clone_sk(skb);
|
||||
else
|
||||
ack_skb = skb_clone(skb, GFP_ATOMIC);
|
||||
|
||||
if (ack_skb) {
|
||||
unsigned long flags;
|
||||
int id;
|
||||
@ -2455,6 +2461,10 @@ static int ieee80211_store_ack_skb(struct ieee80211_local *local,
|
||||
if (id >= 0) {
|
||||
info_id = id;
|
||||
*info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
if (cookie) {
|
||||
*cookie = ieee80211_mgmt_tx_cookie(local);
|
||||
IEEE80211_SKB_CB(ack_skb)->ack.cookie = *cookie;
|
||||
}
|
||||
} else {
|
||||
kfree_skb(ack_skb);
|
||||
}
|
||||
@ -2484,7 +2494,8 @@ static int ieee80211_store_ack_skb(struct ieee80211_local *local,
|
||||
*/
|
||||
static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb, u32 info_flags,
|
||||
struct sta_info *sta, u32 ctrl_flags)
|
||||
struct sta_info *sta, u32 ctrl_flags,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_tx_info *info;
|
||||
@ -2755,9 +2766,11 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (unlikely(!multicast && skb->sk &&
|
||||
skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
|
||||
info_id = ieee80211_store_ack_skb(local, skb, &info_flags);
|
||||
if (unlikely(!multicast && ((skb->sk &&
|
||||
skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) ||
|
||||
ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS)))
|
||||
info_id = ieee80211_store_ack_skb(local, skb, &info_flags,
|
||||
cookie);
|
||||
|
||||
/*
|
||||
* If the skb is shared we need to obtain our own copy.
|
||||
@ -3913,7 +3926,8 @@ EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags,
|
||||
u32 ctrl_flags)
|
||||
u32 ctrl_flags,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
@ -3983,7 +3997,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
skb_mark_not_on_list(skb);
|
||||
|
||||
skb = ieee80211_build_hdr(sdata, skb, info_flags,
|
||||
sta, ctrl_flags);
|
||||
sta, ctrl_flags, cookie);
|
||||
if (IS_ERR(skb)) {
|
||||
kfree_skb_list(next);
|
||||
goto out;
|
||||
@ -4125,9 +4139,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
__skb_queue_head_init(&queue);
|
||||
ieee80211_convert_to_unicast(skb, dev, &queue);
|
||||
while ((skb = __skb_dequeue(&queue)))
|
||||
__ieee80211_subif_start_xmit(skb, dev, 0, 0);
|
||||
__ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
|
||||
} else {
|
||||
__ieee80211_subif_start_xmit(skb, dev, 0, 0);
|
||||
__ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL);
|
||||
}
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@ -4215,7 +4229,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
if (unlikely(!multicast && skb->sk &&
|
||||
skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
|
||||
ieee80211_store_ack_skb(local, skb, &info->flags);
|
||||
ieee80211_store_ack_skb(local, skb, &info->flags, NULL);
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
@ -4299,7 +4313,7 @@ ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
|
||||
goto out;
|
||||
}
|
||||
|
||||
skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, 0);
|
||||
skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, 0, NULL);
|
||||
if (IS_ERR(skb))
|
||||
goto out;
|
||||
|
||||
@ -5339,14 +5353,15 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len,
|
||||
const u8 *dest, __be16 proto, bool unencrypted)
|
||||
const u8 *dest, __be16 proto, bool unencrypted,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct sk_buff *skb;
|
||||
struct ethhdr *ehdr;
|
||||
u32 ctrl_flags = 0;
|
||||
u32 flags;
|
||||
u32 flags = 0;
|
||||
|
||||
/* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
|
||||
* or Pre-Authentication
|
||||
@ -5359,9 +5374,13 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
|
||||
|
||||
if (unencrypted)
|
||||
flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||
else
|
||||
flags = 0;
|
||||
flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
|
||||
|
||||
if (cookie)
|
||||
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
IEEE80211_TX_CTL_INJECTED;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
sizeof(struct ethhdr) + len);
|
||||
@ -5382,10 +5401,15 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
/* mutex lock is only needed for incrementing the cookie counter */
|
||||
mutex_lock(&local->mtx);
|
||||
|
||||
local_bh_disable();
|
||||
__ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags);
|
||||
__ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie);
|
||||
local_bh_enable();
|
||||
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5412,7 +5436,8 @@ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
local_bh_disable();
|
||||
__ieee80211_subif_start_xmit(skb, skb->dev, 0,
|
||||
IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP);
|
||||
IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP,
|
||||
NULL);
|
||||
local_bh_enable();
|
||||
|
||||
return 0;
|
||||
|
@ -936,6 +936,10 @@ static void ieee80211_parse_extension_element(u32 *crc,
|
||||
len >= ieee80211_he_spr_size(data))
|
||||
elems->he_spr = data;
|
||||
break;
|
||||
case WLAN_EID_EXT_HE_6GHZ_CAPA:
|
||||
if (len == sizeof(*elems->he_6ghz_capa))
|
||||
elems->he_6ghz_capa = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1659,7 +1663,20 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
|
||||
static u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end)
|
||||
{
|
||||
if ((end - pos) < 5)
|
||||
return pos;
|
||||
|
||||
*pos++ = WLAN_EID_EXTENSION;
|
||||
*pos++ = 1 + sizeof(cap);
|
||||
*pos++ = WLAN_EID_EXT_HE_6GHZ_CAPA;
|
||||
memcpy(pos, &cap, sizeof(cap));
|
||||
|
||||
return pos + 2;
|
||||
}
|
||||
|
||||
static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
|
||||
u8 *buffer, size_t buffer_len,
|
||||
const u8 *ie, size_t ie_len,
|
||||
enum nl80211_band band,
|
||||
@ -1667,6 +1684,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
size_t *offset, u32 flags)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
u8 *pos = buffer, *end = buffer + buffer_len;
|
||||
@ -1844,6 +1862,14 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
|
||||
pos = ieee80211_ie_build_he_cap(pos, he_cap, end);
|
||||
if (!pos)
|
||||
goto out_err;
|
||||
|
||||
if (sband->band == NL80211_BAND_6GHZ) {
|
||||
enum nl80211_iftype iftype =
|
||||
ieee80211_vif_type_p2p(&sdata->vif);
|
||||
__le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype);
|
||||
|
||||
pos = ieee80211_write_he_6ghz_cap(pos, cap, end);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1858,7 +1884,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
|
||||
return pos - buffer;
|
||||
}
|
||||
|
||||
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
|
||||
int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer,
|
||||
size_t buffer_len,
|
||||
struct ieee80211_scan_ies *ie_desc,
|
||||
const u8 *ie, size_t ie_len,
|
||||
@ -1873,7 +1899,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
|
||||
|
||||
for (i = 0; i < NUM_NL80211_BANDS; i++) {
|
||||
if (bands_used & BIT(i)) {
|
||||
pos += ieee80211_build_preq_ies_band(local,
|
||||
pos += ieee80211_build_preq_ies_band(sdata,
|
||||
buffer + pos,
|
||||
buffer_len - pos,
|
||||
ie, ie_len, i,
|
||||
@ -1935,7 +1961,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
|
||||
return NULL;
|
||||
|
||||
rate_masks[chan->band] = ratemask;
|
||||
ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
|
||||
ies_len = ieee80211_build_preq_ies(sdata, skb_tail_pointer(skb),
|
||||
skb_tailroom(skb), &dummy_ie_desc,
|
||||
ie, ie_len, BIT(chan->band),
|
||||
rate_masks, &chandef, flags);
|
||||
@ -2835,6 +2861,50 @@ end:
|
||||
return pos;
|
||||
}
|
||||
|
||||
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_sband_iftype_data *iftd;
|
||||
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
|
||||
u8 *pos;
|
||||
u16 cap;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
iftd = ieee80211_get_sband_iftype_data(sband, iftype);
|
||||
if (WARN_ON(!iftd))
|
||||
return;
|
||||
|
||||
cap = le16_to_cpu(iftd->he_6ghz_capa.capa);
|
||||
cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS;
|
||||
|
||||
switch (sdata->smps_mode) {
|
||||
case IEEE80211_SMPS_AUTOMATIC:
|
||||
case IEEE80211_SMPS_NUM_MODES:
|
||||
WARN_ON(1);
|
||||
/* fall through */
|
||||
case IEEE80211_SMPS_OFF:
|
||||
cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED,
|
||||
IEEE80211_HE_6GHZ_CAP_SM_PS);
|
||||
break;
|
||||
case IEEE80211_SMPS_STATIC:
|
||||
cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC,
|
||||
IEEE80211_HE_6GHZ_CAP_SM_PS);
|
||||
break;
|
||||
case IEEE80211_SMPS_DYNAMIC:
|
||||
cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC,
|
||||
IEEE80211_HE_6GHZ_CAP_SM_PS);
|
||||
break;
|
||||
}
|
||||
|
||||
pos = skb_put(skb, 2 + 1 + sizeof(cap));
|
||||
ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap),
|
||||
pos + 2 + 1 + sizeof(cap));
|
||||
}
|
||||
|
||||
u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
u16 prot_mode, bool rifs_mode)
|
||||
@ -2958,13 +3028,18 @@ u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
||||
return pos + sizeof(struct ieee80211_vht_operation);
|
||||
}
|
||||
|
||||
u8 *ieee80211_ie_build_he_oper(u8 *pos)
|
||||
u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_he_operation *he_oper;
|
||||
struct ieee80211_he_6ghz_oper *he_6ghz_op;
|
||||
u32 he_oper_params;
|
||||
u8 ie_len = 1 + sizeof(struct ieee80211_he_operation);
|
||||
|
||||
if (chandef->chan->band == NL80211_BAND_6GHZ)
|
||||
ie_len += sizeof(struct ieee80211_he_6ghz_oper);
|
||||
|
||||
*pos++ = WLAN_EID_EXTENSION;
|
||||
*pos++ = 1 + sizeof(struct ieee80211_he_operation);
|
||||
*pos++ = ie_len;
|
||||
*pos++ = WLAN_EID_EXT_HE_OPERATION;
|
||||
|
||||
he_oper_params = 0;
|
||||
@ -2974,16 +3049,68 @@ u8 *ieee80211_ie_build_he_oper(u8 *pos)
|
||||
IEEE80211_HE_OPERATION_ER_SU_DISABLE);
|
||||
he_oper_params |= u32_encode_bits(1,
|
||||
IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
|
||||
if (chandef->chan->band == NL80211_BAND_6GHZ)
|
||||
he_oper_params |= u32_encode_bits(1,
|
||||
IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
|
||||
|
||||
he_oper = (struct ieee80211_he_operation *)pos;
|
||||
he_oper->he_oper_params = cpu_to_le32(he_oper_params);
|
||||
|
||||
/* don't require special HE peer rates */
|
||||
he_oper->he_mcs_nss_set = cpu_to_le16(0xffff);
|
||||
pos += sizeof(struct ieee80211_he_operation);
|
||||
|
||||
/* TODO add VHT operational and 6GHz operational subelement? */
|
||||
if (chandef->chan->band != NL80211_BAND_6GHZ)
|
||||
goto out;
|
||||
|
||||
return pos + sizeof(struct ieee80211_vht_operation);
|
||||
/* TODO add VHT operational */
|
||||
he_6ghz_op = (struct ieee80211_he_6ghz_oper *)pos;
|
||||
he_6ghz_op->minrate = 6; /* 6 Mbps */
|
||||
he_6ghz_op->primary =
|
||||
ieee80211_frequency_to_channel(chandef->chan->center_freq);
|
||||
he_6ghz_op->ccfs0 =
|
||||
ieee80211_frequency_to_channel(chandef->center_freq1);
|
||||
if (chandef->center_freq2)
|
||||
he_6ghz_op->ccfs1 =
|
||||
ieee80211_frequency_to_channel(chandef->center_freq2);
|
||||
else
|
||||
he_6ghz_op->ccfs1 = 0;
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
/* Convert 160 MHz channel width to new style as interop
|
||||
* workaround.
|
||||
*/
|
||||
he_6ghz_op->control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
|
||||
he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0;
|
||||
if (chandef->chan->center_freq < chandef->center_freq1)
|
||||
he_6ghz_op->ccfs0 -= 8;
|
||||
else
|
||||
he_6ghz_op->ccfs0 += 8;
|
||||
fallthrough;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
he_6ghz_op->control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
he_6ghz_op->control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
he_6ghz_op->control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
|
||||
break;
|
||||
default:
|
||||
he_6ghz_op->control =
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
|
||||
break;
|
||||
}
|
||||
|
||||
pos += sizeof(struct ieee80211_he_6ghz_oper);
|
||||
|
||||
out:
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
|
||||
@ -3013,7 +3140,7 @@ bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
|
||||
bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
|
||||
const struct ieee80211_vht_operation *oper,
|
||||
const struct ieee80211_ht_operation *htop,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
@ -3025,6 +3152,10 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
|
||||
u32 vht_cap;
|
||||
bool support_80_80 = false;
|
||||
bool support_160 = false;
|
||||
u8 ext_nss_bw_supp = u32_get_bits(vht_cap_info,
|
||||
IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
|
||||
u8 supp_chwidth = u32_get_bits(vht_cap_info,
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
|
||||
|
||||
if (!oper || !htop)
|
||||
return false;
|
||||
@ -3044,11 +3175,48 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
|
||||
IEEE80211_HT_OP_MODE_CCFS2_MASK)
|
||||
>> IEEE80211_HT_OP_MODE_CCFS2_SHIFT;
|
||||
|
||||
/* when parsing (and we know how to) CCFS1 and CCFS2 are equivalent */
|
||||
ccf0 = ccfs0;
|
||||
ccf1 = ccfs1;
|
||||
if (!ccfs1 && ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW))
|
||||
|
||||
/* if not supported, parse as though we didn't understand it */
|
||||
if (!ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW))
|
||||
ext_nss_bw_supp = 0;
|
||||
|
||||
/*
|
||||
* Cf. IEEE 802.11 Table 9-250
|
||||
*
|
||||
* We really just consider that because it's inefficient to connect
|
||||
* at a higher bandwidth than we'll actually be able to use.
|
||||
*/
|
||||
switch ((supp_chwidth << 4) | ext_nss_bw_supp) {
|
||||
default:
|
||||
case 0x00:
|
||||
ccf1 = 0;
|
||||
support_160 = false;
|
||||
support_80_80 = false;
|
||||
break;
|
||||
case 0x01:
|
||||
support_80_80 = false;
|
||||
/* fall through */
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
ccf1 = ccfs2;
|
||||
break;
|
||||
case 0x10:
|
||||
ccf1 = ccfs1;
|
||||
break;
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
if (!ccfs1)
|
||||
ccf1 = ccfs2;
|
||||
else
|
||||
ccf1 = ccfs1;
|
||||
break;
|
||||
case 0x13:
|
||||
case 0x20:
|
||||
case 0x23:
|
||||
ccf1 = ccfs1;
|
||||
break;
|
||||
}
|
||||
|
||||
cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band);
|
||||
cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band);
|
||||
@ -3096,6 +3264,112 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
|
||||
const struct ieee80211_he_operation *he_oper,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_supported_band *sband;
|
||||
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct cfg80211_chan_def he_chandef = *chandef;
|
||||
const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
|
||||
bool support_80_80, support_160;
|
||||
u8 he_phy_cap;
|
||||
u32 freq;
|
||||
|
||||
if (chandef->chan->band != NL80211_BAND_6GHZ)
|
||||
return true;
|
||||
|
||||
sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ];
|
||||
|
||||
he_cap = ieee80211_get_he_iftype_cap(sband, iftype);
|
||||
if (!he_cap) {
|
||||
sdata_info(sdata, "Missing iftype sband data/HE cap");
|
||||
return false;
|
||||
}
|
||||
|
||||
he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0];
|
||||
support_160 =
|
||||
he_phy_cap &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
|
||||
support_80_80 =
|
||||
he_phy_cap &
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
|
||||
|
||||
if (!he_oper) {
|
||||
sdata_info(sdata,
|
||||
"HE is not advertised on (on %d MHz), expect issues\n",
|
||||
chandef->chan->center_freq);
|
||||
return false;
|
||||
}
|
||||
|
||||
he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
|
||||
|
||||
if (!he_6ghz_oper) {
|
||||
sdata_info(sdata,
|
||||
"HE 6GHz operation missing (on %d MHz), expect issues\n",
|
||||
chandef->chan->center_freq);
|
||||
return false;
|
||||
}
|
||||
|
||||
freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary,
|
||||
NL80211_BAND_6GHZ);
|
||||
he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
|
||||
|
||||
switch (u8_get_bits(he_6ghz_oper->control,
|
||||
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) {
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_20;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_40;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80;
|
||||
break;
|
||||
case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ:
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80;
|
||||
if (!he_6ghz_oper->ccfs1)
|
||||
break;
|
||||
if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) {
|
||||
if (support_160)
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_160;
|
||||
} else {
|
||||
if (support_80_80)
|
||||
he_chandef.width = NL80211_CHAN_WIDTH_80P80;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (he_chandef.width == NL80211_CHAN_WIDTH_160) {
|
||||
he_chandef.center_freq1 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
} else {
|
||||
he_chandef.center_freq1 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0,
|
||||
NL80211_BAND_6GHZ);
|
||||
he_chandef.center_freq2 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(&he_chandef)) {
|
||||
sdata_info(sdata,
|
||||
"HE 6GHz operation resulted in invalid chandef: %d MHz/%d/%d MHz/%d MHz\n",
|
||||
he_chandef.chan ? he_chandef.chan->center_freq : 0,
|
||||
he_chandef.width,
|
||||
he_chandef.center_freq1,
|
||||
he_chandef.center_freq2);
|
||||
return false;
|
||||
}
|
||||
|
||||
*chandef = he_chandef;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
|
||||
const struct ieee80211_supported_band *sband,
|
||||
const u8 *srates, int srates_len, u32 *rates)
|
||||
|
@ -181,8 +181,8 @@ config CFG80211_CRDA_SUPPORT
|
||||
default y
|
||||
help
|
||||
You should enable this option unless you know for sure you have no
|
||||
need for it, for example when using internal regdb (above) or the
|
||||
database loaded as a firmware file.
|
||||
need for it, for example when using the regulatory database loaded as
|
||||
a firmware file.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2018 Intel Corporation
|
||||
* Copyright 2018-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
@ -919,7 +919,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
|
||||
width = 10;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
if (!ht_cap->ht_supported)
|
||||
if (!ht_cap->ht_supported &&
|
||||
chandef->chan->band != NL80211_BAND_6GHZ)
|
||||
return false;
|
||||
/* fall through */
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
@ -928,6 +929,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
width = 40;
|
||||
if (chandef->chan->band == NL80211_BAND_6GHZ)
|
||||
break;
|
||||
if (!ht_cap->ht_supported)
|
||||
return false;
|
||||
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
|
||||
@ -942,24 +945,29 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
|
||||
if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
|
||||
if (chandef->chan->band != NL80211_BAND_6GHZ &&
|
||||
cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
|
||||
return false;
|
||||
/* fall through */
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
if (!vht_cap->vht_supported)
|
||||
return false;
|
||||
prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
|
||||
width = 80;
|
||||
if (chandef->chan->band == NL80211_BAND_6GHZ)
|
||||
break;
|
||||
if (!vht_cap->vht_supported)
|
||||
return false;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
|
||||
width = 160;
|
||||
if (chandef->chan->band == NL80211_BAND_6GHZ)
|
||||
break;
|
||||
if (!vht_cap->vht_supported)
|
||||
return false;
|
||||
cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
|
||||
if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
|
||||
cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
|
||||
return false;
|
||||
prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
|
||||
width = 160;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2019 Intel Corporation
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
@ -791,6 +791,7 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
/* sanity check supported bands/channels */
|
||||
for (band = 0; band < NUM_NL80211_BANDS; band++) {
|
||||
u16 types = 0;
|
||||
bool have_he = false;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
if (!sband)
|
||||
@ -807,6 +808,11 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
!sband->n_bitrates))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(band == NL80211_BAND_6GHZ &&
|
||||
(sband->ht_cap.ht_supported ||
|
||||
sband->vht_cap.vht_supported)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Since cfg80211_disable_40mhz_24ghz is global, we can
|
||||
* modify the sband's ht data even if the driver uses a
|
||||
@ -854,8 +860,17 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
return -EINVAL;
|
||||
|
||||
types |= iftd->types_mask;
|
||||
|
||||
if (i == 0)
|
||||
have_he = iftd->he_cap.has_he;
|
||||
else
|
||||
have_he = have_he &&
|
||||
iftd->he_cap.has_he;
|
||||
}
|
||||
|
||||
if (WARN_ON(!have_he && band == NL80211_BAND_6GHZ))
|
||||
return -EINVAL;
|
||||
|
||||
have_band = true;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ struct cfg80211_cqm_config {
|
||||
u32 rssi_hyst;
|
||||
s32 last_rssi_event_value;
|
||||
int n_rssi_thresholds;
|
||||
s32 rssi_thresholds[0];
|
||||
s32 rssi_thresholds[];
|
||||
};
|
||||
|
||||
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
|
||||
|
@ -729,8 +729,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
|
||||
return rdev_mgmt_tx(rdev, wdev, params, cookie);
|
||||
}
|
||||
|
||||
bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
const u8 *buf, size_t len, u32 flags)
|
||||
bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
const u8 *buf, size_t len, u32 flags)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
@ -785,7 +785,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
|
||||
trace_cfg80211_return_bool(result);
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_mgmt);
|
||||
EXPORT_SYMBOL(cfg80211_rx_mgmt_khz);
|
||||
|
||||
void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
|
@ -329,6 +329,15 @@ he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
|
||||
[NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
|
||||
[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
|
||||
.len = NL80211_MAX_SUPP_RATES },
|
||||
[NL80211_TXRATE_HT] = { .type = NLA_BINARY,
|
||||
.len = NL80211_MAX_SUPP_HT_RATES },
|
||||
[NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
|
||||
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
|
||||
[NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
|
||||
@ -343,6 +352,12 @@ nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
|
||||
[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
|
||||
NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
|
||||
[NL80211_TID_CONFIG_ATTR_TX_RATE] =
|
||||
NLA_POLICY_NESTED(nl80211_txattr_policy),
|
||||
};
|
||||
|
||||
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
@ -363,6 +378,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
|
||||
[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
|
||||
[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
|
||||
@ -636,6 +652,12 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
[NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
|
||||
[NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
|
||||
[NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
|
||||
[NL80211_ATTR_HE_6GHZ_CAPABILITY] = {
|
||||
.type = NLA_EXACT_LEN,
|
||||
.len = sizeof(struct ieee80211_he_6ghz_capa),
|
||||
},
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@ -708,9 +730,16 @@ nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
|
||||
/* policy for GTK rekey offload attributes */
|
||||
static const struct nla_policy
|
||||
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
|
||||
[NL80211_REKEY_DATA_KEK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KEK_LEN),
|
||||
[NL80211_REKEY_DATA_KCK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KCK_LEN),
|
||||
[NL80211_REKEY_DATA_KEK] = {
|
||||
.type = NLA_BINARY,
|
||||
.len = NL80211_KEK_EXT_LEN
|
||||
},
|
||||
[NL80211_REKEY_DATA_KCK] = {
|
||||
.type = NLA_BINARY,
|
||||
.len = NL80211_KCK_EXT_LEN
|
||||
},
|
||||
[NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN_WARN(NL80211_REPLAY_CTR_LEN),
|
||||
[NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
@ -902,6 +931,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
|
||||
chan->center_freq))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
|
||||
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
|
||||
goto nla_put_failure;
|
||||
@ -1307,13 +1339,11 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
|
||||
}
|
||||
|
||||
static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
|
||||
struct nlattr *tb)
|
||||
u32 freq)
|
||||
{
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
if (tb == NULL)
|
||||
return NULL;
|
||||
chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
|
||||
chan = ieee80211_get_channel_khz(wiphy, freq);
|
||||
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
return NULL;
|
||||
return chan;
|
||||
@ -1539,6 +1569,7 @@ static int nl80211_send_coalesce(struct sk_buff *msg,
|
||||
|
||||
static int
|
||||
nl80211_send_iftype_data(struct sk_buff *msg,
|
||||
const struct ieee80211_supported_band *sband,
|
||||
const struct ieee80211_sband_iftype_data *iftdata)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
|
||||
@ -1562,6 +1593,12 @@ nl80211_send_iftype_data(struct sk_buff *msg,
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
if (sband->band == NL80211_BAND_6GHZ &&
|
||||
nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
|
||||
sizeof(iftdata->he_6ghz_capa),
|
||||
&iftdata->he_6ghz_capa))
|
||||
return -ENOBUFS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1610,7 +1647,7 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,
|
||||
if (!iftdata)
|
||||
return -ENOBUFS;
|
||||
|
||||
err = nl80211_send_iftype_data(msg,
|
||||
err = nl80211_send_iftype_data(msg, sband,
|
||||
&sband->iftype_data[i]);
|
||||
if (err)
|
||||
return err;
|
||||
@ -2768,13 +2805,17 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
|
||||
if (!attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
return -EINVAL;
|
||||
|
||||
control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
control_freq = MHZ_TO_KHZ(
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
|
||||
control_freq +=
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
|
||||
|
||||
memset(chandef, 0, sizeof(*chandef));
|
||||
|
||||
chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
|
||||
chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
|
||||
chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
chandef->center_freq1 = control_freq;
|
||||
chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
|
||||
chandef->freq1_offset = control_freq % 1000;
|
||||
chandef->center_freq2 = 0;
|
||||
|
||||
/* Primary channel not allowed */
|
||||
@ -2822,9 +2863,15 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
|
||||
} else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
|
||||
chandef->width =
|
||||
nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
|
||||
if (attrs[NL80211_ATTR_CENTER_FREQ1])
|
||||
if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
|
||||
chandef->center_freq1 =
|
||||
nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
|
||||
if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET])
|
||||
chandef->freq1_offset = nla_get_u32(
|
||||
attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]);
|
||||
else
|
||||
chandef->freq1_offset = 0;
|
||||
}
|
||||
if (attrs[NL80211_ATTR_CENTER_FREQ2])
|
||||
chandef->center_freq2 =
|
||||
nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
|
||||
@ -3257,6 +3304,9 @@ static int nl80211_send_chandef(struct sk_buff *msg,
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
|
||||
chandef->chan->center_freq))
|
||||
return -ENOBUFS;
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
|
||||
chandef->chan->freq_offset))
|
||||
return -ENOBUFS;
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
@ -4369,16 +4419,9 @@ static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
|
||||
[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
|
||||
.len = NL80211_MAX_SUPP_RATES },
|
||||
[NL80211_TXRATE_HT] = { .type = NLA_BINARY,
|
||||
.len = NL80211_MAX_SUPP_HT_RATES },
|
||||
[NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
|
||||
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
|
||||
struct nlattr *attrs[],
|
||||
enum nl80211_attrs attr,
|
||||
struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct nlattr *tb[NL80211_TXRATE_MAX + 1];
|
||||
@ -4409,14 +4452,14 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
|
||||
}
|
||||
|
||||
/* if no rates are given set it back to the defaults */
|
||||
if (!info->attrs[NL80211_ATTR_TX_RATES])
|
||||
if (!attrs[attr])
|
||||
goto out;
|
||||
|
||||
/* The nested attribute uses enum nl80211_band as the index. This maps
|
||||
* directly to the enum nl80211_band values used in cfg80211.
|
||||
*/
|
||||
BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
|
||||
nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
|
||||
nla_for_each_nested(tx_rates, attrs[attr], rem) {
|
||||
enum nl80211_band band = nla_type(tx_rates);
|
||||
int err;
|
||||
|
||||
@ -4921,7 +4964,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->attrs[NL80211_ATTR_TX_RATES]) {
|
||||
err = nl80211_parse_tx_bitrate_mask(info, ¶ms.beacon_rate);
|
||||
err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
|
||||
NL80211_ATTR_TX_RATES,
|
||||
¶ms.beacon_rate);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -5962,6 +6007,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
|
||||
nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
|
||||
params.he_6ghz_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
|
||||
params.airtime_weight =
|
||||
nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
|
||||
@ -6096,6 +6145,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
|
||||
params.he_6ghz_capa =
|
||||
nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
|
||||
params.opmode_notif_used = true;
|
||||
params.opmode_notif =
|
||||
@ -6140,10 +6193,14 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
|
||||
params.vht_capa = NULL;
|
||||
|
||||
/* HE requires WME */
|
||||
if (params.he_capa_len)
|
||||
if (params.he_capa_len || params.he_6ghz_capa)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
|
||||
if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa))
|
||||
return -EINVAL;
|
||||
|
||||
/* When you run into this, adjust the code below for the new flag */
|
||||
BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
|
||||
|
||||
@ -7701,6 +7758,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct wireless_dev *wdev = info->user_ptr[1];
|
||||
struct cfg80211_scan_request *request;
|
||||
struct nlattr *scan_freqs = NULL;
|
||||
bool scan_freqs_khz = false;
|
||||
struct nlattr *attr;
|
||||
struct wiphy *wiphy;
|
||||
int err, tmp, n_ssids = 0, n_channels, i;
|
||||
@ -7719,9 +7778,17 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
|
||||
n_channels = validate_scan_freqs(
|
||||
info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
|
||||
if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
|
||||
if (!wiphy_ext_feature_isset(wiphy,
|
||||
NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
|
||||
return -EOPNOTSUPP;
|
||||
scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
|
||||
scan_freqs_khz = true;
|
||||
} else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
|
||||
scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
|
||||
|
||||
if (scan_freqs) {
|
||||
n_channels = validate_scan_freqs(scan_freqs);
|
||||
if (!n_channels) {
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
@ -7769,13 +7836,16 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
|
||||
if (scan_freqs) {
|
||||
/* user specified, bail out if channel not found */
|
||||
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
|
||||
nla_for_each_nested(attr, scan_freqs, tmp) {
|
||||
struct ieee80211_channel *chan;
|
||||
int freq = nla_get_u32(attr);
|
||||
|
||||
chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
|
||||
if (!scan_freqs_khz)
|
||||
freq = MHZ_TO_KHZ(freq);
|
||||
|
||||
chan = ieee80211_get_channel_khz(wiphy, freq);
|
||||
if (!chan) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
@ -8871,6 +8941,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
|
||||
nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
|
||||
nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
|
||||
res->channel->freq_offset) ||
|
||||
nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
|
||||
nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
|
||||
jiffies_to_msecs(jiffies - intbss->ts)))
|
||||
@ -9139,6 +9211,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
|
||||
enum nl80211_auth_type auth_type;
|
||||
struct key_parse key;
|
||||
bool local_state_change;
|
||||
u32 freq;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
@ -9195,8 +9268,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
chan = nl80211_get_valid_chan(&rdev->wiphy,
|
||||
info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
|
||||
freq +=
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
|
||||
|
||||
chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
@ -9386,6 +9463,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
|
||||
struct cfg80211_assoc_request req = {};
|
||||
const u8 *bssid, *ssid;
|
||||
int err, ssid_len = 0;
|
||||
u32 freq;
|
||||
|
||||
if (dev->ieee80211_ptr->conn_owner_nlportid &&
|
||||
dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
|
||||
@ -9405,8 +9483,11 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
||||
chan = nl80211_get_valid_chan(&rdev->wiphy,
|
||||
info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
|
||||
freq +=
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
|
||||
chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
@ -10086,6 +10167,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
||||
struct cfg80211_connect_params connect;
|
||||
struct wiphy *wiphy;
|
||||
struct cfg80211_cached_keys *connkeys = NULL;
|
||||
u32 freq = 0;
|
||||
int err;
|
||||
|
||||
memset(&connect, 0, sizeof(connect));
|
||||
@ -10156,14 +10238,21 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
||||
connect.prev_bssid =
|
||||
nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
|
||||
connect.channel = nl80211_get_valid_chan(
|
||||
wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
|
||||
freq = MHZ_TO_KHZ(nla_get_u32(
|
||||
info->attrs[NL80211_ATTR_WIPHY_FREQ]));
|
||||
if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
|
||||
freq +=
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
|
||||
|
||||
if (freq) {
|
||||
connect.channel = nl80211_get_valid_chan(wiphy, freq);
|
||||
if (!connect.channel)
|
||||
return -EINVAL;
|
||||
} else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
|
||||
connect.channel_hint = nl80211_get_valid_chan(
|
||||
wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
|
||||
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
|
||||
freq = MHZ_TO_KHZ(freq);
|
||||
connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
|
||||
if (!connect.channel_hint)
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -10702,7 +10791,8 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
|
||||
if (!rdev->ops->set_bitrate_mask)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = nl80211_parse_tx_bitrate_mask(info, &mask);
|
||||
err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
|
||||
NL80211_ATTR_TX_RATES, &mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -11308,7 +11398,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_TX_RATES]) {
|
||||
err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
|
||||
err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
|
||||
NL80211_ATTR_TX_RATES,
|
||||
&setup.beacon_rate);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -12262,14 +12354,22 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
|
||||
return -ERANGE;
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
|
||||
!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
|
||||
nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
|
||||
return -ERANGE;
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
|
||||
if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
|
||||
!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
|
||||
nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
|
||||
return -ERANGE;
|
||||
|
||||
rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
|
||||
rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
|
||||
rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
|
||||
rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
|
||||
rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
|
||||
if (tb[NL80211_REKEY_DATA_AKM])
|
||||
rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
|
||||
|
||||
wdev_lock(wdev);
|
||||
if (!wdev->current_bss) {
|
||||
@ -13815,6 +13915,7 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
@ -13823,6 +13924,7 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
u8 *dest;
|
||||
u16 proto;
|
||||
bool noencrypt;
|
||||
u64 cookie = 0;
|
||||
int err;
|
||||
|
||||
if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
@ -13867,9 +13969,12 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
|
||||
noencrypt =
|
||||
nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
|
||||
|
||||
return rdev_tx_control_port(rdev, dev, buf, len,
|
||||
dest, cpu_to_be16(proto), noencrypt);
|
||||
|
||||
err = rdev_tx_control_port(rdev, dev, buf, len,
|
||||
dest, cpu_to_be16(proto), noencrypt,
|
||||
dont_wait_for_ack ? NULL : &cookie);
|
||||
if (!err && !dont_wait_for_ack)
|
||||
nl_set_extack_cookie_u64(info->extack, cookie);
|
||||
return err;
|
||||
out:
|
||||
wdev_unlock(wdev);
|
||||
return err;
|
||||
@ -14034,10 +14139,7 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
|
||||
if (rdev->ops->reset_tid_config) {
|
||||
err = rdev_reset_tid_config(rdev, dev, peer,
|
||||
tid_conf->tids);
|
||||
/* If peer is there no other configuration will be
|
||||
* allowed
|
||||
*/
|
||||
if (err || peer)
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
@ -14080,6 +14182,29 @@ static int parse_tid_conf(struct cfg80211_registered_device *rdev,
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
|
||||
tid_conf->amsdu =
|
||||
nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
|
||||
}
|
||||
|
||||
if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
|
||||
u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
|
||||
|
||||
tid_conf->txrate_type = nla_get_u8(attrs[idx]);
|
||||
|
||||
if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
|
||||
attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
|
||||
err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
|
||||
&tid_conf->txrate_mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
|
||||
}
|
||||
tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
|
||||
}
|
||||
|
||||
if (peer)
|
||||
mask = rdev->wiphy.tid_config_support.peer;
|
||||
else
|
||||
@ -15191,14 +15316,27 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
|
||||
nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < req->n_channels; i++) {
|
||||
if (nla_put_u32(msg, i, req->channels[i]->center_freq))
|
||||
if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
|
||||
nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < req->n_channels; i++) {
|
||||
if (nla_put_u32(msg, i,
|
||||
ieee80211_channel_to_khz(req->channels[i])))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
} else {
|
||||
nest = nla_nest_start_noflag(msg,
|
||||
NL80211_ATTR_SCAN_FREQUENCIES);
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < req->n_channels; i++) {
|
||||
if (nla_put_u32(msg, i, req->channels[i]->center_freq))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
|
||||
if (req->ie &&
|
||||
nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
|
||||
@ -16209,7 +16347,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
|
||||
netdev->ifindex)) ||
|
||||
nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
|
||||
NL80211_ATTR_PAD) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
|
||||
(sig_dbm &&
|
||||
nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
|
||||
nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
|
||||
@ -16226,8 +16365,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack, gfp_t gfp)
|
||||
static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack,
|
||||
gfp_t gfp, enum nl80211_commands command)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
@ -16235,13 +16375,16 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
|
||||
if (command == NL80211_CMD_FRAME_TX_STATUS)
|
||||
trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
|
||||
else
|
||||
trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
|
||||
|
||||
msg = nlmsg_new(100 + len, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
|
||||
hdr = nl80211hdr_put(msg, 0, 0, 0, command);
|
||||
if (!hdr) {
|
||||
nlmsg_free(msg);
|
||||
return;
|
||||
@ -16264,9 +16407,25 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
NL80211_MCGRP_MLME, gfp);
|
||||
return;
|
||||
|
||||
nla_put_failure:
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack,
|
||||
gfp_t gfp)
|
||||
{
|
||||
nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
|
||||
NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_control_port_tx_status);
|
||||
|
||||
void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
|
||||
const u8 *buf, size_t len, bool ack, gfp_t gfp)
|
||||
{
|
||||
nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
|
||||
NL80211_CMD_FRAME_TX_STATUS);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
|
||||
|
||||
static int __nl80211_rx_control_port(struct net_device *dev,
|
||||
@ -16835,9 +16994,8 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_probe_status);
|
||||
|
||||
void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
const u8 *frame, size_t len,
|
||||
int freq, int sig_dbm)
|
||||
void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
|
||||
size_t len, int freq, int sig_dbm)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct sk_buff *msg;
|
||||
@ -16860,7 +17018,10 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
(freq &&
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
|
||||
(nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
|
||||
KHZ_TO_MHZ(freq)) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
|
||||
freq % 1000))) ||
|
||||
(sig_dbm &&
|
||||
nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
|
||||
nla_put(msg, NL80211_ATTR_FRAME, len, frame))
|
||||
@ -16877,7 +17038,7 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
|
||||
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_report_obss_beacon);
|
||||
EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int cfg80211_net_detect_results(struct sk_buff *msg,
|
||||
|
@ -748,14 +748,17 @@ static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
const void *buf, size_t len,
|
||||
const u8 *dest, __be16 proto,
|
||||
const bool noencrypt)
|
||||
const bool noencrypt, u64 *cookie)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, proto, noencrypt);
|
||||
ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len,
|
||||
dest, proto, noencrypt);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
dest, proto, noencrypt, cookie);
|
||||
if (cookie)
|
||||
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
|
||||
else
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* (for nl80211's connect() and wext)
|
||||
*
|
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (C) 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2009, 2020 Intel Corporation. All rights reserved.
|
||||
* Copyright 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
||||
@ -1118,7 +1118,10 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
||||
|
||||
if (wiphy_ext_feature_isset(
|
||||
wdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
|
||||
wiphy_ext_feature_isset(
|
||||
wdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
|
||||
max_key_idx = 7;
|
||||
for (i = 0; i <= max_key_idx; i++)
|
||||
rdev_del_key(rdev, dev, i, false, NULL);
|
||||
|
@ -2840,8 +2840,8 @@ TRACE_EVENT(cfg80211_rx_mgmt,
|
||||
__entry->freq = freq;
|
||||
__entry->sig_dbm = sig_dbm;
|
||||
),
|
||||
TP_printk(WDEV_PR_FMT ", freq: %d, sig dbm: %d",
|
||||
WDEV_PR_ARG, __entry->freq, __entry->sig_dbm)
|
||||
TP_printk(WDEV_PR_FMT ", freq: "KHZ_F", sig dbm: %d",
|
||||
WDEV_PR_ARG, PR_KHZ(__entry->freq), __entry->sig_dbm)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_mgmt_tx_status,
|
||||
@ -2861,6 +2861,23 @@ TRACE_EVENT(cfg80211_mgmt_tx_status,
|
||||
WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack))
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_control_port_tx_status,
|
||||
TP_PROTO(struct wireless_dev *wdev, u64 cookie, bool ack),
|
||||
TP_ARGS(wdev, cookie, ack),
|
||||
TP_STRUCT__entry(
|
||||
WDEV_ENTRY
|
||||
__field(u64, cookie)
|
||||
__field(bool, ack)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
__entry->ack = ack;
|
||||
),
|
||||
TP_printk(WDEV_PR_FMT", cookie: %llu, ack: %s",
|
||||
WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack))
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_rx_control_port,
|
||||
TP_PROTO(struct net_device *netdev, struct sk_buff *skb,
|
||||
bool unencrypted),
|
||||
@ -3121,8 +3138,8 @@ TRACE_EVENT(cfg80211_report_obss_beacon,
|
||||
__entry->freq = freq;
|
||||
__entry->sig_dbm = sig_dbm;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", freq: %d, sig_dbm: %d",
|
||||
WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm)
|
||||
TP_printk(WIPHY_PR_FMT ", freq: "KHZ_F", sig_dbm: %d",
|
||||
WIPHY_PR_ARG, PR_KHZ(__entry->freq), __entry->sig_dbm)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_tdls_oper_request,
|
||||
|
@ -92,9 +92,11 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
|
||||
return MHZ_TO_KHZ(5000 + chan * 5);
|
||||
break;
|
||||
case NL80211_BAND_6GHZ:
|
||||
/* see 802.11ax D4.1 27.3.22.2 */
|
||||
/* see 802.11ax D6.1 27.3.23.2 */
|
||||
if (chan == 2)
|
||||
return MHZ_TO_KHZ(5935);
|
||||
if (chan <= 253)
|
||||
return 5940 + chan * 5;
|
||||
return MHZ_TO_KHZ(5950 + chan * 5);
|
||||
break;
|
||||
case NL80211_BAND_60GHZ:
|
||||
if (chan < 7)
|
||||
@ -240,7 +242,9 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
||||
int max_key_idx = 5;
|
||||
|
||||
if (wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION))
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
|
||||
wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
|
||||
max_key_idx = 7;
|
||||
if (key_idx < 0 || key_idx > max_key_idx)
|
||||
return -EINVAL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user