Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+1575 -288
+1
drivers/net/wireless/mac80211_hwsim.c
··· 3054 3054 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 3055 3055 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 3056 3056 WIPHY_FLAG_AP_UAPSD | 3057 + WIPHY_FLAG_SUPPORTS_5_10_MHZ | 3057 3058 WIPHY_FLAG_HAS_CHANNEL_SWITCH; 3058 3059 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | 3059 3060 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
+339 -5
include/linux/ieee80211.h
··· 105 105 106 106 /* extension, added by 802.11ad */ 107 107 #define IEEE80211_STYPE_DMG_BEACON 0x0000 108 + #define IEEE80211_STYPE_S1G_BEACON 0x0010 109 + 110 + /* bits unique to S1G beacon */ 111 + #define IEEE80211_S1G_BCN_NEXT_TBTT 0x100 112 + 113 + /* see 802.11ah-2016 9.9 NDP CMAC frames */ 114 + #define IEEE80211_S1G_1MHZ_NDP_BITS 25 115 + #define IEEE80211_S1G_1MHZ_NDP_BYTES 4 116 + #define IEEE80211_S1G_2MHZ_NDP_BITS 37 117 + #define IEEE80211_S1G_2MHZ_NDP_BYTES 5 118 + 119 + #define IEEE80211_NDP_FTYPE_CTS 0 120 + #define IEEE80211_NDP_FTYPE_CF_END 0 121 + #define IEEE80211_NDP_FTYPE_PS_POLL 1 122 + #define IEEE80211_NDP_FTYPE_ACK 2 123 + #define IEEE80211_NDP_FTYPE_PS_POLL_ACK 3 124 + #define IEEE80211_NDP_FTYPE_BA 4 125 + #define IEEE80211_NDP_FTYPE_BF_REPORT_POLL 5 126 + #define IEEE80211_NDP_FTYPE_PAGING 6 127 + #define IEEE80211_NDP_FTYPE_PREQ 7 128 + 129 + #define SM64(f, v) ((((u64)v) << f##_S) & f) 130 + 131 + /* NDP CMAC frame fields */ 132 + #define IEEE80211_NDP_FTYPE 0x0000000000000007 133 + #define IEEE80211_NDP_FTYPE_S 0x0000000000000000 134 + 135 + /* 1M Probe Request 11ah 9.9.3.1.1 */ 136 + #define IEEE80211_NDP_1M_PREQ_ANO 0x0000000000000008 137 + #define IEEE80211_NDP_1M_PREQ_ANO_S 3 138 + #define IEEE80211_NDP_1M_PREQ_CSSID 0x00000000000FFFF0 139 + #define IEEE80211_NDP_1M_PREQ_CSSID_S 4 140 + #define IEEE80211_NDP_1M_PREQ_RTYPE 0x0000000000100000 141 + #define IEEE80211_NDP_1M_PREQ_RTYPE_S 20 142 + #define IEEE80211_NDP_1M_PREQ_RSV 0x0000000001E00000 143 + #define IEEE80211_NDP_1M_PREQ_RSV 0x0000000001E00000 144 + /* 2M Probe Request 11ah 9.9.3.1.2 */ 145 + #define IEEE80211_NDP_2M_PREQ_ANO 0x0000000000000008 146 + #define IEEE80211_NDP_2M_PREQ_ANO_S 3 147 + #define IEEE80211_NDP_2M_PREQ_CSSID 0x0000000FFFFFFFF0 148 + #define IEEE80211_NDP_2M_PREQ_CSSID_S 4 149 + #define IEEE80211_NDP_2M_PREQ_RTYPE 0x0000001000000000 150 + #define IEEE80211_NDP_2M_PREQ_RTYPE_S 36 151 + 152 + #define IEEE80211_ANO_NETTYPE_WILD 15 108 153 109 154 /* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */ 110 155 #define IEEE80211_CTL_EXT_POLL 0x2000 ··· 165 120 #define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4) 166 121 #define IEEE80211_MAX_SN IEEE80211_SN_MASK 167 122 #define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1) 123 + 124 + 125 + /* PV1 Layout 11ah 9.8.3.1 */ 126 + #define IEEE80211_PV1_FCTL_VERS 0x0003 127 + #define IEEE80211_PV1_FCTL_FTYPE 0x001c 128 + #define IEEE80211_PV1_FCTL_STYPE 0x00e0 129 + #define IEEE80211_PV1_FCTL_TODS 0x0100 130 + #define IEEE80211_PV1_FCTL_MOREFRAGS 0x0200 131 + #define IEEE80211_PV1_FCTL_PM 0x0400 132 + #define IEEE80211_PV1_FCTL_MOREDATA 0x0800 133 + #define IEEE80211_PV1_FCTL_PROTECTED 0x1000 134 + #define IEEE80211_PV1_FCTL_END_SP 0x2000 135 + #define IEEE80211_PV1_FCTL_RELAYED 0x4000 136 + #define IEEE80211_PV1_FCTL_ACK_POLICY 0x8000 137 + #define IEEE80211_PV1_FCTL_CTL_EXT 0x0f00 168 138 169 139 static inline bool ieee80211_sn_less(u16 sn1, u16 sn2) 170 140 { ··· 208 148 #define IEEE80211_MAX_FRAG_THRESHOLD 2352 209 149 #define IEEE80211_MAX_RTS_THRESHOLD 2353 210 150 #define IEEE80211_MAX_AID 2007 151 + #define IEEE80211_MAX_AID_S1G 8191 211 152 #define IEEE80211_MAX_TIM_LEN 251 212 153 #define IEEE80211_MAX_MESH_PEERINGS 63 213 154 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section ··· 433 372 } 434 373 435 374 /** 375 + * ieee80211_is_ext - check if type is IEEE80211_FTYPE_EXT 376 + * @fc: frame control bytes in little-endian byteorder 377 + */ 378 + static inline bool ieee80211_is_ext(__le16 fc) 379 + { 380 + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == 381 + cpu_to_le16(IEEE80211_FTYPE_EXT); 382 + } 383 + 384 + 385 + /** 436 386 * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set 437 387 * @fc: frame control bytes in little-endian byteorder 438 388 */ ··· 539 467 { 540 468 return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == 541 469 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); 470 + } 471 + 472 + /** 473 + * ieee80211_is_s1g_beacon - check if IEEE80211_FTYPE_EXT && 474 + * IEEE80211_STYPE_S1G_BEACON 475 + * @fc: frame control bytes in little-endian byteorder 476 + */ 477 + static inline bool ieee80211_is_s1g_beacon(__le16 fc) 478 + { 479 + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 480 + IEEE80211_FCTL_STYPE)) == 481 + cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON); 542 482 } 543 483 544 484 /** ··· 800 716 u8 token; 801 717 u8 mode; 802 718 u8 type; 803 - u8 request[0]; 719 + u8 request[]; 804 720 } __packed; 805 721 806 722 /** ··· 983 899 struct ieee80211_addba_ext_ie { 984 900 u8 data; 985 901 } __packed; 902 + 903 + /** 904 + * struct ieee80211_s1g_bcn_compat_ie 905 + * 906 + * S1G Beacon Compatibility element 907 + */ 908 + struct ieee80211_s1g_bcn_compat_ie { 909 + __le16 compat_info; 910 + __le16 beacon_int; 911 + __le32 tsf_completion; 912 + } __packed; 913 + 914 + /** 915 + * struct ieee80211_s1g_oper_ie 916 + * 917 + * S1G Operation element 918 + */ 919 + struct ieee80211_s1g_oper_ie { 920 + u8 ch_width; 921 + u8 oper_class; 922 + u8 primary_ch; 923 + u8 oper_ch; 924 + __le16 basic_mcs_nss; 925 + } __packed; 926 + 927 + /** 928 + * struct ieee80211_aid_response_ie 929 + * 930 + * AID Response element 931 + */ 932 + struct ieee80211_aid_response_ie { 933 + __le16 aid; 934 + u8 switch_count; 935 + __le16 response_int; 936 + } __packed; 937 + 938 + struct ieee80211_s1g_cap { 939 + u8 capab_info[10]; 940 + u8 supp_mcs_nss[5]; 941 + } __packed; 942 + 943 + struct ieee80211_ext { 944 + __le16 frame_control; 945 + __le16 duration; 946 + union { 947 + struct { 948 + u8 sa[ETH_ALEN]; 949 + __le32 timestamp; 950 + u8 change_seq; 951 + u8 variable[0]; 952 + } __packed s1g_beacon; 953 + } u; 954 + } __packed __aligned(2); 986 955 987 956 struct ieee80211_mgmt { 988 957 __le16 frame_control; ··· 1781 1644 __le32 he_oper_params; 1782 1645 __le16 he_mcs_nss_set; 1783 1646 /* Optional 0,1,3,4,5,7 or 8 bytes: depends on @he_oper_params */ 1784 - u8 optional[0]; 1647 + u8 optional[]; 1785 1648 } __packed; 1786 1649 1787 1650 /** ··· 1793 1656 struct ieee80211_he_spr { 1794 1657 u8 he_sr_control; 1795 1658 /* Optional 0 to 19 bytes: depends on @he_sr_control */ 1796 - u8 optional[0]; 1659 + u8 optional[]; 1797 1660 } __packed; 1798 1661 1799 1662 /** ··· 1958 1821 #define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40 1959 1822 #define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80 1960 1823 1824 + #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3 1825 + 1961 1826 #define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01 1962 1827 #define IEEE80211_HE_MAC_CAP4_QTP 0x02 1963 1828 #define IEEE80211_HE_MAC_CAP4_BQR 0x04 ··· 1980 1841 #define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20 1981 1842 #define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING 0x40 1982 1843 #define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX 0x80 1844 + 1845 + #define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR 20 1846 + #define IEEE80211_HE_HT_MAX_AMPDU_FACTOR 16 1983 1847 1984 1848 /* 802.11ax HE PHY capabilities */ 1985 1849 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02 ··· 2209 2067 #define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000 2210 2068 #define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000 2211 2069 2070 + /** 2071 + * ieee80211_he_6ghz_oper - HE 6 GHz operation Information field 2072 + * @primary: primary channel 2073 + * @control: control flags 2074 + * @ccfs0: channel center frequency segment 0 2075 + * @ccfs1: channel center frequency segment 1 2076 + * @minrate: minimum rate (in 1 Mbps units) 2077 + */ 2078 + struct ieee80211_he_6ghz_oper { 2079 + u8 primary; 2080 + #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH 0x3 2081 + #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ 0 2082 + #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ 1 2083 + #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ 2 2084 + #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ 3 2085 + #define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON 0x4 2086 + u8 control; 2087 + u8 ccfs0; 2088 + u8 ccfs1; 2089 + u8 minrate; 2090 + } __packed; 2091 + 2212 2092 /* 2213 2093 * ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size 2214 2094 * @he_oper_ie: byte data of the He Operations IE, stating from the byte ··· 2257 2093 if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) 2258 2094 oper_len++; 2259 2095 if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO) 2260 - oper_len += 4; 2096 + oper_len += sizeof(struct ieee80211_he_6ghz_oper); 2261 2097 2262 2098 /* Add the first byte (extension ID) to the total length */ 2263 2099 oper_len++; 2264 2100 2265 2101 return oper_len; 2102 + } 2103 + 2104 + /** 2105 + * ieee80211_he_6ghz_oper - obtain 6 GHz operation field 2106 + * @he_oper: HE operation element (must be pre-validated for size) 2107 + * but may be %NULL 2108 + * 2109 + * Return: a pointer to the 6 GHz operation field, or %NULL 2110 + */ 2111 + static inline const struct ieee80211_he_6ghz_oper * 2112 + ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper) 2113 + { 2114 + const u8 *ret = (void *)&he_oper->optional; 2115 + u32 he_oper_params; 2116 + 2117 + if (!he_oper) 2118 + return NULL; 2119 + 2120 + he_oper_params = le32_to_cpu(he_oper->he_oper_params); 2121 + 2122 + if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)) 2123 + return NULL; 2124 + if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO) 2125 + ret += 3; 2126 + if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) 2127 + ret++; 2128 + 2129 + return (void *)ret; 2266 2130 } 2267 2131 2268 2132 /* HE Spatial Reuse defines */ ··· 2328 2136 2329 2137 return spr_len; 2330 2138 } 2139 + 2140 + /* S1G Capabilities Information field */ 2141 + #define S1G_CAPAB_B0_S1G_LONG BIT(0) 2142 + #define S1G_CAPAB_B0_SGI_1MHZ BIT(1) 2143 + #define S1G_CAPAB_B0_SGI_2MHZ BIT(2) 2144 + #define S1G_CAPAB_B0_SGI_4MHZ BIT(3) 2145 + #define S1G_CAPAB_B0_SGI_8MHZ BIT(4) 2146 + #define S1G_CAPAB_B0_SGI_16MHZ BIT(5) 2147 + #define S1G_CAPAB_B0_SUPP_CH_WIDTH_MASK (BIT(6) | BIT(7)) 2148 + #define S1G_CAPAB_B0_SUPP_CH_WIDTH_SHIFT 6 2149 + 2150 + #define S1G_CAPAB_B1_RX_LDPC BIT(0) 2151 + #define S1G_CAPAB_B1_TX_STBC BIT(1) 2152 + #define S1G_CAPAB_B1_RX_STBC BIT(2) 2153 + #define S1G_CAPAB_B1_SU_BFER BIT(3) 2154 + #define S1G_CAPAB_B1_SU_BFEE BIT(4) 2155 + #define S1G_CAPAB_B1_BFEE_STS_MASK (BIT(5) | BIT(6) | BIT(7)) 2156 + #define S1G_CAPAB_B1_BFEE_STS_SHIFT 5 2157 + 2158 + #define S1G_CAPAB_B2_SOUNDING_DIMENSIONS_MASK (BIT(0) | BIT(1) | BIT(2)) 2159 + #define S1G_CAPAB_B2_SOUNDING_DIMENSIONS_SHIFT 0 2160 + #define S1G_CAPAB_B2_MU_BFER BIT(3) 2161 + #define S1G_CAPAB_B2_MU_BFEE BIT(4) 2162 + #define S1G_CAPAB_B2_PLUS_HTC_VHT BIT(5) 2163 + #define S1G_CAPAB_B2_TRAVELING_PILOT_MASK (BIT(6) | BIT(7)) 2164 + #define S1G_CAPAB_B2_TRAVELING_PILOT_SHIFT 6 2165 + 2166 + #define S1G_CAPAB_B3_RD_RESPONDER BIT(0) 2167 + #define S1G_CAPAB_B3_HT_DELAYED_BA BIT(1) 2168 + #define S1G_CAPAB_B3_MAX_MPDU_LEN BIT(2) 2169 + #define S1G_CAPAB_B3_MAX_AMPDU_LEN_EXP_MASK (BIT(3) | BIT(4)) 2170 + #define S1G_CAPAB_B3_MAX_AMPDU_LEN_EXP_SHIFT 3 2171 + #define S1G_CAPAB_B3_MIN_MPDU_START_MASK (BIT(5) | BIT(6) | BIT(7)) 2172 + #define S1G_CAPAB_B3_MIN_MPDU_START_SHIFT 5 2173 + 2174 + #define S1G_CAPAB_B4_UPLINK_SYNC BIT(0) 2175 + #define S1G_CAPAB_B4_DYNAMIC_AID BIT(1) 2176 + #define S1G_CAPAB_B4_BAT BIT(2) 2177 + #define S1G_CAPAB_B4_TIME_ADE BIT(3) 2178 + #define S1G_CAPAB_B4_NON_TIM BIT(4) 2179 + #define S1G_CAPAB_B4_GROUP_AID BIT(5) 2180 + #define S1G_CAPAB_B4_STA_TYPE_MASK (BIT(6) | BIT(7)) 2181 + #define S1G_CAPAB_B4_STA_TYPE_SHIFT 6 2182 + 2183 + #define S1G_CAPAB_B5_CENT_AUTH_CONTROL BIT(0) 2184 + #define S1G_CAPAB_B5_DIST_AUTH_CONTROL BIT(1) 2185 + #define S1G_CAPAB_B5_AMSDU BIT(2) 2186 + #define S1G_CAPAB_B5_AMPDU BIT(3) 2187 + #define S1G_CAPAB_B5_ASYMMETRIC_BA BIT(4) 2188 + #define S1G_CAPAB_B5_FLOW_CONTROL BIT(5) 2189 + #define S1G_CAPAB_B5_SECTORIZED_BEAM_MASK (BIT(6) | BIT(7)) 2190 + #define S1G_CAPAB_B5_SECTORIZED_BEAM_SHIFT 6 2191 + 2192 + #define S1G_CAPAB_B6_OBSS_MITIGATION BIT(0) 2193 + #define S1G_CAPAB_B6_FRAGMENT_BA BIT(1) 2194 + #define S1G_CAPAB_B6_NDP_PS_POLL BIT(2) 2195 + #define S1G_CAPAB_B6_RAW_OPERATION BIT(3) 2196 + #define S1G_CAPAB_B6_PAGE_SLICING BIT(4) 2197 + #define S1G_CAPAB_B6_TXOP_SHARING_IMP_ACK BIT(5) 2198 + #define S1G_CAPAB_B6_VHT_LINK_ADAPT_MASK (BIT(6) | BIT(7)) 2199 + #define S1G_CAPAB_B6_VHT_LINK_ADAPT_SHIFT 6 2200 + 2201 + #define S1G_CAPAB_B7_TACK_AS_PS_POLL BIT(0) 2202 + #define S1G_CAPAB_B7_DUP_1MHZ BIT(1) 2203 + #define S1G_CAPAB_B7_MCS_NEGOTIATION BIT(2) 2204 + #define S1G_CAPAB_B7_1MHZ_CTL_RESPONSE_PREAMBLE BIT(3) 2205 + #define S1G_CAPAB_B7_NDP_BFING_REPORT_POLL BIT(4) 2206 + #define S1G_CAPAB_B7_UNSOLICITED_DYN_AID BIT(5) 2207 + #define S1G_CAPAB_B7_SECTOR_TRAINING_OPERATION BIT(6) 2208 + #define S1G_CAPAB_B7_TEMP_PS_MODE_SWITCH BIT(7) 2209 + 2210 + #define S1G_CAPAB_B8_TWT_GROUPING BIT(0) 2211 + #define S1G_CAPAB_B8_BDT BIT(1) 2212 + #define S1G_CAPAB_B8_COLOR_MASK (BIT(2) | BIT(3) | BIT(4)) 2213 + #define S1G_CAPAB_B8_COLOR_SHIFT 2 2214 + #define S1G_CAPAB_B8_TWT_REQUEST BIT(5) 2215 + #define S1G_CAPAB_B8_TWT_RESPOND BIT(6) 2216 + #define S1G_CAPAB_B8_PV1_FRAME BIT(7) 2217 + 2218 + #define S1G_CAPAB_B9_LINK_ADAPT_PER_CONTROL_RESPONSE BIT(0) 2331 2219 2332 2220 /* Authentication algorithms */ 2333 2221 #define WLAN_AUTH_OPEN 0 ··· 2804 2532 WLAN_EID_QUIET_CHANNEL = 198, 2805 2533 WLAN_EID_OPMODE_NOTIF = 199, 2806 2534 2535 + WLAN_EID_REDUCED_NEIGHBOR_REPORT = 201, 2536 + 2537 + WLAN_EID_S1G_BCN_COMPAT = 213, 2538 + WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214, 2539 + WLAN_EID_S1G_CAPABILITIES = 217, 2807 2540 WLAN_EID_VENDOR_SPECIFIC = 221, 2808 2541 WLAN_EID_QOS_PARAMETER = 222, 2542 + WLAN_EID_S1G_OPERATION = 232, 2809 2543 WLAN_EID_CAG_NUMBER = 237, 2810 2544 WLAN_EID_AP_CSN = 239, 2811 2545 WLAN_EID_FILS_INDICATION = 240, ··· 2839 2561 WLAN_EID_EXT_UORA = 37, 2840 2562 WLAN_EID_EXT_HE_MU_EDCA = 38, 2841 2563 WLAN_EID_EXT_HE_SPR = 39, 2564 + WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET = 41, 2565 + WLAN_EID_EXT_BSS_COLOR_CHG_ANN = 42, 2566 + WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP = 43, 2567 + WLAN_EID_EXT_ESS_REPORT = 45, 2568 + WLAN_EID_EXT_OPS = 46, 2569 + WLAN_EID_EXT_HE_BSS_LOAD = 47, 2842 2570 WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52, 2843 2571 WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55, 2844 2572 WLAN_EID_EXT_NON_INHERITANCE = 56, 2573 + WLAN_EID_EXT_KNOWN_BSSID = 57, 2574 + WLAN_EID_EXT_SHORT_SSID_LIST = 58, 2575 + WLAN_EID_EXT_HE_6GHZ_CAPA = 59, 2576 + WLAN_EID_EXT_UL_MU_POWER_CAPA = 60, 2845 2577 }; 2846 2578 2847 2579 /* Action category code */ ··· 3082 2794 #define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7) 3083 2795 3084 2796 /* Defines support for enhanced multi-bssid advertisement*/ 3085 - #define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(1) 2797 + #define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(3) 3086 2798 3087 2799 /* TDLS specific payload type in the LLC/SNAP header */ 3088 2800 #define WLAN_TDLS_SNAP_RFTYPE 0x2 ··· 3394 3106 __le16 medium_time; 3395 3107 } __packed; 3396 3108 3109 + struct ieee80211_he_6ghz_capa { 3110 + /* uses IEEE80211_HE_6GHZ_CAP_* below */ 3111 + __le16 capa; 3112 + } __packed; 3113 + 3114 + /* HE 6 GHz band capabilities */ 3115 + /* uses enum ieee80211_min_mpdu_spacing values */ 3116 + #define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x0007 3117 + /* uses enum ieee80211_vht_max_ampdu_length_exp values */ 3118 + #define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x0038 3119 + /* uses IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_* values */ 3120 + #define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x00c0 3121 + /* WLAN_HT_CAP_SM_PS_* values */ 3122 + #define IEEE80211_HE_6GHZ_CAP_SM_PS 0x0600 3123 + #define IEEE80211_HE_6GHZ_CAP_RD_RESPONDER 0x0800 3124 + #define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS 0x1000 3125 + #define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS 0x2000 3126 + 3397 3127 /** 3398 3128 * ieee80211_get_qos_ctl - get pointer to qos control bytes 3399 3129 * @hdr: the frame ··· 3639 3333 /* convert frequencies */ 3640 3334 #define MHZ_TO_KHZ(freq) ((freq) * 1000) 3641 3335 #define KHZ_TO_MHZ(freq) ((freq) / 1000) 3336 + #define PR_KHZ(f) KHZ_TO_MHZ(f), f % 1000 3337 + #define KHZ_F "%d.%03d" 3642 3338 3643 3339 /* convert powers */ 3644 3340 #define DBI_TO_MBI(gain) ((gain) * 100) ··· 3754 3446 */ 3755 3447 #define WLAN_RSNX_CAPA_PROTECTED_TWT BIT(4) 3756 3448 #define WLAN_RSNX_CAPA_SAE_H2E BIT(5) 3449 + 3450 + /* 3451 + * reduced neighbor report, based on Draft P802.11ax_D5.0, 3452 + * section 9.4.2.170 3453 + */ 3454 + #define IEEE80211_AP_INFO_TBTT_HDR_TYPE 0x03 3455 + #define IEEE80211_AP_INFO_TBTT_HDR_FILTERED 0x04 3456 + #define IEEE80211_AP_INFO_TBTT_HDR_COLOC 0x08 3457 + #define IEEE80211_AP_INFO_TBTT_HDR_COUNT 0xF0 3458 + #define IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM 8 3459 + #define IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM 12 3460 + 3461 + #define IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED 0x01 3462 + #define IEEE80211_RNR_TBTT_PARAMS_SAME_SSID 0x02 3463 + #define IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID 0x04 3464 + #define IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID 0x08 3465 + #define IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS 0x10 3466 + #define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20 3467 + #define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40 3468 + 3469 + struct ieee80211_neighbor_ap_info { 3470 + u8 tbtt_info_hdr; 3471 + u8 tbtt_info_len; 3472 + u8 op_class; 3473 + u8 channel; 3474 + } __packed; 3757 3475 3758 3476 #endif /* LINUX_IEEE80211_H */
+142 -27
include/net/cfg80211.h
··· 354 354 * 355 355 * @types_mask: interface types mask 356 356 * @he_cap: holds the HE capabilities 357 + * @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a 358 + * 6 GHz band channel (and 0 may be valid value). 357 359 */ 358 360 struct ieee80211_sband_iftype_data { 359 361 u16 types_mask; 360 362 struct ieee80211_sta_he_cap he_cap; 363 + struct ieee80211_he_6ghz_capa he_6ghz_capa; 361 364 }; 362 365 363 366 /** ··· 513 510 } 514 511 515 512 /** 513 + * ieee80211_get_he_6ghz_capa - return HE 6 GHz capabilities 514 + * @sband: the sband to search for the STA on 515 + * @iftype: the iftype to search for 516 + * 517 + * Return: the 6GHz capabilities 518 + */ 519 + static inline __le16 520 + ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband, 521 + enum nl80211_iftype iftype) 522 + { 523 + const struct ieee80211_sband_iftype_data *data = 524 + ieee80211_get_sband_iftype_data(sband, iftype); 525 + 526 + if (WARN_ON(!data || !data->he_cap.has_he)) 527 + return 0; 528 + 529 + return data->he_6ghz_capa.capa; 530 + } 531 + 532 + /** 516 533 * wiphy_read_of_freq_limits - read frequency limits from device tree 517 534 * 518 535 * @wiphy: the wireless device to get extra limits for ··· 653 630 u16 freq1_offset; 654 631 }; 655 632 633 + /* 634 + * cfg80211_bitrate_mask - masks for bitrate control 635 + */ 636 + struct cfg80211_bitrate_mask { 637 + struct { 638 + u32 legacy; 639 + u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN]; 640 + u16 vht_mcs[NL80211_VHT_NSS_MAX]; 641 + enum nl80211_txrate_gi gi; 642 + } control[NUM_NL80211_BANDS]; 643 + }; 644 + 645 + 656 646 /** 657 647 * struct cfg80211_tid_cfg - TID specific configuration 658 648 * @config_override: Flag to notify driver to reset TID configuration ··· 676 640 * @noack: noack configuration value for the TID 677 641 * @retry_long: retry count value 678 642 * @retry_short: retry count value 679 - * @ampdu: Enable/Disable aggregation 643 + * @ampdu: Enable/Disable MPDU aggregation 680 644 * @rtscts: Enable/Disable RTS/CTS 645 + * @amsdu: Enable/Disable MSDU aggregation 646 + * @txrate_type: Tx bitrate mask type 647 + * @txrate_mask: Tx bitrate to be applied for the TID 681 648 */ 682 649 struct cfg80211_tid_cfg { 683 650 bool config_override; 684 651 u8 tids; 685 - u32 mask; 652 + u64 mask; 686 653 enum nl80211_tid_config noack; 687 654 u8 retry_long, retry_short; 688 655 enum nl80211_tid_config ampdu; 689 656 enum nl80211_tid_config rtscts; 657 + enum nl80211_tid_config amsdu; 658 + enum nl80211_tx_rate_setting txrate_type; 659 + struct cfg80211_bitrate_mask txrate_mask; 690 660 }; 691 661 692 662 /** ··· 1047 1005 struct mac_address mac_addrs[]; 1048 1006 }; 1049 1007 1050 - /* 1051 - * cfg80211_bitrate_mask - masks for bitrate control 1052 - */ 1053 - struct cfg80211_bitrate_mask { 1054 - struct { 1055 - u32 legacy; 1056 - u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN]; 1057 - u16 vht_mcs[NL80211_VHT_NSS_MAX]; 1058 - enum nl80211_txrate_gi gi; 1059 - } control[NUM_NL80211_BANDS]; 1060 - }; 1061 - 1062 1008 /** 1063 1009 * enum cfg80211_ap_settings_flags - AP settings flags 1064 1010 * ··· 1261 1231 * @he_capa_len: the length of the HE capabilities 1262 1232 * @airtime_weight: airtime scheduler weight for this station 1263 1233 * @txpwr: transmit power for an associated station 1234 + * @he_6ghz_capa: HE 6 GHz Band capabilities of station 1264 1235 */ 1265 1236 struct station_parameters { 1266 1237 const u8 *supported_rates; ··· 1294 1263 u8 he_capa_len; 1295 1264 u16 airtime_weight; 1296 1265 struct sta_txpwr txpwr; 1266 + const struct ieee80211_he_6ghz_capa *he_6ghz_capa; 1297 1267 }; 1298 1268 1299 1269 /** ··· 2067 2035 bool no_cck; 2068 2036 2069 2037 /* keep last */ 2070 - struct ieee80211_channel *channels[0]; 2038 + struct ieee80211_channel *channels[]; 2071 2039 }; 2072 2040 2073 2041 static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask) ··· 2213 2181 struct list_head list; 2214 2182 2215 2183 /* keep last */ 2216 - struct ieee80211_channel *channels[0]; 2184 + struct ieee80211_channel *channels[]; 2217 2185 }; 2218 2186 2219 2187 /** ··· 2335 2303 u8 bssid_index; 2336 2304 u8 max_bssid_indicator; 2337 2305 2338 - u8 priv[0] __aligned(sizeof(void *)); 2306 + u8 priv[] __aligned(sizeof(void *)); 2339 2307 }; 2340 2308 2341 2309 /** ··· 2936 2904 2937 2905 /** 2938 2906 * struct cfg80211_gtk_rekey_data - rekey data 2939 - * @kek: key encryption key (NL80211_KEK_LEN bytes) 2940 - * @kck: key confirmation key (NL80211_KCK_LEN bytes) 2907 + * @kek: key encryption key (@kek_len bytes) 2908 + * @kck: key confirmation key (@kck_len bytes) 2941 2909 * @replay_ctr: replay counter (NL80211_REPLAY_CTR_LEN bytes) 2910 + * @kek_len: length of kek 2911 + * @kck_len length of kck 2912 + * @akm: akm (oui, id) 2942 2913 */ 2943 2914 struct cfg80211_gtk_rekey_data { 2944 2915 const u8 *kek, *kck, *replay_ctr; 2916 + u32 akm; 2917 + u8 kek_len, kck_len; 2945 2918 }; 2946 2919 2947 2920 /** ··· 4104 4067 struct net_device *dev, 4105 4068 const u8 *buf, size_t len, 4106 4069 const u8 *dest, const __be16 proto, 4107 - const bool noencrypt); 4070 + const bool noencrypt, 4071 + u64 *cookie); 4108 4072 4109 4073 int (*get_ftm_responder_stats)(struct wiphy *wiphy, 4110 4074 struct net_device *dev, ··· 4171 4133 * beaconing mode (AP, IBSS, Mesh, ...). 4172 4134 * @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation 4173 4135 * before connection. 4136 + * @WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK: The device supports bigger kek and kck keys 4174 4137 */ 4175 4138 enum wiphy_flags { 4176 - /* use hole at 0 */ 4139 + WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0), 4177 4140 /* use hole at 1 */ 4178 4141 /* use hole at 2 */ 4179 4142 WIPHY_FLAG_NETNS_OK = BIT(3), ··· 4889 4850 4890 4851 u8 max_data_retry_count; 4891 4852 4892 - char priv[0] __aligned(NETDEV_ALIGN); 4853 + char priv[] __aligned(NETDEV_ALIGN); 4893 4854 }; 4894 4855 4895 4856 static inline struct net *wiphy_net(struct wiphy *wiphy) ··· 5306 5267 ieee80211_get_channel(struct wiphy *wiphy, int freq) 5307 5268 { 5308 5269 return ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(freq)); 5270 + } 5271 + 5272 + /** 5273 + * cfg80211_channel_is_psc - Check if the channel is a 6 GHz PSC 5274 + * @chan: control channel to check 5275 + * 5276 + * The Preferred Scanning Channels (PSC) are defined in 5277 + * Draft IEEE P802.11ax/D5.0, 26.17.2.3.3 5278 + */ 5279 + static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan) 5280 + { 5281 + if (chan->band != NL80211_BAND_6GHZ) 5282 + return false; 5283 + 5284 + return ieee80211_frequency_to_channel(chan->center_freq) % 16 == 5; 5309 5285 } 5310 5286 5311 5287 /** ··· 7041 6987 gfp_t gfp); 7042 6988 7043 6989 /** 6990 + * cfg80211_rx_mgmt_khz - notification of received, unprocessed management frame 6991 + * @wdev: wireless device receiving the frame 6992 + * @freq: Frequency on which the frame was received in KHz 6993 + * @sig_dbm: signal strength in dBm, or 0 if unknown 6994 + * @buf: Management frame (header + body) 6995 + * @len: length of the frame data 6996 + * @flags: flags, as defined in enum nl80211_rxmgmt_flags 6997 + * 6998 + * This function is called whenever an Action frame is received for a station 6999 + * mode interface, but is not processed in kernel. 7000 + * 7001 + * Return: %true if a user space application has registered for this frame. 7002 + * For action frames, that makes it responsible for rejecting unrecognized 7003 + * action frames; %false otherwise, in which case for action frames the 7004 + * driver is responsible for rejecting the frame. 7005 + */ 7006 + bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm, 7007 + const u8 *buf, size_t len, u32 flags); 7008 + 7009 + /** 7044 7010 * cfg80211_rx_mgmt - notification of received, unprocessed management frame 7045 7011 * @wdev: wireless device receiving the frame 7046 7012 * @freq: Frequency on which the frame was received in MHz ··· 7077 7003 * action frames; %false otherwise, in which case for action frames the 7078 7004 * driver is responsible for rejecting the frame. 7079 7005 */ 7080 - bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, 7081 - const u8 *buf, size_t len, u32 flags); 7006 + static inline bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, 7007 + int sig_dbm, const u8 *buf, size_t len, 7008 + u32 flags) 7009 + { 7010 + return cfg80211_rx_mgmt_khz(wdev, MHZ_TO_KHZ(freq), sig_dbm, buf, len, 7011 + flags); 7012 + } 7082 7013 7083 7014 /** 7084 7015 * cfg80211_mgmt_tx_status - notification of TX status for management frame ··· 7101 7022 void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, 7102 7023 const u8 *buf, size_t len, bool ack, gfp_t gfp); 7103 7024 7025 + /** 7026 + * cfg80211_control_port_tx_status - notification of TX status for control 7027 + * port frames 7028 + * @wdev: wireless device receiving the frame 7029 + * @cookie: Cookie returned by cfg80211_ops::tx_control_port() 7030 + * @buf: Data frame (header + body) 7031 + * @len: length of the frame data 7032 + * @ack: Whether frame was acknowledged 7033 + * @gfp: context flags 7034 + * 7035 + * This function is called whenever a control port frame was requested to be 7036 + * transmitted with cfg80211_ops::tx_control_port() to report the TX status of 7037 + * the transmission attempt. 7038 + */ 7039 + void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie, 7040 + const u8 *buf, size_t len, bool ack, 7041 + gfp_t gfp); 7104 7042 7105 7043 /** 7106 7044 * cfg80211_rx_control_port - notification about a received control port frame ··· 7299 7203 bool is_valid_ack_signal, gfp_t gfp); 7300 7204 7301 7205 /** 7206 + * cfg80211_report_obss_beacon_khz - report beacon from other APs 7207 + * @wiphy: The wiphy that received the beacon 7208 + * @frame: the frame 7209 + * @len: length of the frame 7210 + * @freq: frequency the frame was received on in KHz 7211 + * @sig_dbm: signal strength in dBm, or 0 if unknown 7212 + * 7213 + * Use this function to report to userspace when a beacon was 7214 + * received. It is not useful to call this when there is no 7215 + * netdev that is in AP/GO mode. 7216 + */ 7217 + void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame, 7218 + size_t len, int freq, int sig_dbm); 7219 + 7220 + /** 7302 7221 * cfg80211_report_obss_beacon - report beacon from other APs 7303 7222 * @wiphy: The wiphy that received the beacon 7304 7223 * @frame: the frame ··· 7325 7214 * received. It is not useful to call this when there is no 7326 7215 * netdev that is in AP/GO mode. 7327 7216 */ 7328 - void cfg80211_report_obss_beacon(struct wiphy *wiphy, 7329 - const u8 *frame, size_t len, 7330 - int freq, int sig_dbm); 7217 + static inline void cfg80211_report_obss_beacon(struct wiphy *wiphy, 7218 + const u8 *frame, size_t len, 7219 + int freq, int sig_dbm) 7220 + { 7221 + cfg80211_report_obss_beacon_khz(wiphy, frame, len, MHZ_TO_KHZ(freq), 7222 + sig_dbm); 7223 + } 7331 7224 7332 7225 /** 7333 7226 * cfg80211_reg_can_beacon - check if beaconing is allowed
+8 -6
include/net/mac80211.h
··· 7 7 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 8 8 * Copyright 2013-2014 Intel Mobile Communications GmbH 9 9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 10 - * Copyright (C) 2018 - 2019 Intel Corporation 10 + * Copyright (C) 2018 - 2020 Intel Corporation 11 11 */ 12 12 13 13 #ifndef MAC80211_H ··· 230 230 231 231 bool radar_enabled; 232 232 233 - u8 drv_priv[0] __aligned(sizeof(void *)); 233 + u8 drv_priv[] __aligned(sizeof(void *)); 234 234 }; 235 235 236 236 /** ··· 1670 1670 bool txqs_stopped[IEEE80211_NUM_ACS]; 1671 1671 1672 1672 /* must be last */ 1673 - u8 drv_priv[0] __aligned(sizeof(void *)); 1673 + u8 drv_priv[] __aligned(sizeof(void *)); 1674 1674 }; 1675 1675 1676 1676 static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) ··· 1798 1798 s8 keyidx; 1799 1799 u16 flags; 1800 1800 u8 keylen; 1801 - u8 key[0]; 1801 + u8 key[]; 1802 1802 }; 1803 1803 1804 1804 #define IEEE80211_MAX_PN_LEN 16 ··· 1977 1977 * @ht_cap: HT capabilities of this STA; restricted to our own capabilities 1978 1978 * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities 1979 1979 * @he_cap: HE capabilities of this STA 1980 + * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities 1980 1981 * @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU 1981 1982 * that this station is allowed to transmit to us. 1982 1983 * Can be modified by driver. ··· 2017 2016 struct ieee80211_sta_ht_cap ht_cap; 2018 2017 struct ieee80211_sta_vht_cap vht_cap; 2019 2018 struct ieee80211_sta_he_cap he_cap; 2019 + struct ieee80211_he_6ghz_capa he_6ghz_capa; 2020 2020 u16 max_rx_aggregation_subframes; 2021 2021 bool wme; 2022 2022 u8 uapsd_queues; ··· 2055 2053 struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1]; 2056 2054 2057 2055 /* must be last */ 2058 - u8 drv_priv[0] __aligned(sizeof(void *)); 2056 + u8 drv_priv[] __aligned(sizeof(void *)); 2059 2057 }; 2060 2058 2061 2059 /** ··· 2101 2099 u8 ac; 2102 2100 2103 2101 /* must be last */ 2104 - u8 drv_priv[0] __aligned(sizeof(void *)); 2102 + u8 drv_priv[] __aligned(sizeof(void *)); 2105 2103 }; 2106 2104 2107 2105 /**
+100 -26
include/uapi/linux/nl80211.h
··· 296 296 * to get a list of all present wiphys. 297 297 * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or 298 298 * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, 299 - * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the 300 - * attributes determining the channel width; this is used for setting 301 - * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT, 302 - * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, 303 - * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. 304 - * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL 305 - * instead, the support here is for backward compatibility only. 299 + * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, 300 + * %NL80211_ATTR_WIPHY_FREQ_OFFSET (and the attributes determining the 301 + * channel width; this is used for setting monitor mode channel), 302 + * %NL80211_ATTR_WIPHY_RETRY_SHORT, %NL80211_ATTR_WIPHY_RETRY_LONG, 303 + * %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, and/or 304 + * %NL80211_ATTR_WIPHY_RTS_THRESHOLD. However, for setting the channel, 305 + * see %NL80211_CMD_SET_CHANNEL instead, the support here is for backward 306 + * compatibility only. 306 307 * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request 307 308 * or rename notification. Has attributes %NL80211_ATTR_WIPHY and 308 309 * %NL80211_ATTR_WIPHY_NAME. ··· 352 351 * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT, 353 352 * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS. 354 353 * The channel to use can be set on the interface or be given using the 355 - * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. 354 + * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_WIPHY_FREQ_OFFSET, and the 355 + * attributes determining channel width. 356 356 * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP 357 357 * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface 358 358 * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP ··· 538 536 * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and 539 537 * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify 540 538 * the SSID (mainly for association, but is included in authentication 541 - * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used 542 - * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE 543 - * is used to specify the authentication type. %NL80211_ATTR_IE is used to 544 - * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs) 545 - * to be added to the frame. 539 + * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ + 540 + * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequence of the 541 + * channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the 542 + * authentication type. %NL80211_ATTR_IE is used to define IEs 543 + * (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added 544 + * to the frame. 546 545 * When used as an event, this reports reception of an Authentication 547 546 * frame in station and IBSS modes when the local MLME processed the 548 547 * frame, i.e., it was for the local STA and was received in correct ··· 598 595 * requests to connect to a specified network but without separating 599 596 * auth and assoc steps. For this, you need to specify the SSID in a 600 597 * %NL80211_ATTR_SSID attribute, and can optionally specify the association 601 - * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP, 602 - * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, 598 + * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, 599 + * %NL80211_ATTR_USE_MFP, %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, 600 + * %NL80211_ATTR_WIPHY_FREQ_OFFSET, %NL80211_ATTR_CONTROL_PORT, 603 601 * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, 604 602 * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, 605 603 * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and ··· 1164 1160 * dropped because it did not include a valid MME MIC while beacon 1165 1161 * protection was enabled (BIGTK configured in station mode). 1166 1162 * 1163 + * @NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS: Report TX status of a control 1164 + * port frame transmitted with %NL80211_CMD_CONTROL_PORT_FRAME. 1165 + * %NL80211_ATTR_COOKIE identifies the TX command and %NL80211_ATTR_FRAME 1166 + * includes the contents of the frame. %NL80211_ATTR_ACK flag is included 1167 + * if the recipient acknowledged the frame. 1168 + * 1167 1169 * @NL80211_CMD_MAX: highest used command number 1168 1170 * @__NL80211_CMD_AFTER_LAST: internal use 1169 1171 */ ··· 1398 1388 1399 1389 NL80211_CMD_UNPROT_BEACON, 1400 1390 1391 + NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, 1392 + 1401 1393 /* add new commands above here */ 1402 1394 1403 1395 /* used to define NL80211_CMD_MAX below */ ··· 1445 1433 * of &enum nl80211_chan_width, describing the channel width. See the 1446 1434 * documentation of the enum for more information. 1447 1435 * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the 1448 - * channel, used for anything but 20 MHz bandwidth 1436 + * channel, used for anything but 20 MHz bandwidth. In S1G this is the 1437 + * operating channel center frequency. 1449 1438 * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the 1450 1439 * channel, used only for 80+80 MHz bandwidth 1451 1440 * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ ··· 2493 2480 * entry without having to force a disconnection after the PMK timeout. If 2494 2481 * no roaming occurs between the reauth threshold and PMK expiration, 2495 2482 * disassociation is still forced. 2496 - * 2497 2483 * @NL80211_ATTR_RECEIVE_MULTICAST: multicast flag for the 2498 2484 * %NL80211_CMD_REGISTER_FRAME command, see the description there. 2485 + * @NL80211_ATTR_WIPHY_FREQ_OFFSET: offset of the associated 2486 + * %NL80211_ATTR_WIPHY_FREQ in positive KHz. Only valid when supplied with 2487 + * an %NL80211_ATTR_WIPHY_FREQ_OFFSET. 2488 + * @NL80211_ATTR_CENTER_FREQ1_OFFSET: Center frequency offset in KHz for the 2489 + * first channel segment specified in %NL80211_ATTR_CENTER_FREQ1. 2490 + * @NL80211_ATTR_SCAN_FREQ_KHZ: nested attribute with KHz frequencies 2491 + * 2492 + * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from 2493 + * association request when used with NL80211_CMD_NEW_STATION). 2499 2494 * 2500 2495 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2501 2496 * @NL80211_ATTR_MAX: highest attribute number currently defined ··· 2981 2960 NL80211_ATTR_PMK_REAUTH_THRESHOLD, 2982 2961 2983 2962 NL80211_ATTR_RECEIVE_MULTICAST, 2963 + NL80211_ATTR_WIPHY_FREQ_OFFSET, 2964 + NL80211_ATTR_CENTER_FREQ1_OFFSET, 2965 + NL80211_ATTR_SCAN_FREQ_KHZ, 2966 + 2967 + NL80211_ATTR_HE_6GHZ_CAPABILITY, 2984 2968 2985 2969 /* add attributes here, update the policy in nl80211.c */ 2986 2970 ··· 3565 3539 * defined in HE capabilities IE 3566 3540 * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently 3567 3541 * defined 3542 + * @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16), 3543 + * given for all 6 GHz band channels 3568 3544 * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use 3569 3545 */ 3570 3546 enum nl80211_band_iftype_attr { ··· 3577 3549 NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, 3578 3550 NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, 3579 3551 NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, 3552 + NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, 3580 3553 3581 3554 /* keep last */ 3582 3555 __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, ··· 3711 3682 * (see &enum nl80211_wmm_rule) 3712 3683 * @NL80211_FREQUENCY_ATTR_NO_HE: HE operation is not allowed on this channel 3713 3684 * in current regulatory domain. 3685 + * @NL80211_FREQUENCY_ATTR_OFFSET: frequency offset in KHz 3714 3686 * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number 3715 3687 * currently defined 3716 3688 * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use ··· 3742 3712 NL80211_FREQUENCY_ATTR_NO_10MHZ, 3743 3713 NL80211_FREQUENCY_ATTR_WMM, 3744 3714 NL80211_FREQUENCY_ATTR_NO_HE, 3715 + NL80211_FREQUENCY_ATTR_OFFSET, 3745 3716 3746 3717 /* keep last */ 3747 3718 __NL80211_FREQUENCY_ATTR_AFTER_LAST, ··· 4513 4482 * @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update. 4514 4483 * Contains a nested array of signal strength attributes (u8, dBm), 4515 4484 * using the nesting index as the antenna number. 4485 + * @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz 4516 4486 * @__NL80211_BSS_AFTER_LAST: internal 4517 4487 * @NL80211_BSS_MAX: highest BSS attribute 4518 4488 */ ··· 4538 4506 NL80211_BSS_PARENT_TSF, 4539 4507 NL80211_BSS_PARENT_BSSID, 4540 4508 NL80211_BSS_CHAIN_SIGNAL, 4509 + NL80211_BSS_FREQUENCY_OFFSET, 4541 4510 4542 4511 /* keep last */ 4543 4512 __NL80211_BSS_AFTER_LAST, ··· 4849 4816 NL80211_TID_CONFIG_DISABLE, 4850 4817 }; 4851 4818 4819 + /* enum nl80211_tx_rate_setting - TX rate configuration type 4820 + * @NL80211_TX_RATE_AUTOMATIC: automatically determine TX rate 4821 + * @NL80211_TX_RATE_LIMITED: limit the TX rate by the TX rate parameter 4822 + * @NL80211_TX_RATE_FIXED: fix TX rate to the TX rate parameter 4823 + */ 4824 + enum nl80211_tx_rate_setting { 4825 + NL80211_TX_RATE_AUTOMATIC, 4826 + NL80211_TX_RATE_LIMITED, 4827 + NL80211_TX_RATE_FIXED, 4828 + }; 4829 + 4852 4830 /* enum nl80211_tid_config_attr - TID specific configuration. 4853 4831 * @NL80211_TID_CONFIG_ATTR_PAD: pad attribute for 64-bit values 4854 4832 * @NL80211_TID_CONFIG_ATTR_VIF_SUPP: a bitmap (u64) of attributes supported ··· 4867 4823 * (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE). 4868 4824 * @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but 4869 4825 * per peer instead. 4870 - * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if no peer 4871 - * is selected, if set indicates that the new configuration overrides 4872 - * all previous peer configurations, otherwise previous peer specific 4873 - * configurations should be left untouched. If peer is selected then 4874 - * it will reset particular TID configuration of that peer and it will 4875 - * not accept other TID config attributes along with peer. 4826 + * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if set indicates 4827 + * that the new configuration overrides all previous peer 4828 + * configurations, otherwise previous peer specific configurations 4829 + * should be left untouched. 4876 4830 * @NL80211_TID_CONFIG_ATTR_TIDS: a bitmask value of TIDs (bit 0 to 7) 4877 4831 * Its type is u16. 4878 4832 * @NL80211_TID_CONFIG_ATTR_NOACK: Configure ack policy for the TID. ··· 4886 4844 * &NL80211_CMD_SET_TID_CONFIG. Its type is u8, min value is 1 and 4887 4845 * the max value is advertised by the driver in this attribute on 4888 4846 * output in wiphy capabilities. 4889 - * @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable aggregation for the TIDs 4890 - * specified in %NL80211_TID_CONFIG_ATTR_TIDS. Its type is u8, using 4891 - * the values from &nl80211_tid_config. 4847 + * @NL80211_TID_CONFIG_ATTR_AMPDU_CTRL: Enable/Disable MPDU aggregation 4848 + * for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS. 4849 + * Its type is u8, using the values from &nl80211_tid_config. 4892 4850 * @NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL: Enable/Disable RTS_CTS for the TIDs 4893 4851 * specified in %NL80211_TID_CONFIG_ATTR_TIDS. It is u8 type, using 4894 4852 * the values from &nl80211_tid_config. 4853 + * @NL80211_TID_CONFIG_ATTR_AMSDU_CTRL: Enable/Disable MSDU aggregation 4854 + * for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS. 4855 + * Its type is u8, using the values from &nl80211_tid_config. 4856 + * @NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE: This attribute will be useful 4857 + * to notfiy the driver that what type of txrate should be used 4858 + * for the TIDs specified in %NL80211_TID_CONFIG_ATTR_TIDS. using 4859 + * the values form &nl80211_tx_rate_setting. 4860 + * @NL80211_TID_CONFIG_ATTR_TX_RATE: Data frame TX rate mask should be applied 4861 + * with the parameters passed through %NL80211_ATTR_TX_RATES. 4862 + * configuration is applied to the data frame for the tid to that connected 4863 + * station. 4895 4864 */ 4896 4865 enum nl80211_tid_config_attr { 4897 4866 __NL80211_TID_CONFIG_ATTR_INVALID, ··· 4916 4863 NL80211_TID_CONFIG_ATTR_RETRY_LONG, 4917 4864 NL80211_TID_CONFIG_ATTR_AMPDU_CTRL, 4918 4865 NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL, 4866 + NL80211_TID_CONFIG_ATTR_AMSDU_CTRL, 4867 + NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, 4868 + NL80211_TID_CONFIG_ATTR_TX_RATE, 4919 4869 4920 4870 /* keep last */ 4921 4871 __NL80211_TID_CONFIG_ATTR_AFTER_LAST, ··· 5396 5340 5397 5341 #define NL80211_KCK_LEN 16 5398 5342 #define NL80211_KEK_LEN 16 5343 + #define NL80211_KCK_EXT_LEN 24 5344 + #define NL80211_KEK_EXT_LEN 32 5399 5345 #define NL80211_REPLAY_CTR_LEN 8 5400 5346 5401 5347 /** ··· 5406 5348 * @NL80211_REKEY_DATA_KEK: key encryption key (binary) 5407 5349 * @NL80211_REKEY_DATA_KCK: key confirmation key (binary) 5408 5350 * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary) 5351 + * @NL80211_REKEY_DATA_AKM: AKM data (OUI, suite type) 5409 5352 * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal) 5410 5353 * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal) 5411 5354 */ ··· 5415 5356 NL80211_REKEY_DATA_KEK, 5416 5357 NL80211_REKEY_DATA_KCK, 5417 5358 NL80211_REKEY_DATA_REPLAY_CTR, 5359 + NL80211_REKEY_DATA_AKM, 5418 5360 5419 5361 /* keep last */ 5420 5362 NUM_NL80211_REKEY_DATA, ··· 5765 5705 * @NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS: management frame registrations 5766 5706 * are possible for multicast frames and those will be reported properly. 5767 5707 * 5708 + * @NL80211_EXT_FEATURE_SCAN_FREQ_KHZ: This driver supports receiving and 5709 + * reporting scan request with %NL80211_ATTR_SCAN_FREQ_KHZ. In order to 5710 + * report %NL80211_ATTR_SCAN_FREQ_KHZ, %NL80211_SCAN_FLAG_FREQ_KHZ must be 5711 + * included in the scan request. 5712 + * 5713 + * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS: The driver 5714 + * can report tx status for control port over nl80211 tx operations. 5715 + * 5768 5716 * @NUM_NL80211_EXT_FEATURES: number of extended features. 5769 5717 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 5770 5718 */ ··· 5826 5758 NL80211_EXT_FEATURE_DEL_IBSS_STA, 5827 5759 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS, 5828 5760 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT, 5761 + NL80211_EXT_FEATURE_SCAN_FREQ_KHZ, 5762 + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS, 5829 5763 5830 5764 /* add new features before the definition below */ 5831 5765 NUM_NL80211_EXT_FEATURES, ··· 5939 5869 * @NL80211_SCAN_FLAG_MIN_PREQ_CONTENT: minimize probe request content to 5940 5870 * only have supported rates and no additional capabilities (unless 5941 5871 * added by userspace explicitly.) 5872 + * @NL80211_SCAN_FLAG_FREQ_KHZ: report scan results with 5873 + * %NL80211_ATTR_SCAN_FREQ_KHZ. This also means 5874 + * %NL80211_ATTR_SCAN_FREQUENCIES will not be included. 5942 5875 */ 5943 5876 enum nl80211_scan_flags { 5944 5877 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, ··· 5957 5884 NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10, 5958 5885 NL80211_SCAN_FLAG_RANDOM_SN = 1<<11, 5959 5886 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT = 1<<12, 5887 + NL80211_SCAN_FLAG_FREQ_KHZ = 1<<13, 5960 5888 }; 5961 5889 5962 5890 /**
+5 -1
include/uapi/linux/wireless.h
··· 74 74 #include <linux/socket.h> /* for "struct sockaddr" et al */ 75 75 #include <linux/if.h> /* for IFNAMSIZ and co... */ 76 76 77 - #include <stddef.h> /* for offsetof */ 77 + #ifdef __KERNEL__ 78 + # include <linux/stddef.h> /* for offsetof */ 79 + #else 80 + # include <stddef.h> /* for offsetof */ 81 + #endif 78 82 79 83 /***************************** VERSION *****************************/ 80 84 /*
+3 -2
net/mac80211/agg-rx.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2010, Intel Corporation 11 11 * Copyright(c) 2015-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018 Intel Corporation 12 + * Copyright (C) 2018-2020 Intel Corporation 13 13 */ 14 14 15 15 /** ··· 292 292 goto end; 293 293 } 294 294 295 - if (!sta->sta.ht_cap.ht_supported) { 295 + if (!sta->sta.ht_cap.ht_supported && 296 + sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) { 296 297 ht_dbg(sta->sdata, 297 298 "STA %pM erroneously requests BA session on tid %d w/o QoS\n", 298 299 sta->sta.addr, tid);
+2 -1
net/mac80211/agg-tx.c
··· 593 593 "Requested to start BA session on reserved tid=%d", tid)) 594 594 return -EINVAL; 595 595 596 - if (!pubsta->ht_cap.ht_supported) 596 + if (!pubsta->ht_cap.ht_supported && 597 + sta->sdata->vif.bss_conf.chandef.chan->band != NL80211_BAND_6GHZ) 597 598 return -EINVAL; 598 599 599 600 if (WARN_ON_ONCE(!local->ops->ampdu_action))
+8 -5
net/mac80211/cfg.c
··· 1520 1520 if (params->he_capa) 1521 1521 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, 1522 1522 (void *)params->he_capa, 1523 - params->he_capa_len, sta); 1523 + params->he_capa_len, 1524 + (void *)params->he_6ghz_capa, 1525 + sta); 1524 1526 1525 1527 if (params->opmode_notif_used) { 1526 1528 /* returned value is only needed for rc update, but the ··· 2198 2196 } 2199 2197 2200 2198 if (!sdata->vif.bss_conf.use_short_slot && 2201 - sband->band == NL80211_BAND_5GHZ) { 2199 + (sband->band == NL80211_BAND_5GHZ || 2200 + sband->band == NL80211_BAND_6GHZ)) { 2202 2201 sdata->vif.bss_conf.use_short_slot = true; 2203 2202 changed |= BSS_CHANGED_ERP_SLOT; 2204 2203 } ··· 3960 3957 3961 3958 static int ieee80211_reset_tid_config(struct wiphy *wiphy, 3962 3959 struct net_device *dev, 3963 - const u8 *peer, u8 tid) 3960 + const u8 *peer, u8 tids) 3964 3961 { 3965 3962 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3966 3963 struct sta_info *sta; ··· 3970 3967 return -EOPNOTSUPP; 3971 3968 3972 3969 if (!peer) 3973 - return drv_reset_tid_config(sdata->local, sdata, NULL, tid); 3970 + return drv_reset_tid_config(sdata->local, sdata, NULL, tids); 3974 3971 3975 3972 mutex_lock(&sdata->local->sta_mtx); 3976 3973 sta = sta_info_get_bss(sdata, peer); ··· 3979 3976 return -ENOENT; 3980 3977 } 3981 3978 3982 - ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tid); 3979 + ret = drv_reset_tid_config(sdata->local, sdata, &sta->sta, tids); 3983 3980 mutex_unlock(&sdata->local->sta_mtx); 3984 3981 3985 3982 return ret;
+2 -2
net/mac80211/driver-ops.h
··· 1375 1375 1376 1376 static inline int drv_reset_tid_config(struct ieee80211_local *local, 1377 1377 struct ieee80211_sub_if_data *sdata, 1378 - struct ieee80211_sta *sta, u8 tid) 1378 + struct ieee80211_sta *sta, u8 tids) 1379 1379 { 1380 1380 int ret; 1381 1381 1382 1382 might_sleep(); 1383 - ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tid); 1383 + ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids); 1384 1384 trace_drv_return_int(local, ret); 1385 1385 1386 1386 return ret;
+48
net/mac80211/he.c
··· 8 8 9 9 #include "ieee80211_i.h" 10 10 11 + static void 12 + ieee80211_update_from_he_6ghz_capa(const struct ieee80211_he_6ghz_capa *he_6ghz_capa, 13 + struct sta_info *sta) 14 + { 15 + enum ieee80211_smps_mode smps_mode; 16 + 17 + if (sta->sdata->vif.type == NL80211_IFTYPE_AP || 18 + sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 19 + switch (le16_get_bits(he_6ghz_capa->capa, 20 + IEEE80211_HE_6GHZ_CAP_SM_PS)) { 21 + case WLAN_HT_CAP_SM_PS_INVALID: 22 + case WLAN_HT_CAP_SM_PS_STATIC: 23 + smps_mode = IEEE80211_SMPS_STATIC; 24 + break; 25 + case WLAN_HT_CAP_SM_PS_DYNAMIC: 26 + smps_mode = IEEE80211_SMPS_DYNAMIC; 27 + break; 28 + case WLAN_HT_CAP_SM_PS_DISABLED: 29 + smps_mode = IEEE80211_SMPS_OFF; 30 + break; 31 + } 32 + 33 + sta->sta.smps_mode = smps_mode; 34 + } else { 35 + sta->sta.smps_mode = IEEE80211_SMPS_OFF; 36 + } 37 + 38 + switch (le16_get_bits(he_6ghz_capa->capa, 39 + IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN)) { 40 + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: 41 + sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; 42 + break; 43 + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991: 44 + sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991; 45 + break; 46 + case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895: 47 + default: 48 + sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895; 49 + break; 50 + } 51 + 52 + sta->sta.he_6ghz_capa = *he_6ghz_capa; 53 + } 54 + 11 55 void 12 56 ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata, 13 57 struct ieee80211_supported_band *sband, 14 58 const u8 *he_cap_ie, u8 he_cap_len, 59 + const struct ieee80211_he_6ghz_capa *he_6ghz_capa, 15 60 struct sta_info *sta) 16 61 { 17 62 struct ieee80211_sta_he_cap *he_cap = &sta->sta.he_cap; ··· 98 53 99 54 sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(sta); 100 55 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); 56 + 57 + if (sband->band == NL80211_BAND_6GHZ && he_6ghz_capa) 58 + ieee80211_update_from_he_6ghz_capa(he_6ghz_capa, sta); 101 59 } 102 60 103 61 void
+9 -2
net/mac80211/ibss.c
··· 9 9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> 10 10 * Copyright 2013-2014 Intel Mobile Communications GmbH 11 11 * Copyright(c) 2016 Intel Deutschland GmbH 12 - * Copyright(c) 2018-2019 Intel Corporation 12 + * Copyright(c) 2018-2020 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/delay.h> ··· 781 781 enum nl80211_channel_type ch_type; 782 782 int err; 783 783 u32 sta_flags; 784 + u32 vht_cap_info = 0; 784 785 785 786 sdata_assert_lock(sdata); 786 787 ··· 799 798 break; 800 799 } 801 800 801 + if (elems->vht_cap_elem) 802 + vht_cap_info = le32_to_cpu(elems->vht_cap_elem->vht_cap_info); 803 + 802 804 memset(&params, 0, sizeof(params)); 803 805 err = ieee80211_parse_ch_switch_ie(sdata, elems, 804 806 ifibss->chandef.chan->band, 807 + vht_cap_info, 805 808 sta_flags, ifibss->bssid, &csa_ie); 806 809 /* can't switch to destination channel, fail */ 807 810 if (err < 0) ··· 1065 1060 /* we both use VHT */ 1066 1061 struct ieee80211_vht_cap cap_ie; 1067 1062 struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap; 1063 + u32 vht_cap_info = 1064 + le32_to_cpu(elems->vht_cap_elem->vht_cap_info); 1068 1065 1069 - ieee80211_chandef_vht_oper(&local->hw, 1066 + ieee80211_chandef_vht_oper(&local->hw, vht_cap_info, 1070 1067 elems->vht_operation, 1071 1068 elems->ht_operation, 1072 1069 &chandef);
+19 -6
net/mac80211/ieee80211_i.h
··· 111 111 size_t supp_rates_len; 112 112 struct ieee80211_rate *beacon_rate; 113 113 114 + u32 vht_cap_info; 115 + 114 116 /* 115 117 * During association, we save an ERP value from a probe response so 116 118 * that we can feed ERP info to the driver when handling the ··· 269 267 struct rcu_head rcu_head; 270 268 int len; 271 269 u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM]; 272 - u8 data[0]; 270 + u8 data[]; 273 271 }; 274 272 275 273 struct ps_data { ··· 1496 1494 const struct ieee80211_he_operation *he_operation; 1497 1495 const struct ieee80211_he_spr *he_spr; 1498 1496 const struct ieee80211_mu_edca_param_set *mu_edca_param_set; 1497 + const struct ieee80211_he_6ghz_capa *he_6ghz_capa; 1499 1498 const u8 *uora_element; 1500 1499 const u8 *mesh_id; 1501 1500 const u8 *peering; ··· 1786 1783 void __ieee80211_subif_start_xmit(struct sk_buff *skb, 1787 1784 struct net_device *dev, 1788 1785 u32 info_flags, 1789 - u32 ctrl_flags); 1786 + u32 ctrl_flags, 1787 + u64 *cookie); 1790 1788 void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, 1791 1789 struct sk_buff_head *skbs); 1792 1790 struct sk_buff * ··· 1804 1800 void ieee80211_clear_fast_xmit(struct sta_info *sta); 1805 1801 int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, 1806 1802 const u8 *buf, size_t len, 1807 - const u8 *dest, __be16 proto, bool unencrypted); 1803 + const u8 *dest, __be16 proto, bool unencrypted, 1804 + u64 *cookie); 1808 1805 int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, 1809 1806 const u8 *buf, size_t len); 1810 1807 ··· 1899 1894 ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata, 1900 1895 struct ieee80211_supported_band *sband, 1901 1896 const u8 *he_cap_ie, u8 he_cap_len, 1897 + const struct ieee80211_he_6ghz_capa *he_6ghz_capa, 1902 1898 struct sta_info *sta); 1903 1899 void 1904 1900 ieee80211_he_spr_ie_to_bss_conf(struct ieee80211_vif *vif, ··· 1918 1912 * @sdata: the sdata of the interface which has received the frame 1919 1913 * @elems: parsed 802.11 elements received with the frame 1920 1914 * @current_band: indicates the current band 1915 + * @vht_cap_info: VHT capabilities of the transmitter 1921 1916 * @sta_flags: contains information about own capabilities and restrictions 1922 1917 * to decide which channel switch announcements can be accepted. Only the 1923 1918 * following subset of &enum ieee80211_sta_flags are evaluated: ··· 1933 1926 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, 1934 1927 struct ieee802_11_elems *elems, 1935 1928 enum nl80211_band current_band, 1929 + u32 vht_cap_info, 1936 1930 u32 sta_flags, u8 *bssid, 1937 1931 struct ieee80211_csa_ie *csa_ie); 1938 1932 ··· 2144 2136 IEEE80211_PROBE_FLAG_RANDOM_SN = BIT(2), 2145 2137 }; 2146 2138 2147 - int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 2139 + int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer, 2148 2140 size_t buffer_len, 2149 2141 struct ieee80211_scan_ies *ie_desc, 2150 2142 const u8 *ie, size_t ie_len, ··· 2182 2174 u8 *ieee80211_ie_build_he_cap(u8 *pos, 2183 2175 const struct ieee80211_sta_he_cap *he_cap, 2184 2176 u8 *end); 2185 - u8 *ieee80211_ie_build_he_oper(u8 *pos); 2177 + void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata, 2178 + struct sk_buff *skb); 2179 + u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef); 2186 2180 int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, 2187 2181 const struct ieee80211_supported_band *sband, 2188 2182 const u8 *srates, int srates_len, u32 *rates); ··· 2199 2189 /* channel management */ 2200 2190 bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper, 2201 2191 struct cfg80211_chan_def *chandef); 2202 - bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, 2192 + bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info, 2203 2193 const struct ieee80211_vht_operation *oper, 2204 2194 const struct ieee80211_ht_operation *htop, 2205 2195 struct cfg80211_chan_def *chandef); 2196 + bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, 2197 + const struct ieee80211_he_operation *he_oper, 2198 + struct cfg80211_chan_def *chandef); 2206 2199 u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c); 2207 2200 2208 2201 int __must_check
+4
net/mac80211/main.c
··· 596 596 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); 597 597 wiphy_ext_feature_set(wiphy, 598 598 NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH); 599 + wiphy_ext_feature_set(wiphy, 600 + NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS); 601 + wiphy_ext_feature_set(wiphy, 602 + NL80211_EXT_FEATURE_SCAN_FREQ_KHZ); 599 603 600 604 if (!ops->hw_scan) { 601 605 wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
+48 -6
net/mac80211/mesh.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (c) 2008, 2009 open80211s Ltd. 4 - * Copyright (C) 2018 - 2019 Intel Corporation 4 + * Copyright (C) 2018 - 2020 Intel Corporation 5 5 * Authors: Luis Carlos Cobo <luisca@cozybit.com> 6 6 * Javier Cardona <javier@cozybit.com> 7 7 */ ··· 63 63 u32 basic_rates = 0; 64 64 struct cfg80211_chan_def sta_chan_def; 65 65 struct ieee80211_supported_band *sband; 66 + u32 vht_cap_info = 0; 66 67 67 68 /* 68 69 * As support for each feature is added, check for matching ··· 97 96 cfg80211_chandef_create(&sta_chan_def, sdata->vif.bss_conf.chandef.chan, 98 97 NL80211_CHAN_NO_HT); 99 98 ieee80211_chandef_ht_oper(ie->ht_operation, &sta_chan_def); 100 - ieee80211_chandef_vht_oper(&sdata->local->hw, 99 + 100 + if (ie->vht_cap_elem) 101 + vht_cap_info = le32_to_cpu(ie->vht_cap_elem->vht_cap_info); 102 + 103 + ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info, 101 104 ie->vht_operation, ie->ht_operation, 102 105 &sta_chan_def); 106 + ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, &sta_chan_def); 103 107 104 108 if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef, 105 109 &sta_chan_def)) ··· 421 415 if (!sband) 422 416 return -EINVAL; 423 417 418 + /* HT not allowed in 6 GHz */ 419 + if (sband->band == NL80211_BAND_6GHZ) 420 + return 0; 421 + 424 422 if (!sband->ht_cap.ht_supported || 425 423 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || 426 424 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 || ··· 462 452 sband = local->hw.wiphy->bands[channel->band]; 463 453 ht_cap = &sband->ht_cap; 464 454 455 + /* HT not allowed in 6 GHz */ 456 + if (sband->band == NL80211_BAND_6GHZ) 457 + return 0; 458 + 465 459 if (!ht_cap->ht_supported || 466 460 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || 467 461 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 || ··· 492 478 sband = ieee80211_get_sband(sdata); 493 479 if (!sband) 494 480 return -EINVAL; 481 + 482 + /* VHT not allowed in 6 GHz */ 483 + if (sband->band == NL80211_BAND_6GHZ) 484 + return 0; 495 485 496 486 if (!sband->vht_cap.vht_supported || 497 487 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || ··· 533 515 534 516 sband = local->hw.wiphy->bands[channel->band]; 535 517 vht_cap = &sband->vht_cap; 518 + 519 + /* VHT not allowed in 6 GHz */ 520 + if (sband->band == NL80211_BAND_6GHZ) 521 + return 0; 536 522 537 523 if (!vht_cap->vht_supported || 538 524 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || ··· 587 565 { 588 566 const struct ieee80211_sta_he_cap *he_cap; 589 567 struct ieee80211_supported_band *sband; 568 + u32 len; 590 569 u8 *pos; 591 570 592 571 sband = ieee80211_get_sband(sdata); ··· 601 578 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10) 602 579 return 0; 603 580 604 - if (skb_tailroom(skb) < 2 + 1 + sizeof(struct ieee80211_he_operation)) 581 + len = 2 + 1 + sizeof(struct ieee80211_he_operation); 582 + if (sdata->vif.bss_conf.chandef.chan->band == NL80211_BAND_6GHZ) 583 + len += sizeof(struct ieee80211_he_6ghz_oper); 584 + 585 + if (skb_tailroom(skb) < len) 605 586 return -ENOMEM; 606 587 607 - pos = skb_put(skb, 2 + 1 + sizeof(struct ieee80211_he_operation)); 608 - ieee80211_ie_build_he_oper(pos); 588 + pos = skb_put(skb, len); 589 + ieee80211_ie_build_he_oper(pos, &sdata->vif.bss_conf.chandef); 609 590 591 + return 0; 592 + } 593 + 594 + int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, 595 + struct sk_buff *skb) 596 + { 597 + ieee80211_ie_build_he_6ghz_cap(sdata, skb); 610 598 return 0; 611 599 } 612 600 ··· 800 766 2 + sizeof(struct ieee80211_vht_operation) + 801 767 ie_len_he_cap + 802 768 2 + 1 + sizeof(struct ieee80211_he_operation) + 769 + sizeof(struct ieee80211_he_6ghz_oper) + 770 + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + 803 771 ifmsh->ie_len; 804 772 805 773 bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL); ··· 921 885 mesh_add_vht_oper_ie(sdata, skb) || 922 886 mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || 923 887 mesh_add_he_oper_ie(sdata, skb) || 888 + mesh_add_he_6ghz_cap_ie(sdata, skb) || 924 889 mesh_add_vendor_ies(sdata, skb)) 925 890 goto out_free; 926 891 ··· 1082 1045 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1083 1046 struct ieee80211_supported_band *sband; 1084 1047 int err; 1085 - u32 sta_flags; 1048 + u32 sta_flags, vht_cap_info = 0; 1086 1049 1087 1050 sdata_assert_lock(sdata); 1088 1051 ··· 1105 1068 break; 1106 1069 } 1107 1070 1071 + if (elems->vht_cap_elem) 1072 + vht_cap_info = 1073 + le32_to_cpu(elems->vht_cap_elem->vht_cap_info); 1074 + 1108 1075 memset(&params, 0, sizeof(params)); 1109 1076 err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band, 1077 + vht_cap_info, 1110 1078 sta_flags, sdata->vif.addr, 1111 1079 &csa_ie); 1112 1080 if (err < 0)
+2
net/mac80211/mesh.h
··· 222 222 struct sk_buff *skb, u8 ie_len); 223 223 int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, 224 224 struct sk_buff *skb); 225 + int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, 226 + struct sk_buff *skb); 225 227 void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 226 228 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 227 229 void ieee80211s_init(void);
+7 -2
net/mac80211/mesh_plink.c
··· 238 238 2 + sizeof(struct ieee80211_vht_operation) + 239 239 ie_len_he_cap + 240 240 2 + 1 + sizeof(struct ieee80211_he_operation) + 241 + sizeof(struct ieee80211_he_6ghz_oper) + 242 + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + 241 243 2 + 8 + /* peering IE */ 242 244 sdata->u.mesh.ie_len); 243 245 if (!skb) ··· 330 328 mesh_add_vht_cap_ie(sdata, skb) || 331 329 mesh_add_vht_oper_ie(sdata, skb) || 332 330 mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || 333 - mesh_add_he_oper_ie(sdata, skb)) 331 + mesh_add_he_oper_ie(sdata, skb) || 332 + mesh_add_he_6ghz_cap_ie(sdata, skb)) 334 333 goto free; 335 334 } 336 335 ··· 444 441 elems->vht_cap_elem, sta); 445 442 446 443 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, 447 - elems->he_cap_len, sta); 444 + elems->he_cap_len, 445 + elems->he_6ghz_capa, 446 + sta); 448 447 449 448 if (bw != sta->sta.bandwidth) 450 449 changed |= IEEE80211_RC_BW_CHANGED;
+85 -35
net/mac80211/mlme.c
··· 145 145 ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, 146 146 struct ieee80211_supported_band *sband, 147 147 struct ieee80211_channel *channel, 148 + u32 vht_cap_info, 148 149 const struct ieee80211_ht_operation *ht_oper, 149 150 const struct ieee80211_vht_operation *vht_oper, 150 151 const struct ieee80211_he_operation *he_oper, ··· 156 155 struct ieee80211_sta_ht_cap sta_ht_cap; 157 156 u32 ht_cfreq, ret; 158 157 159 - memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); 160 - ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); 161 - 162 158 memset(chandef, 0, sizeof(struct cfg80211_chan_def)); 163 159 chandef->chan = channel; 164 160 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 165 161 chandef->center_freq1 = channel->center_freq; 166 162 chandef->freq1_offset = channel->freq_offset; 163 + 164 + if (channel->band == NL80211_BAND_6GHZ) { 165 + if (!ieee80211_chandef_he_6ghz_oper(sdata, he_oper, chandef)) 166 + ret = IEEE80211_STA_DISABLE_HT | 167 + IEEE80211_STA_DISABLE_VHT | 168 + IEEE80211_STA_DISABLE_HE; 169 + vht_chandef = *chandef; 170 + goto out; 171 + } 172 + 173 + memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap)); 174 + ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap); 167 175 168 176 if (!ht_oper || !sta_ht_cap.ht_supported) { 169 177 ret = IEEE80211_STA_DISABLE_HT | ··· 233 223 memcpy(&he_oper_vht_cap, he_oper->optional, 3); 234 224 he_oper_vht_cap.basic_mcs_set = cpu_to_le16(0); 235 225 236 - if (!ieee80211_chandef_vht_oper(&sdata->local->hw, 226 + if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info, 237 227 &he_oper_vht_cap, ht_oper, 238 228 &vht_chandef)) { 239 229 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) ··· 242 232 ret = IEEE80211_STA_DISABLE_HE; 243 233 goto out; 244 234 } 245 - } else if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_oper, 246 - ht_oper, &vht_chandef)) { 235 + } else if (!ieee80211_chandef_vht_oper(&sdata->local->hw, 236 + vht_cap_info, 237 + vht_oper, ht_oper, 238 + &vht_chandef)) { 247 239 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 248 240 sdata_info(sdata, 249 241 "AP VHT information is invalid, disable VHT\n"); ··· 341 329 static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, 342 330 struct sta_info *sta, 343 331 const struct ieee80211_ht_cap *ht_cap, 332 + const struct ieee80211_vht_cap *vht_cap, 344 333 const struct ieee80211_ht_operation *ht_oper, 345 334 const struct ieee80211_vht_operation *vht_oper, 346 335 const struct ieee80211_he_operation *he_oper, ··· 356 343 u16 ht_opmode; 357 344 u32 flags; 358 345 enum ieee80211_sta_rx_bandwidth new_sta_bw; 346 + u32 vht_cap_info = 0; 359 347 int ret; 360 348 361 349 /* if HT was/is disabled, don't track any bandwidth changes */ ··· 385 371 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 386 372 } 387 373 374 + if (vht_cap) 375 + vht_cap_info = le32_to_cpu(vht_cap->vht_cap_info); 376 + 388 377 /* calculate new channel (type) based on HT/VHT/HE operation IEs */ 389 - flags = ieee80211_determine_chantype(sdata, sband, chan, 378 + flags = ieee80211_determine_chantype(sdata, sband, chan, vht_cap_info, 390 379 ht_oper, vht_oper, he_oper, 391 380 &chandef, true); 392 381 ··· 675 658 he_cap->he_cap_elem.phy_cap_info); 676 659 pos = skb_put(skb, he_cap_size); 677 660 ieee80211_ie_build_he_cap(pos, he_cap, pos + he_cap_size); 661 + 662 + ieee80211_ie_build_he_6ghz_cap(sdata, skb); 678 663 } 679 664 680 665 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) ··· 750 731 2 + 1 + sizeof(struct ieee80211_he_cap_elem) + /* HE */ 751 732 sizeof(struct ieee80211_he_mcs_nss_supp) + 752 733 IEEE80211_HE_PPE_THRES_MAX_LEN + 734 + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + 753 735 assoc_data->ie_len + /* extra IEs */ 754 736 (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) + 755 737 9, /* WMM */ ··· 923 903 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))) 924 904 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 925 905 926 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) 906 + if (sband->band != NL80211_BAND_6GHZ && 907 + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) 927 908 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 928 909 sband, chan, sdata->smps_mode); 929 910 ··· 978 957 offset = noffset; 979 958 } 980 959 981 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 960 + if (sband->band != NL80211_BAND_6GHZ && 961 + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) 982 962 ieee80211_add_vht_ie(sdata, skb, sband, 983 963 &assoc_data->ap_vht_cap); 984 964 ··· 1346 1324 enum nl80211_band current_band; 1347 1325 struct ieee80211_csa_ie csa_ie; 1348 1326 struct ieee80211_channel_switch ch_switch; 1327 + struct ieee80211_bss *bss; 1349 1328 int res; 1350 1329 1351 1330 sdata_assert_lock(sdata); ··· 1358 1335 return; 1359 1336 1360 1337 current_band = cbss->channel->band; 1338 + bss = (void *)cbss->priv; 1361 1339 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, 1340 + bss->vht_cap_info, 1362 1341 ifmgd->flags, 1363 1342 ifmgd->associated->bssid, &csa_ie); 1364 1343 ··· 1533 1508 chan_increment = 1; 1534 1509 break; 1535 1510 case NL80211_BAND_5GHZ: 1511 + case NL80211_BAND_6GHZ: 1536 1512 chan_increment = 4; 1537 1513 break; 1538 1514 } ··· 2171 2145 } 2172 2146 2173 2147 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); 2174 - if (sband->band == NL80211_BAND_5GHZ) 2148 + if (sband->band == NL80211_BAND_5GHZ || 2149 + sband->band == NL80211_BAND_6GHZ) 2175 2150 use_short_slot = true; 2176 2151 2177 2152 if (use_protection != bss_conf->use_cts_prot) { ··· 3261 3234 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 3262 3235 const struct cfg80211_bss_ies *bss_ies = NULL; 3263 3236 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; 3237 + bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ; 3264 3238 u32 changed = 0; 3265 3239 int err; 3266 3240 bool ret; ··· 3303 3275 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T", 3304 3276 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device. 3305 3277 */ 3306 - if ((assoc_data->wmm && !elems->wmm_param) || 3307 - (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3308 - (!elems->ht_cap_elem || !elems->ht_operation)) || 3309 - (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 3310 - (!elems->vht_cap_elem || !elems->vht_operation))) { 3278 + if (!is_6ghz && 3279 + ((assoc_data->wmm && !elems->wmm_param) || 3280 + (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3281 + (!elems->ht_cap_elem || !elems->ht_operation)) || 3282 + (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 3283 + (!elems->vht_cap_elem || !elems->vht_operation)))) { 3311 3284 const struct cfg80211_bss_ies *ies; 3312 3285 struct ieee802_11_elems bss_elems; 3313 3286 ··· 3366 3337 * We previously checked these in the beacon/probe response, so 3367 3338 * they should be present here. This is just a safety net. 3368 3339 */ 3369 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3340 + if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3370 3341 (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) { 3371 3342 sdata_info(sdata, 3372 3343 "HT AP is missing WMM params or HT capability/operation\n"); ··· 3374 3345 goto out; 3375 3346 } 3376 3347 3377 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 3348 + if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && 3378 3349 (!elems->vht_cap_elem || !elems->vht_operation)) { 3379 3350 sdata_info(sdata, 3380 3351 "VHT AP is missing VHT capability/operation\n"); 3352 + ret = false; 3353 + goto out; 3354 + } 3355 + 3356 + if (is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) && 3357 + !elems->he_6ghz_capa) { 3358 + sdata_info(sdata, 3359 + "HE 6 GHz AP is missing HE 6 GHz band capability\n"); 3381 3360 ret = false; 3382 3361 goto out; 3383 3362 } ··· 3432 3395 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, 3433 3396 elems->he_cap, 3434 3397 elems->he_cap_len, 3398 + elems->he_6ghz_capa, 3435 3399 sta); 3436 3400 3437 3401 bss_conf->he_support = sta->sta.he_cap.has_he; ··· 4132 4094 4133 4095 changed |= ieee80211_recalc_twt_req(sdata, sta, &elems); 4134 4096 4135 - if (ieee80211_config_bw(sdata, sta, 4136 - elems.ht_cap_elem, elems.ht_operation, 4097 + if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem, 4098 + elems.vht_cap_elem, elems.ht_operation, 4137 4099 elems.vht_operation, elems.he_operation, 4138 4100 bssid, &changed)) { 4139 4101 mutex_unlock(&local->sta_mtx); ··· 4850 4812 const struct ieee80211_he_operation *he_oper = NULL; 4851 4813 struct ieee80211_supported_band *sband; 4852 4814 struct cfg80211_chan_def chandef; 4815 + bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ; 4816 + struct ieee80211_bss *bss = (void *)cbss->priv; 4853 4817 int ret; 4854 4818 u32 i; 4855 4819 bool have_80mhz; ··· 4863 4823 IEEE80211_STA_DISABLE_160MHZ); 4864 4824 4865 4825 /* disable HT/VHT/HE if we don't support them */ 4866 - if (!sband->ht_cap.ht_supported) { 4826 + if (!sband->ht_cap.ht_supported && !is_6ghz) { 4867 4827 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 4868 4828 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 4869 4829 ifmgd->flags |= IEEE80211_STA_DISABLE_HE; 4870 4830 } 4871 4831 4872 - if (!sband->vht_cap.vht_supported) 4832 + if (!sband->vht_cap.vht_supported && !is_6ghz) { 4873 4833 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 4834 + ifmgd->flags |= IEEE80211_STA_DISABLE_HE; 4835 + } 4874 4836 4875 4837 if (!ieee80211_get_he_sta_cap(sband)) 4876 4838 ifmgd->flags |= IEEE80211_STA_DISABLE_HE; 4877 4839 4878 4840 rcu_read_lock(); 4879 4841 4880 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { 4842 + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && !is_6ghz) { 4881 4843 const u8 *ht_oper_ie, *ht_cap_ie; 4882 4844 4883 4845 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); ··· 4896 4854 } 4897 4855 } 4898 4856 4899 - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { 4857 + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && !is_6ghz) { 4900 4858 const u8 *vht_oper_ie, *vht_cap; 4901 4859 4902 4860 vht_oper_ie = ieee80211_bss_get_ie(cbss, ··· 4952 4910 4953 4911 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, 4954 4912 cbss->channel, 4913 + bss->vht_cap_info, 4955 4914 ht_oper, vht_oper, he_oper, 4956 4915 &chandef, false); 4957 4916 ··· 4960 4917 local->rx_chains); 4961 4918 4962 4919 rcu_read_unlock(); 4920 + 4921 + if (ifmgd->flags & IEEE80211_STA_DISABLE_HE && is_6ghz) { 4922 + sdata_info(sdata, "Rejecting non-HE 6/7 GHz connection"); 4923 + return -EINVAL; 4924 + } 4963 4925 4964 4926 /* will change later if needed */ 4965 4927 sdata->smps_mode = IEEE80211_SMPS_OFF; ··· 5347 5299 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, 5348 5300 struct cfg80211_assoc_request *req) 5349 5301 { 5302 + bool is_6ghz = req->bss->channel->band == NL80211_BAND_6GHZ; 5350 5303 struct ieee80211_local *local = sdata->local; 5351 5304 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 5352 5305 struct ieee80211_bss *bss = (void *)req->bss->priv; ··· 5490 5441 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) 5491 5442 assoc_data->ap_ht_param = 5492 5443 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; 5493 - else 5444 + else if (!is_6ghz) 5494 5445 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 5495 5446 vht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_VHT_CAPABILITY); 5496 5447 if (vht_ie && vht_ie[1] >= sizeof(struct ieee80211_vht_cap)) 5497 5448 memcpy(&assoc_data->ap_vht_cap, vht_ie + 2, 5498 5449 sizeof(struct ieee80211_vht_cap)); 5499 - else 5500 - ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; 5450 + else if (!is_6ghz) 5451 + ifmgd->flags |= IEEE80211_STA_DISABLE_VHT | 5452 + IEEE80211_STA_DISABLE_HE; 5501 5453 rcu_read_unlock(); 5502 5454 5503 5455 if (WARN((sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD) && ··· 5599 5549 assoc_data->timeout_started = true; 5600 5550 assoc_data->need_beacon = true; 5601 5551 } else if (beacon_ies) { 5602 - const u8 *ie; 5552 + const struct element *elem; 5603 5553 u8 dtim_count = 0; 5604 5554 5605 5555 ieee80211_get_dtim(beacon_ies, &dtim_count, ··· 5616 5566 sdata->vif.bss_conf.sync_dtim_count = dtim_count; 5617 5567 } 5618 5568 5619 - ie = cfg80211_find_ext_ie(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION, 5620 - beacon_ies->data, beacon_ies->len); 5621 - if (ie && ie[1] >= 3) 5622 - sdata->vif.bss_conf.profile_periodicity = ie[4]; 5569 + elem = cfg80211_find_ext_elem(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION, 5570 + beacon_ies->data, beacon_ies->len); 5571 + if (elem && elem->datalen >= 3) 5572 + sdata->vif.bss_conf.profile_periodicity = elem->data[2]; 5623 5573 5624 - ie = cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, 5625 - beacon_ies->data, beacon_ies->len); 5626 - if (ie && ie[1] >= 11 && 5627 - (ie[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) 5574 + elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, 5575 + beacon_ies->data, beacon_ies->len); 5576 + if (elem && elem->datalen >= 11 && 5577 + (elem->data[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) 5628 5578 sdata->vif.bss_conf.ema_ap = true; 5629 5579 } else { 5630 5580 assoc_data->timeout = jiffies;
+80 -25
net/mac80211/rx.c
··· 93 93 * This function cleans up the SKB, i.e. it removes all the stuff 94 94 * only useful for monitoring. 95 95 */ 96 - static void remove_monitor_info(struct sk_buff *skb, 97 - unsigned int present_fcs_len, 98 - unsigned int rtap_space) 96 + static struct sk_buff *ieee80211_clean_skb(struct sk_buff *skb, 97 + unsigned int present_fcs_len, 98 + unsigned int rtap_space) 99 99 { 100 + struct ieee80211_hdr *hdr; 101 + unsigned int hdrlen; 102 + __le16 fc; 103 + 100 104 if (present_fcs_len) 101 105 __pskb_trim(skb, skb->len - present_fcs_len); 102 106 __pskb_pull(skb, rtap_space); 107 + 108 + hdr = (void *)skb->data; 109 + fc = hdr->frame_control; 110 + 111 + /* 112 + * Remove the HT-Control field (if present) on management 113 + * frames after we've sent the frame to monitoring. We 114 + * (currently) don't need it, and don't properly parse 115 + * frames with it present, due to the assumption of a 116 + * fixed management header length. 117 + */ 118 + if (likely(!ieee80211_is_mgmt(fc) || !ieee80211_has_order(fc))) 119 + return skb; 120 + 121 + hdrlen = ieee80211_hdrlen(fc); 122 + hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_ORDER); 123 + 124 + if (!pskb_may_pull(skb, hdrlen)) { 125 + dev_kfree_skb(skb); 126 + return NULL; 127 + } 128 + 129 + memmove(skb->data + IEEE80211_HT_CTL_LEN, skb->data, 130 + hdrlen - IEEE80211_HT_CTL_LEN); 131 + __pskb_pull(skb, IEEE80211_HT_CTL_LEN); 132 + 133 + return skb; 103 134 } 104 135 105 136 static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len, ··· 858 827 return NULL; 859 828 } 860 829 861 - remove_monitor_info(origskb, present_fcs_len, rtap_space); 862 - return origskb; 830 + return ieee80211_clean_skb(origskb, present_fcs_len, 831 + rtap_space); 863 832 } 864 833 865 834 ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space); ··· 902 871 if (!origskb) 903 872 return NULL; 904 873 905 - remove_monitor_info(origskb, present_fcs_len, rtap_space); 906 - return origskb; 874 + return ieee80211_clean_skb(origskb, present_fcs_len, rtap_space); 907 875 } 908 876 909 877 static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) ··· 3125 3095 !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) 3126 3096 sig = status->signal; 3127 3097 3128 - cfg80211_report_obss_beacon(rx->local->hw.wiphy, 3129 - rx->skb->data, rx->skb->len, 3130 - status->freq, sig); 3098 + cfg80211_report_obss_beacon_khz(rx->local->hw.wiphy, 3099 + rx->skb->data, rx->skb->len, 3100 + ieee80211_rx_status_to_khz(status), 3101 + sig); 3131 3102 rx->flags |= IEEE80211_RX_BEACON_REPORTED; 3132 3103 } 3133 3104 ··· 3384 3353 } 3385 3354 } 3386 3355 break; 3387 - case WLAN_CATEGORY_SA_QUERY: 3388 - if (len < (IEEE80211_MIN_ACTION_SIZE + 3389 - sizeof(mgmt->u.action.u.sa_query))) 3390 - break; 3391 - 3392 - switch (mgmt->u.action.u.sa_query.action) { 3393 - case WLAN_ACTION_SA_QUERY_REQUEST: 3394 - if (sdata->vif.type != NL80211_IFTYPE_STATION) 3395 - break; 3396 - ieee80211_process_sa_query_req(sdata, mgmt, len); 3397 - goto handled; 3398 - } 3399 - break; 3400 3356 case WLAN_CATEGORY_SELF_PROTECTED: 3401 3357 if (len < (IEEE80211_MIN_ACTION_SIZE + 3402 3358 sizeof(mgmt->u.action.u.self_prot.action_code))) ··· 3461 3443 !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) 3462 3444 sig = status->signal; 3463 3445 3464 - if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, 3465 - rx->skb->data, rx->skb->len, 0)) { 3446 + if (cfg80211_rx_mgmt_khz(&rx->sdata->wdev, 3447 + ieee80211_rx_status_to_khz(status), sig, 3448 + rx->skb->data, rx->skb->len, 0)) { 3466 3449 if (rx->sta) 3467 3450 rx->sta->rx_stats.packets++; 3468 3451 dev_kfree_skb(rx->skb); ··· 3471 3452 } 3472 3453 3473 3454 return RX_CONTINUE; 3455 + } 3456 + 3457 + static ieee80211_rx_result debug_noinline 3458 + ieee80211_rx_h_action_post_userspace(struct ieee80211_rx_data *rx) 3459 + { 3460 + struct ieee80211_sub_if_data *sdata = rx->sdata; 3461 + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; 3462 + int len = rx->skb->len; 3463 + 3464 + if (!ieee80211_is_action(mgmt->frame_control)) 3465 + return RX_CONTINUE; 3466 + 3467 + switch (mgmt->u.action.category) { 3468 + case WLAN_CATEGORY_SA_QUERY: 3469 + if (len < (IEEE80211_MIN_ACTION_SIZE + 3470 + sizeof(mgmt->u.action.u.sa_query))) 3471 + break; 3472 + 3473 + switch (mgmt->u.action.u.sa_query.action) { 3474 + case WLAN_ACTION_SA_QUERY_REQUEST: 3475 + if (sdata->vif.type != NL80211_IFTYPE_STATION) 3476 + break; 3477 + ieee80211_process_sa_query_req(sdata, mgmt, len); 3478 + goto handled; 3479 + } 3480 + break; 3481 + } 3482 + 3483 + return RX_CONTINUE; 3484 + 3485 + handled: 3486 + if (rx->sta) 3487 + rx->sta->rx_stats.packets++; 3488 + dev_kfree_skb(rx->skb); 3489 + return RX_QUEUED; 3474 3490 } 3475 3491 3476 3492 static ieee80211_rx_result debug_noinline ··· 3788 3734 CALL_RXH(ieee80211_rx_h_mgmt_check); 3789 3735 CALL_RXH(ieee80211_rx_h_action); 3790 3736 CALL_RXH(ieee80211_rx_h_userspace_mgmt); 3737 + CALL_RXH(ieee80211_rx_h_action_post_userspace); 3791 3738 CALL_RXH(ieee80211_rx_h_action_return); 3792 3739 CALL_RXH(ieee80211_rx_h_mgmt); 3793 3740
+15 -8
net/mac80211/scan.c
··· 132 132 bss->beacon_rate = 133 133 &sband->bitrates[rx_status->rate_idx]; 134 134 } 135 + 136 + if (elems->vht_cap_elem) 137 + bss->vht_cap_info = 138 + le32_to_cpu(elems->vht_cap_elem->vht_cap_info); 139 + else 140 + bss->vht_cap_info = 0; 135 141 } 136 142 137 143 struct ieee80211_bss * ··· 313 307 } 314 308 315 309 /* return false if no more work */ 316 - static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) 310 + static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata) 317 311 { 312 + struct ieee80211_local *local = sdata->local; 318 313 struct cfg80211_scan_request *req; 319 314 struct cfg80211_chan_def chandef; 320 315 u8 bands_used = 0; ··· 362 355 if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) 363 356 flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; 364 357 365 - ielen = ieee80211_build_preq_ies(local, 358 + ielen = ieee80211_build_preq_ies(sdata, 366 359 (u8 *)local->hw_scan_req->req.ie, 367 360 local->hw_scan_ies_bufsize, 368 361 &local->hw_scan_req->ies, ··· 402 395 if (WARN_ON(!local->scan_req)) 403 396 return; 404 397 398 + scan_sdata = rcu_dereference_protected(local->scan_sdata, 399 + lockdep_is_held(&local->mtx)); 400 + 405 401 if (hw_scan && !aborted && 406 402 !ieee80211_hw_check(&local->hw, SINGLE_SCAN_ON_ALL_BANDS) && 407 - ieee80211_prep_hw_scan(local)) { 403 + ieee80211_prep_hw_scan(scan_sdata)) { 408 404 int rc; 409 405 410 406 rc = drv_hw_scan(local, ··· 436 426 cfg80211_scan_done(scan_req, &local->scan_info); 437 427 } 438 428 RCU_INIT_POINTER(local->scan_req, NULL); 439 - 440 - scan_sdata = rcu_dereference_protected(local->scan_sdata, 441 - lockdep_is_held(&local->mtx)); 442 429 RCU_INIT_POINTER(local->scan_sdata, NULL); 443 430 444 431 local->scanning = 0; ··· 777 770 ieee80211_recalc_idle(local); 778 771 779 772 if (hw_scan) { 780 - WARN_ON(!ieee80211_prep_hw_scan(local)); 773 + WARN_ON(!ieee80211_prep_hw_scan(sdata)); 781 774 rc = drv_hw_scan(local, sdata, local->hw_scan_req); 782 775 } else { 783 776 rc = ieee80211_start_sw_scan(local, sdata); ··· 1275 1268 1276 1269 ieee80211_prepare_scan_chandef(&chandef, req->scan_width); 1277 1270 1278 - ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, 1271 + ieee80211_build_preq_ies(sdata, ie, num_bands * iebufsz, 1279 1272 &sched_scan_ies, req->ie, 1280 1273 req->ie_len, bands_used, rate_masks, &chandef, 1281 1274 flags);
+3 -1
net/mac80211/spectmgmt.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2007-2008, Intel Corporation 11 11 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 12 - * Copyright (C) 2018 Intel Corporation 12 + * Copyright (C) 2018, 2020 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 22 22 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, 23 23 struct ieee802_11_elems *elems, 24 24 enum nl80211_band current_band, 25 + u32 vht_cap_info, 25 26 u32 sta_flags, u8 *bssid, 26 27 struct ieee80211_csa_ie *csa_ie) 27 28 { ··· 151 150 152 151 /* ignore if parsing fails */ 153 152 if (!ieee80211_chandef_vht_oper(&sdata->local->hw, 153 + vht_cap_info, 154 154 &vht_oper, &ht_oper, 155 155 &new_vht_chandef)) 156 156 new_vht_chandef.chan = NULL;
+8 -1
net/mac80211/status.c
··· 649 649 info->status.ack_signal, 650 650 info->status.is_valid_ack_signal, 651 651 GFP_ATOMIC); 652 - else 652 + else if (ieee80211_is_mgmt(hdr->frame_control)) 653 653 cfg80211_mgmt_tx_status(&sdata->wdev, cookie, 654 654 skb->data, skb->len, 655 655 acked, GFP_ATOMIC); 656 + else 657 + cfg80211_control_port_tx_status(&sdata->wdev, 658 + cookie, 659 + skb->data, 660 + skb->len, 661 + acked, 662 + GFP_ATOMIC); 656 663 } 657 664 rcu_read_unlock(); 658 665
+1 -1
net/mac80211/tdls.c
··· 1054 1054 1055 1055 /* disable bottom halves when entering the Tx path */ 1056 1056 local_bh_disable(); 1057 - __ieee80211_subif_start_xmit(skb, dev, flags, 0); 1057 + __ieee80211_subif_start_xmit(skb, dev, flags, 0, NULL); 1058 1058 local_bh_enable(); 1059 1059 1060 1060 return ret;
+45 -20
net/mac80211/tx.c
··· 2436 2436 return 0; 2437 2437 } 2438 2438 2439 - static int ieee80211_store_ack_skb(struct ieee80211_local *local, 2439 + static u16 ieee80211_store_ack_skb(struct ieee80211_local *local, 2440 2440 struct sk_buff *skb, 2441 - u32 *info_flags) 2441 + u32 *info_flags, 2442 + u64 *cookie) 2442 2443 { 2443 - struct sk_buff *ack_skb = skb_clone_sk(skb); 2444 + struct sk_buff *ack_skb; 2444 2445 u16 info_id = 0; 2446 + 2447 + if (skb->sk) 2448 + ack_skb = skb_clone_sk(skb); 2449 + else 2450 + ack_skb = skb_clone(skb, GFP_ATOMIC); 2445 2451 2446 2452 if (ack_skb) { 2447 2453 unsigned long flags; ··· 2461 2455 if (id >= 0) { 2462 2456 info_id = id; 2463 2457 *info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 2458 + if (cookie) { 2459 + *cookie = ieee80211_mgmt_tx_cookie(local); 2460 + IEEE80211_SKB_CB(ack_skb)->ack.cookie = *cookie; 2461 + } 2464 2462 } else { 2465 2463 kfree_skb(ack_skb); 2466 2464 } ··· 2494 2484 */ 2495 2485 static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, 2496 2486 struct sk_buff *skb, u32 info_flags, 2497 - struct sta_info *sta, u32 ctrl_flags) 2487 + struct sta_info *sta, u32 ctrl_flags, 2488 + u64 *cookie) 2498 2489 { 2499 2490 struct ieee80211_local *local = sdata->local; 2500 2491 struct ieee80211_tx_info *info; ··· 2766 2755 goto free; 2767 2756 } 2768 2757 2769 - if (unlikely(!multicast && skb->sk && 2770 - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) 2771 - info_id = ieee80211_store_ack_skb(local, skb, &info_flags); 2758 + if (unlikely(!multicast && ((skb->sk && 2759 + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || 2760 + ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS))) 2761 + info_id = ieee80211_store_ack_skb(local, skb, &info_flags, 2762 + cookie); 2772 2763 2773 2764 /* 2774 2765 * If the skb is shared we need to obtain our own copy. ··· 3926 3913 void __ieee80211_subif_start_xmit(struct sk_buff *skb, 3927 3914 struct net_device *dev, 3928 3915 u32 info_flags, 3929 - u32 ctrl_flags) 3916 + u32 ctrl_flags, 3917 + u64 *cookie) 3930 3918 { 3931 3919 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3932 3920 struct ieee80211_local *local = sdata->local; ··· 3997 3983 skb_mark_not_on_list(skb); 3998 3984 3999 3985 skb = ieee80211_build_hdr(sdata, skb, info_flags, 4000 - sta, ctrl_flags); 3986 + sta, ctrl_flags, cookie); 4001 3987 if (IS_ERR(skb)) { 4002 3988 kfree_skb_list(next); 4003 3989 goto out; ··· 4139 4125 __skb_queue_head_init(&queue); 4140 4126 ieee80211_convert_to_unicast(skb, dev, &queue); 4141 4127 while ((skb = __skb_dequeue(&queue))) 4142 - __ieee80211_subif_start_xmit(skb, dev, 0, 0); 4128 + __ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL); 4143 4129 } else { 4144 - __ieee80211_subif_start_xmit(skb, dev, 0, 0); 4130 + __ieee80211_subif_start_xmit(skb, dev, 0, 0, NULL); 4145 4131 } 4146 4132 4147 4133 return NETDEV_TX_OK; ··· 4229 4215 4230 4216 if (unlikely(!multicast && skb->sk && 4231 4217 skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) 4232 - ieee80211_store_ack_skb(local, skb, &info->flags); 4218 + ieee80211_store_ack_skb(local, skb, &info->flags, NULL); 4233 4219 4234 4220 memset(info, 0, sizeof(*info)); 4235 4221 ··· 4313 4299 goto out; 4314 4300 } 4315 4301 4316 - skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, 0); 4302 + skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, 0, NULL); 4317 4303 if (IS_ERR(skb)) 4318 4304 goto out; 4319 4305 ··· 5353 5339 5354 5340 int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, 5355 5341 const u8 *buf, size_t len, 5356 - const u8 *dest, __be16 proto, bool unencrypted) 5342 + const u8 *dest, __be16 proto, bool unencrypted, 5343 + u64 *cookie) 5357 5344 { 5358 5345 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 5359 5346 struct ieee80211_local *local = sdata->local; 5360 5347 struct sk_buff *skb; 5361 5348 struct ethhdr *ehdr; 5362 5349 u32 ctrl_flags = 0; 5363 - u32 flags; 5350 + u32 flags = 0; 5364 5351 5365 5352 /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE 5366 5353 * or Pre-Authentication ··· 5374 5359 ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; 5375 5360 5376 5361 if (unencrypted) 5377 - flags = IEEE80211_TX_INTFL_DONT_ENCRYPT; 5378 - else 5379 - flags = 0; 5362 + flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 5363 + 5364 + if (cookie) 5365 + ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 5366 + 5367 + flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX | 5368 + IEEE80211_TX_CTL_INJECTED; 5380 5369 5381 5370 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 5382 5371 sizeof(struct ethhdr) + len); ··· 5401 5382 skb_reset_network_header(skb); 5402 5383 skb_reset_mac_header(skb); 5403 5384 5385 + /* mutex lock is only needed for incrementing the cookie counter */ 5386 + mutex_lock(&local->mtx); 5387 + 5404 5388 local_bh_disable(); 5405 - __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags); 5389 + __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); 5406 5390 local_bh_enable(); 5391 + 5392 + mutex_unlock(&local->mtx); 5407 5393 5408 5394 return 0; 5409 5395 } ··· 5436 5412 5437 5413 local_bh_disable(); 5438 5414 __ieee80211_subif_start_xmit(skb, skb->dev, 0, 5439 - IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP); 5415 + IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP, 5416 + NULL); 5440 5417 local_bh_enable(); 5441 5418 5442 5419 return 0;
+286 -12
net/mac80211/util.c
··· 936 936 len >= ieee80211_he_spr_size(data)) 937 937 elems->he_spr = data; 938 938 break; 939 + case WLAN_EID_EXT_HE_6GHZ_CAPA: 940 + if (len == sizeof(*elems->he_6ghz_capa)) 941 + elems->he_6ghz_capa = data; 942 + break; 939 943 } 940 944 } 941 945 ··· 1663 1659 } 1664 1660 } 1665 1661 1666 - static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, 1662 + static u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end) 1663 + { 1664 + if ((end - pos) < 5) 1665 + return pos; 1666 + 1667 + *pos++ = WLAN_EID_EXTENSION; 1668 + *pos++ = 1 + sizeof(cap); 1669 + *pos++ = WLAN_EID_EXT_HE_6GHZ_CAPA; 1670 + memcpy(pos, &cap, sizeof(cap)); 1671 + 1672 + return pos + 2; 1673 + } 1674 + 1675 + static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata, 1667 1676 u8 *buffer, size_t buffer_len, 1668 1677 const u8 *ie, size_t ie_len, 1669 1678 enum nl80211_band band, ··· 1684 1667 struct cfg80211_chan_def *chandef, 1685 1668 size_t *offset, u32 flags) 1686 1669 { 1670 + struct ieee80211_local *local = sdata->local; 1687 1671 struct ieee80211_supported_band *sband; 1688 1672 const struct ieee80211_sta_he_cap *he_cap; 1689 1673 u8 *pos = buffer, *end = buffer + buffer_len; ··· 1862 1844 pos = ieee80211_ie_build_he_cap(pos, he_cap, end); 1863 1845 if (!pos) 1864 1846 goto out_err; 1847 + 1848 + if (sband->band == NL80211_BAND_6GHZ) { 1849 + enum nl80211_iftype iftype = 1850 + ieee80211_vif_type_p2p(&sdata->vif); 1851 + __le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype); 1852 + 1853 + pos = ieee80211_write_he_6ghz_cap(pos, cap, end); 1854 + } 1865 1855 } 1866 1856 1867 1857 /* ··· 1884 1858 return pos - buffer; 1885 1859 } 1886 1860 1887 - int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1861 + int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer, 1888 1862 size_t buffer_len, 1889 1863 struct ieee80211_scan_ies *ie_desc, 1890 1864 const u8 *ie, size_t ie_len, ··· 1899 1873 1900 1874 for (i = 0; i < NUM_NL80211_BANDS; i++) { 1901 1875 if (bands_used & BIT(i)) { 1902 - pos += ieee80211_build_preq_ies_band(local, 1876 + pos += ieee80211_build_preq_ies_band(sdata, 1903 1877 buffer + pos, 1904 1878 buffer_len - pos, 1905 1879 ie, ie_len, i, ··· 1961 1935 return NULL; 1962 1936 1963 1937 rate_masks[chan->band] = ratemask; 1964 - ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1938 + ies_len = ieee80211_build_preq_ies(sdata, skb_tail_pointer(skb), 1965 1939 skb_tailroom(skb), &dummy_ie_desc, 1966 1940 ie, ie_len, BIT(chan->band), 1967 1941 rate_masks, &chandef, flags); ··· 2861 2835 return pos; 2862 2836 } 2863 2837 2838 + void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata, 2839 + struct sk_buff *skb) 2840 + { 2841 + struct ieee80211_supported_band *sband; 2842 + const struct ieee80211_sband_iftype_data *iftd; 2843 + enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif); 2844 + u8 *pos; 2845 + u16 cap; 2846 + 2847 + sband = ieee80211_get_sband(sdata); 2848 + if (!sband) 2849 + return; 2850 + 2851 + iftd = ieee80211_get_sband_iftype_data(sband, iftype); 2852 + if (WARN_ON(!iftd)) 2853 + return; 2854 + 2855 + cap = le16_to_cpu(iftd->he_6ghz_capa.capa); 2856 + cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS; 2857 + 2858 + switch (sdata->smps_mode) { 2859 + case IEEE80211_SMPS_AUTOMATIC: 2860 + case IEEE80211_SMPS_NUM_MODES: 2861 + WARN_ON(1); 2862 + /* fall through */ 2863 + case IEEE80211_SMPS_OFF: 2864 + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED, 2865 + IEEE80211_HE_6GHZ_CAP_SM_PS); 2866 + break; 2867 + case IEEE80211_SMPS_STATIC: 2868 + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC, 2869 + IEEE80211_HE_6GHZ_CAP_SM_PS); 2870 + break; 2871 + case IEEE80211_SMPS_DYNAMIC: 2872 + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC, 2873 + IEEE80211_HE_6GHZ_CAP_SM_PS); 2874 + break; 2875 + } 2876 + 2877 + pos = skb_put(skb, 2 + 1 + sizeof(cap)); 2878 + ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap), 2879 + pos + 2 + 1 + sizeof(cap)); 2880 + } 2881 + 2864 2882 u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 2865 2883 const struct cfg80211_chan_def *chandef, 2866 2884 u16 prot_mode, bool rifs_mode) ··· 3028 2958 return pos + sizeof(struct ieee80211_vht_operation); 3029 2959 } 3030 2960 3031 - u8 *ieee80211_ie_build_he_oper(u8 *pos) 2961 + u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef) 3032 2962 { 3033 2963 struct ieee80211_he_operation *he_oper; 2964 + struct ieee80211_he_6ghz_oper *he_6ghz_op; 3034 2965 u32 he_oper_params; 2966 + u8 ie_len = 1 + sizeof(struct ieee80211_he_operation); 2967 + 2968 + if (chandef->chan->band == NL80211_BAND_6GHZ) 2969 + ie_len += sizeof(struct ieee80211_he_6ghz_oper); 3035 2970 3036 2971 *pos++ = WLAN_EID_EXTENSION; 3037 - *pos++ = 1 + sizeof(struct ieee80211_he_operation); 2972 + *pos++ = ie_len; 3038 2973 *pos++ = WLAN_EID_EXT_HE_OPERATION; 3039 2974 3040 2975 he_oper_params = 0; ··· 3049 2974 IEEE80211_HE_OPERATION_ER_SU_DISABLE); 3050 2975 he_oper_params |= u32_encode_bits(1, 3051 2976 IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED); 2977 + if (chandef->chan->band == NL80211_BAND_6GHZ) 2978 + he_oper_params |= u32_encode_bits(1, 2979 + IEEE80211_HE_OPERATION_6GHZ_OP_INFO); 3052 2980 3053 2981 he_oper = (struct ieee80211_he_operation *)pos; 3054 2982 he_oper->he_oper_params = cpu_to_le32(he_oper_params); 3055 2983 3056 2984 /* don't require special HE peer rates */ 3057 2985 he_oper->he_mcs_nss_set = cpu_to_le16(0xffff); 2986 + pos += sizeof(struct ieee80211_he_operation); 3058 2987 3059 - /* TODO add VHT operational and 6GHz operational subelement? */ 2988 + if (chandef->chan->band != NL80211_BAND_6GHZ) 2989 + goto out; 3060 2990 3061 - return pos + sizeof(struct ieee80211_vht_operation); 2991 + /* TODO add VHT operational */ 2992 + he_6ghz_op = (struct ieee80211_he_6ghz_oper *)pos; 2993 + he_6ghz_op->minrate = 6; /* 6 Mbps */ 2994 + he_6ghz_op->primary = 2995 + ieee80211_frequency_to_channel(chandef->chan->center_freq); 2996 + he_6ghz_op->ccfs0 = 2997 + ieee80211_frequency_to_channel(chandef->center_freq1); 2998 + if (chandef->center_freq2) 2999 + he_6ghz_op->ccfs1 = 3000 + ieee80211_frequency_to_channel(chandef->center_freq2); 3001 + else 3002 + he_6ghz_op->ccfs1 = 0; 3003 + 3004 + switch (chandef->width) { 3005 + case NL80211_CHAN_WIDTH_160: 3006 + /* Convert 160 MHz channel width to new style as interop 3007 + * workaround. 3008 + */ 3009 + he_6ghz_op->control = 3010 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ; 3011 + he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0; 3012 + if (chandef->chan->center_freq < chandef->center_freq1) 3013 + he_6ghz_op->ccfs0 -= 8; 3014 + else 3015 + he_6ghz_op->ccfs0 += 8; 3016 + fallthrough; 3017 + case NL80211_CHAN_WIDTH_80P80: 3018 + he_6ghz_op->control = 3019 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ; 3020 + break; 3021 + case NL80211_CHAN_WIDTH_80: 3022 + he_6ghz_op->control = 3023 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ; 3024 + break; 3025 + case NL80211_CHAN_WIDTH_40: 3026 + he_6ghz_op->control = 3027 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ; 3028 + break; 3029 + default: 3030 + he_6ghz_op->control = 3031 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ; 3032 + break; 3033 + } 3034 + 3035 + pos += sizeof(struct ieee80211_he_6ghz_oper); 3036 + 3037 + out: 3038 + return pos; 3062 3039 } 3063 3040 3064 3041 bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper, ··· 3140 3013 return true; 3141 3014 } 3142 3015 3143 - bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, 3016 + bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info, 3144 3017 const struct ieee80211_vht_operation *oper, 3145 3018 const struct ieee80211_ht_operation *htop, 3146 3019 struct cfg80211_chan_def *chandef) ··· 3152 3025 u32 vht_cap; 3153 3026 bool support_80_80 = false; 3154 3027 bool support_160 = false; 3028 + u8 ext_nss_bw_supp = u32_get_bits(vht_cap_info, 3029 + IEEE80211_VHT_CAP_EXT_NSS_BW_MASK); 3030 + u8 supp_chwidth = u32_get_bits(vht_cap_info, 3031 + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK); 3155 3032 3156 3033 if (!oper || !htop) 3157 3034 return false; ··· 3175 3044 IEEE80211_HT_OP_MODE_CCFS2_MASK) 3176 3045 >> IEEE80211_HT_OP_MODE_CCFS2_SHIFT; 3177 3046 3178 - /* when parsing (and we know how to) CCFS1 and CCFS2 are equivalent */ 3179 3047 ccf0 = ccfs0; 3180 - ccf1 = ccfs1; 3181 - if (!ccfs1 && ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW)) 3048 + 3049 + /* if not supported, parse as though we didn't understand it */ 3050 + if (!ieee80211_hw_check(hw, SUPPORTS_VHT_EXT_NSS_BW)) 3051 + ext_nss_bw_supp = 0; 3052 + 3053 + /* 3054 + * Cf. IEEE 802.11 Table 9-250 3055 + * 3056 + * We really just consider that because it's inefficient to connect 3057 + * at a higher bandwidth than we'll actually be able to use. 3058 + */ 3059 + switch ((supp_chwidth << 4) | ext_nss_bw_supp) { 3060 + default: 3061 + case 0x00: 3062 + ccf1 = 0; 3063 + support_160 = false; 3064 + support_80_80 = false; 3065 + break; 3066 + case 0x01: 3067 + support_80_80 = false; 3068 + /* fall through */ 3069 + case 0x02: 3070 + case 0x03: 3182 3071 ccf1 = ccfs2; 3072 + break; 3073 + case 0x10: 3074 + ccf1 = ccfs1; 3075 + break; 3076 + case 0x11: 3077 + case 0x12: 3078 + if (!ccfs1) 3079 + ccf1 = ccfs2; 3080 + else 3081 + ccf1 = ccfs1; 3082 + break; 3083 + case 0x13: 3084 + case 0x20: 3085 + case 0x23: 3086 + ccf1 = ccfs1; 3087 + break; 3088 + } 3183 3089 3184 3090 cf0 = ieee80211_channel_to_frequency(ccf0, chandef->chan->band); 3185 3091 cf1 = ieee80211_channel_to_frequency(ccf1, chandef->chan->band); ··· 3261 3093 return false; 3262 3094 3263 3095 *chandef = new; 3096 + return true; 3097 + } 3098 + 3099 + bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata, 3100 + const struct ieee80211_he_operation *he_oper, 3101 + struct cfg80211_chan_def *chandef) 3102 + { 3103 + struct ieee80211_local *local = sdata->local; 3104 + struct ieee80211_supported_band *sband; 3105 + enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif); 3106 + const struct ieee80211_sta_he_cap *he_cap; 3107 + struct cfg80211_chan_def he_chandef = *chandef; 3108 + const struct ieee80211_he_6ghz_oper *he_6ghz_oper; 3109 + bool support_80_80, support_160; 3110 + u8 he_phy_cap; 3111 + u32 freq; 3112 + 3113 + if (chandef->chan->band != NL80211_BAND_6GHZ) 3114 + return true; 3115 + 3116 + sband = local->hw.wiphy->bands[NL80211_BAND_6GHZ]; 3117 + 3118 + he_cap = ieee80211_get_he_iftype_cap(sband, iftype); 3119 + if (!he_cap) { 3120 + sdata_info(sdata, "Missing iftype sband data/HE cap"); 3121 + return false; 3122 + } 3123 + 3124 + he_phy_cap = he_cap->he_cap_elem.phy_cap_info[0]; 3125 + support_160 = 3126 + he_phy_cap & 3127 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 3128 + support_80_80 = 3129 + he_phy_cap & 3130 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; 3131 + 3132 + if (!he_oper) { 3133 + sdata_info(sdata, 3134 + "HE is not advertised on (on %d MHz), expect issues\n", 3135 + chandef->chan->center_freq); 3136 + return false; 3137 + } 3138 + 3139 + he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper); 3140 + 3141 + if (!he_6ghz_oper) { 3142 + sdata_info(sdata, 3143 + "HE 6GHz operation missing (on %d MHz), expect issues\n", 3144 + chandef->chan->center_freq); 3145 + return false; 3146 + } 3147 + 3148 + freq = ieee80211_channel_to_frequency(he_6ghz_oper->primary, 3149 + NL80211_BAND_6GHZ); 3150 + he_chandef.chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq); 3151 + 3152 + switch (u8_get_bits(he_6ghz_oper->control, 3153 + IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH)) { 3154 + case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ: 3155 + he_chandef.width = NL80211_CHAN_WIDTH_20; 3156 + break; 3157 + case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ: 3158 + he_chandef.width = NL80211_CHAN_WIDTH_40; 3159 + break; 3160 + case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ: 3161 + he_chandef.width = NL80211_CHAN_WIDTH_80; 3162 + break; 3163 + case IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ: 3164 + he_chandef.width = NL80211_CHAN_WIDTH_80; 3165 + if (!he_6ghz_oper->ccfs1) 3166 + break; 3167 + if (abs(he_6ghz_oper->ccfs1 - he_6ghz_oper->ccfs0) == 8) { 3168 + if (support_160) 3169 + he_chandef.width = NL80211_CHAN_WIDTH_160; 3170 + } else { 3171 + if (support_80_80) 3172 + he_chandef.width = NL80211_CHAN_WIDTH_80P80; 3173 + } 3174 + break; 3175 + } 3176 + 3177 + if (he_chandef.width == NL80211_CHAN_WIDTH_160) { 3178 + he_chandef.center_freq1 = 3179 + ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1, 3180 + NL80211_BAND_6GHZ); 3181 + } else { 3182 + he_chandef.center_freq1 = 3183 + ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0, 3184 + NL80211_BAND_6GHZ); 3185 + he_chandef.center_freq2 = 3186 + ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1, 3187 + NL80211_BAND_6GHZ); 3188 + } 3189 + 3190 + if (!cfg80211_chandef_valid(&he_chandef)) { 3191 + sdata_info(sdata, 3192 + "HE 6GHz operation resulted in invalid chandef: %d MHz/%d/%d MHz/%d MHz\n", 3193 + he_chandef.chan ? he_chandef.chan->center_freq : 0, 3194 + he_chandef.width, 3195 + he_chandef.center_freq1, 3196 + he_chandef.center_freq2); 3197 + return false; 3198 + } 3199 + 3200 + *chandef = he_chandef; 3201 + 3264 3202 return true; 3265 3203 } 3266 3204
+2 -2
net/wireless/Kconfig
··· 181 181 default y 182 182 help 183 183 You should enable this option unless you know for sure you have no 184 - need for it, for example when using internal regdb (above) or the 185 - database loaded as a firmware file. 184 + need for it, for example when using the regulatory database loaded as 185 + a firmware file. 186 186 187 187 If unsure, say Y. 188 188
+15 -7
net/wireless/chan.c
··· 6 6 * 7 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 8 8 * Copyright 2013-2014 Intel Mobile Communications GmbH 9 - * Copyright 2018 Intel Corporation 9 + * Copyright 2018-2020 Intel Corporation 10 10 */ 11 11 12 12 #include <linux/export.h> ··· 919 919 width = 10; 920 920 break; 921 921 case NL80211_CHAN_WIDTH_20: 922 - if (!ht_cap->ht_supported) 922 + if (!ht_cap->ht_supported && 923 + chandef->chan->band != NL80211_BAND_6GHZ) 923 924 return false; 924 925 /* fall through */ 925 926 case NL80211_CHAN_WIDTH_20_NOHT: ··· 929 928 break; 930 929 case NL80211_CHAN_WIDTH_40: 931 930 width = 40; 931 + if (chandef->chan->band == NL80211_BAND_6GHZ) 932 + break; 932 933 if (!ht_cap->ht_supported) 933 934 return false; 934 935 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || ··· 945 942 break; 946 943 case NL80211_CHAN_WIDTH_80P80: 947 944 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; 948 - if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) 945 + if (chandef->chan->band != NL80211_BAND_6GHZ && 946 + cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) 949 947 return false; 950 948 /* fall through */ 951 949 case NL80211_CHAN_WIDTH_80: 952 - if (!vht_cap->vht_supported) 953 - return false; 954 950 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ; 955 951 width = 80; 952 + if (chandef->chan->band == NL80211_BAND_6GHZ) 953 + break; 954 + if (!vht_cap->vht_supported) 955 + return false; 956 956 break; 957 957 case NL80211_CHAN_WIDTH_160: 958 + prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; 959 + width = 160; 960 + if (chandef->chan->band == NL80211_BAND_6GHZ) 961 + break; 958 962 if (!vht_cap->vht_supported) 959 963 return false; 960 964 cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; 961 965 if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && 962 966 cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) 963 967 return false; 964 - prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; 965 - width = 160; 966 968 break; 967 969 default: 968 970 WARN_ON_ONCE(1);
+16 -1
net/wireless/core.c
··· 5 5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 7 * Copyright 2015-2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018-2019 Intel Corporation 8 + * Copyright (C) 2018-2020 Intel Corporation 9 9 */ 10 10 11 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ··· 791 791 /* sanity check supported bands/channels */ 792 792 for (band = 0; band < NUM_NL80211_BANDS; band++) { 793 793 u16 types = 0; 794 + bool have_he = false; 794 795 795 796 sband = wiphy->bands[band]; 796 797 if (!sband) ··· 806 805 */ 807 806 if (WARN_ON(band != NL80211_BAND_60GHZ && 808 807 !sband->n_bitrates)) 808 + return -EINVAL; 809 + 810 + if (WARN_ON(band == NL80211_BAND_6GHZ && 811 + (sband->ht_cap.ht_supported || 812 + sband->vht_cap.vht_supported))) 809 813 return -EINVAL; 810 814 811 815 /* ··· 860 854 return -EINVAL; 861 855 862 856 types |= iftd->types_mask; 857 + 858 + if (i == 0) 859 + have_he = iftd->he_cap.has_he; 860 + else 861 + have_he = have_he && 862 + iftd->he_cap.has_he; 863 863 } 864 + 865 + if (WARN_ON(!have_he && band == NL80211_BAND_6GHZ)) 866 + return -EINVAL; 864 867 865 868 have_band = true; 866 869 }
+1 -1
net/wireless/core.h
··· 286 286 u32 rssi_hyst; 287 287 s32 last_rssi_event_value; 288 288 int n_rssi_thresholds; 289 - s32 rssi_thresholds[0]; 289 + s32 rssi_thresholds[]; 290 290 }; 291 291 292 292 void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev);
+3 -3
net/wireless/mlme.c
··· 729 729 return rdev_mgmt_tx(rdev, wdev, params, cookie); 730 730 } 731 731 732 - bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, 733 - const u8 *buf, size_t len, u32 flags) 732 + bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm, 733 + const u8 *buf, size_t len, u32 flags) 734 734 { 735 735 struct wiphy *wiphy = wdev->wiphy; 736 736 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ··· 785 785 trace_cfg80211_return_bool(result); 786 786 return result; 787 787 } 788 - EXPORT_SYMBOL(cfg80211_rx_mgmt); 788 + EXPORT_SYMBOL(cfg80211_rx_mgmt_khz); 789 789 790 790 void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev) 791 791 {
+229 -68
net/wireless/nl80211.c
··· 329 329 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG }, 330 330 }; 331 331 332 + static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { 333 + [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY, 334 + .len = NL80211_MAX_SUPP_RATES }, 335 + [NL80211_TXRATE_HT] = { .type = NLA_BINARY, 336 + .len = NL80211_MAX_SUPP_HT_RATES }, 337 + [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)), 338 + [NL80211_TXRATE_GI] = { .type = NLA_U8 }, 339 + }; 340 + 332 341 static const struct nla_policy 333 342 nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = { 334 343 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 }, ··· 352 343 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE), 353 344 [NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] = 354 345 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE), 346 + [NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] = 347 + NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE), 348 + [NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] = 349 + NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED), 350 + [NL80211_TID_CONFIG_ATTR_TX_RATE] = 351 + NLA_POLICY_NESTED(nl80211_txattr_policy), 355 352 }; 356 353 357 354 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { ··· 378 363 379 364 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 }, 380 365 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 }, 366 + [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999), 381 367 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 }, 382 368 383 369 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1), ··· 652 636 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1), 653 637 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100), 654 638 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG }, 639 + [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999), 640 + [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED }, 641 + [NL80211_ATTR_HE_6GHZ_CAPABILITY] = { 642 + .type = NLA_EXACT_LEN, 643 + .len = sizeof(struct ieee80211_he_6ghz_capa), 644 + }, 655 645 }; 656 646 657 647 /* policy for the key attributes */ ··· 730 708 /* policy for GTK rekey offload attributes */ 731 709 static const struct nla_policy 732 710 nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { 733 - [NL80211_REKEY_DATA_KEK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KEK_LEN), 734 - [NL80211_REKEY_DATA_KCK] = NLA_POLICY_EXACT_LEN_WARN(NL80211_KCK_LEN), 711 + [NL80211_REKEY_DATA_KEK] = { 712 + .type = NLA_BINARY, 713 + .len = NL80211_KEK_EXT_LEN 714 + }, 715 + [NL80211_REKEY_DATA_KCK] = { 716 + .type = NLA_BINARY, 717 + .len = NL80211_KCK_EXT_LEN 718 + }, 735 719 [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN_WARN(NL80211_REPLAY_CTR_LEN), 720 + [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 }, 736 721 }; 737 722 738 723 static const struct nla_policy ··· 929 900 930 901 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, 931 902 chan->center_freq)) 903 + goto nla_put_failure; 904 + 905 + if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset)) 932 906 goto nla_put_failure; 933 907 934 908 if ((chan->flags & IEEE80211_CHAN_DISABLED) && ··· 1339 1307 } 1340 1308 1341 1309 static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy, 1342 - struct nlattr *tb) 1310 + u32 freq) 1343 1311 { 1344 1312 struct ieee80211_channel *chan; 1345 1313 1346 - if (tb == NULL) 1347 - return NULL; 1348 - chan = ieee80211_get_channel(wiphy, nla_get_u32(tb)); 1314 + chan = ieee80211_get_channel_khz(wiphy, freq); 1349 1315 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) 1350 1316 return NULL; 1351 1317 return chan; ··· 1569 1539 1570 1540 static int 1571 1541 nl80211_send_iftype_data(struct sk_buff *msg, 1542 + const struct ieee80211_supported_band *sband, 1572 1543 const struct ieee80211_sband_iftype_data *iftdata) 1573 1544 { 1574 1545 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap; ··· 1592 1561 sizeof(he_cap->ppe_thres), he_cap->ppe_thres)) 1593 1562 return -ENOBUFS; 1594 1563 } 1564 + 1565 + if (sband->band == NL80211_BAND_6GHZ && 1566 + nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, 1567 + sizeof(iftdata->he_6ghz_capa), 1568 + &iftdata->he_6ghz_capa)) 1569 + return -ENOBUFS; 1595 1570 1596 1571 return 0; 1597 1572 } ··· 1647 1610 if (!iftdata) 1648 1611 return -ENOBUFS; 1649 1612 1650 - err = nl80211_send_iftype_data(msg, 1613 + err = nl80211_send_iftype_data(msg, sband, 1651 1614 &sband->iftype_data[i]); 1652 1615 if (err) 1653 1616 return err; ··· 2805 2768 if (!attrs[NL80211_ATTR_WIPHY_FREQ]) 2806 2769 return -EINVAL; 2807 2770 2808 - control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]); 2771 + control_freq = MHZ_TO_KHZ( 2772 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 2773 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]) 2774 + control_freq += 2775 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); 2809 2776 2810 2777 memset(chandef, 0, sizeof(*chandef)); 2811 - 2812 - chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq); 2778 + chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq); 2813 2779 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 2814 - chandef->center_freq1 = control_freq; 2780 + chandef->center_freq1 = KHZ_TO_MHZ(control_freq); 2781 + chandef->freq1_offset = control_freq % 1000; 2815 2782 chandef->center_freq2 = 0; 2816 2783 2817 2784 /* Primary channel not allowed */ ··· 2863 2822 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) { 2864 2823 chandef->width = 2865 2824 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]); 2866 - if (attrs[NL80211_ATTR_CENTER_FREQ1]) 2825 + if (attrs[NL80211_ATTR_CENTER_FREQ1]) { 2867 2826 chandef->center_freq1 = 2868 2827 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]); 2828 + if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]) 2829 + chandef->freq1_offset = nla_get_u32( 2830 + attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]); 2831 + else 2832 + chandef->freq1_offset = 0; 2833 + } 2869 2834 if (attrs[NL80211_ATTR_CENTER_FREQ2]) 2870 2835 chandef->center_freq2 = 2871 2836 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]); ··· 3303 3256 3304 3257 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 3305 3258 chandef->chan->center_freq)) 3259 + return -ENOBUFS; 3260 + if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, 3261 + chandef->chan->freq_offset)) 3306 3262 return -ENOBUFS; 3307 3263 switch (chandef->width) { 3308 3264 case NL80211_CHAN_WIDTH_20_NOHT: ··· 4419 4369 return true; 4420 4370 } 4421 4371 4422 - static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { 4423 - [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY, 4424 - .len = NL80211_MAX_SUPP_RATES }, 4425 - [NL80211_TXRATE_HT] = { .type = NLA_BINARY, 4426 - .len = NL80211_MAX_SUPP_HT_RATES }, 4427 - [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)), 4428 - [NL80211_TXRATE_GI] = { .type = NLA_U8 }, 4429 - }; 4430 - 4431 4372 static int nl80211_parse_tx_bitrate_mask(struct genl_info *info, 4373 + struct nlattr *attrs[], 4374 + enum nl80211_attrs attr, 4432 4375 struct cfg80211_bitrate_mask *mask) 4433 4376 { 4434 4377 struct nlattr *tb[NL80211_TXRATE_MAX + 1]; ··· 4452 4409 } 4453 4410 4454 4411 /* if no rates are given set it back to the defaults */ 4455 - if (!info->attrs[NL80211_ATTR_TX_RATES]) 4412 + if (!attrs[attr]) 4456 4413 goto out; 4457 4414 4458 4415 /* The nested attribute uses enum nl80211_band as the index. This maps 4459 4416 * directly to the enum nl80211_band values used in cfg80211. 4460 4417 */ 4461 4418 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); 4462 - nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) { 4419 + nla_for_each_nested(tx_rates, attrs[attr], rem) { 4463 4420 enum nl80211_band band = nla_type(tx_rates); 4464 4421 int err; 4465 4422 ··· 4964 4921 return -EINVAL; 4965 4922 4966 4923 if (info->attrs[NL80211_ATTR_TX_RATES]) { 4967 - err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate); 4924 + err = nl80211_parse_tx_bitrate_mask(info, info->attrs, 4925 + NL80211_ATTR_TX_RATES, 4926 + &params.beacon_rate); 4968 4927 if (err) 4969 4928 return err; 4970 4929 ··· 6007 5962 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]); 6008 5963 } 6009 5964 5965 + if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]) 5966 + params.he_6ghz_capa = 5967 + nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]); 5968 + 6010 5969 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) 6011 5970 params.airtime_weight = 6012 5971 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]); ··· 6145 6096 return -EINVAL; 6146 6097 } 6147 6098 6099 + if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]) 6100 + params.he_6ghz_capa = 6101 + nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]); 6102 + 6148 6103 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) { 6149 6104 params.opmode_notif_used = true; 6150 6105 params.opmode_notif = ··· 6193 6140 params.vht_capa = NULL; 6194 6141 6195 6142 /* HE requires WME */ 6196 - if (params.he_capa_len) 6143 + if (params.he_capa_len || params.he_6ghz_capa) 6197 6144 return -EINVAL; 6198 6145 } 6146 + 6147 + /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */ 6148 + if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa)) 6149 + return -EINVAL; 6199 6150 6200 6151 /* When you run into this, adjust the code below for the new flag */ 6201 6152 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); ··· 7758 7701 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7759 7702 struct wireless_dev *wdev = info->user_ptr[1]; 7760 7703 struct cfg80211_scan_request *request; 7704 + struct nlattr *scan_freqs = NULL; 7705 + bool scan_freqs_khz = false; 7761 7706 struct nlattr *attr; 7762 7707 struct wiphy *wiphy; 7763 7708 int err, tmp, n_ssids = 0, n_channels, i; ··· 7778 7719 goto unlock; 7779 7720 } 7780 7721 7781 - if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 7782 - n_channels = validate_scan_freqs( 7783 - info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); 7722 + if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) { 7723 + if (!wiphy_ext_feature_isset(wiphy, 7724 + NL80211_EXT_FEATURE_SCAN_FREQ_KHZ)) 7725 + return -EOPNOTSUPP; 7726 + scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]; 7727 + scan_freqs_khz = true; 7728 + } else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) 7729 + scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]; 7730 + 7731 + if (scan_freqs) { 7732 + n_channels = validate_scan_freqs(scan_freqs); 7784 7733 if (!n_channels) { 7785 7734 err = -EINVAL; 7786 7735 goto unlock; ··· 7836 7769 } 7837 7770 7838 7771 i = 0; 7839 - if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 7772 + if (scan_freqs) { 7840 7773 /* user specified, bail out if channel not found */ 7841 - nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { 7774 + nla_for_each_nested(attr, scan_freqs, tmp) { 7842 7775 struct ieee80211_channel *chan; 7776 + int freq = nla_get_u32(attr); 7843 7777 7844 - chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); 7778 + if (!scan_freqs_khz) 7779 + freq = MHZ_TO_KHZ(freq); 7845 7780 7781 + chan = ieee80211_get_channel_khz(wiphy, freq); 7846 7782 if (!chan) { 7847 7783 err = -EINVAL; 7848 7784 goto out_free; ··· 8941 8871 goto nla_put_failure; 8942 8872 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) || 8943 8873 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) || 8874 + nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET, 8875 + res->channel->freq_offset) || 8944 8876 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) || 8945 8877 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, 8946 8878 jiffies_to_msecs(jiffies - intbss->ts))) ··· 9211 9139 enum nl80211_auth_type auth_type; 9212 9140 struct key_parse key; 9213 9141 bool local_state_change; 9142 + u32 freq; 9214 9143 9215 9144 if (!info->attrs[NL80211_ATTR_MAC]) 9216 9145 return -EINVAL; ··· 9268 9195 return -EOPNOTSUPP; 9269 9196 9270 9197 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 9271 - chan = nl80211_get_valid_chan(&rdev->wiphy, 9272 - info->attrs[NL80211_ATTR_WIPHY_FREQ]); 9198 + freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 9199 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]) 9200 + freq += 9201 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); 9202 + 9203 + chan = nl80211_get_valid_chan(&rdev->wiphy, freq); 9273 9204 if (!chan) 9274 9205 return -EINVAL; 9275 9206 ··· 9463 9386 struct cfg80211_assoc_request req = {}; 9464 9387 const u8 *bssid, *ssid; 9465 9388 int err, ssid_len = 0; 9389 + u32 freq; 9466 9390 9467 9391 if (dev->ieee80211_ptr->conn_owner_nlportid && 9468 9392 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid) ··· 9483 9405 9484 9406 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 9485 9407 9486 - chan = nl80211_get_valid_chan(&rdev->wiphy, 9487 - info->attrs[NL80211_ATTR_WIPHY_FREQ]); 9408 + freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); 9409 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]) 9410 + freq += 9411 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); 9412 + chan = nl80211_get_valid_chan(&rdev->wiphy, freq); 9488 9413 if (!chan) 9489 9414 return -EINVAL; 9490 9415 ··· 10167 10086 struct cfg80211_connect_params connect; 10168 10087 struct wiphy *wiphy; 10169 10088 struct cfg80211_cached_keys *connkeys = NULL; 10089 + u32 freq = 0; 10170 10090 int err; 10171 10091 10172 10092 memset(&connect, 0, sizeof(connect)); ··· 10238 10156 connect.prev_bssid = 10239 10157 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); 10240 10158 10241 - if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 10242 - connect.channel = nl80211_get_valid_chan( 10243 - wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]); 10159 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) 10160 + freq = MHZ_TO_KHZ(nla_get_u32( 10161 + info->attrs[NL80211_ATTR_WIPHY_FREQ])); 10162 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]) 10163 + freq += 10164 + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]); 10165 + 10166 + if (freq) { 10167 + connect.channel = nl80211_get_valid_chan(wiphy, freq); 10244 10168 if (!connect.channel) 10245 10169 return -EINVAL; 10246 10170 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) { 10247 - connect.channel_hint = nl80211_get_valid_chan( 10248 - wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]); 10171 + freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]); 10172 + freq = MHZ_TO_KHZ(freq); 10173 + connect.channel_hint = nl80211_get_valid_chan(wiphy, freq); 10249 10174 if (!connect.channel_hint) 10250 10175 return -EINVAL; 10251 10176 } ··· 10791 10702 if (!rdev->ops->set_bitrate_mask) 10792 10703 return -EOPNOTSUPP; 10793 10704 10794 - err = nl80211_parse_tx_bitrate_mask(info, &mask); 10705 + err = nl80211_parse_tx_bitrate_mask(info, info->attrs, 10706 + NL80211_ATTR_TX_RATES, &mask); 10795 10707 if (err) 10796 10708 return err; 10797 10709 ··· 11398 11308 } 11399 11309 11400 11310 if (info->attrs[NL80211_ATTR_TX_RATES]) { 11401 - err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate); 11311 + err = nl80211_parse_tx_bitrate_mask(info, info->attrs, 11312 + NL80211_ATTR_TX_RATES, 11313 + &setup.beacon_rate); 11402 11314 if (err) 11403 11315 return err; 11404 11316 ··· 12354 12262 return -EINVAL; 12355 12263 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN) 12356 12264 return -ERANGE; 12357 - if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN) 12265 + if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN && 12266 + !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK && 12267 + nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN)) 12358 12268 return -ERANGE; 12359 - if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) 12269 + if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN && 12270 + !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK && 12271 + nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN)) 12360 12272 return -ERANGE; 12361 12273 12362 12274 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]); 12363 12275 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]); 12364 12276 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]); 12277 + rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]); 12278 + rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]); 12279 + if (tb[NL80211_REKEY_DATA_AKM]) 12280 + rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]); 12365 12281 12366 12282 wdev_lock(wdev); 12367 12283 if (!wdev->current_bss) { ··· 13915 13815 13916 13816 static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info) 13917 13817 { 13818 + bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 13918 13819 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 13919 13820 struct net_device *dev = info->user_ptr[1]; 13920 13821 struct wireless_dev *wdev = dev->ieee80211_ptr; ··· 13924 13823 u8 *dest; 13925 13824 u16 proto; 13926 13825 bool noencrypt; 13826 + u64 cookie = 0; 13927 13827 int err; 13928 13828 13929 13829 if (!wiphy_ext_feature_isset(&rdev->wiphy, ··· 13969 13867 noencrypt = 13970 13868 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]); 13971 13869 13972 - return rdev_tx_control_port(rdev, dev, buf, len, 13973 - dest, cpu_to_be16(proto), noencrypt); 13974 - 13870 + err = rdev_tx_control_port(rdev, dev, buf, len, 13871 + dest, cpu_to_be16(proto), noencrypt, 13872 + dont_wait_for_ack ? NULL : &cookie); 13873 + if (!err && !dont_wait_for_ack) 13874 + nl_set_extack_cookie_u64(info->extack, cookie); 13875 + return err; 13975 13876 out: 13976 13877 wdev_unlock(wdev); 13977 13878 return err; ··· 14139 14034 if (rdev->ops->reset_tid_config) { 14140 14035 err = rdev_reset_tid_config(rdev, dev, peer, 14141 14036 tid_conf->tids); 14142 - /* If peer is there no other configuration will be 14143 - * allowed 14144 - */ 14145 - if (err || peer) 14037 + if (err) 14146 14038 return err; 14147 14039 } else { 14148 14040 return -EINVAL; ··· 14180 14078 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL); 14181 14079 tid_conf->rtscts = 14182 14080 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]); 14081 + } 14082 + 14083 + if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) { 14084 + tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL); 14085 + tid_conf->amsdu = 14086 + nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]); 14087 + } 14088 + 14089 + if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) { 14090 + u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr; 14091 + 14092 + tid_conf->txrate_type = nla_get_u8(attrs[idx]); 14093 + 14094 + if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) { 14095 + attr = NL80211_TID_CONFIG_ATTR_TX_RATE; 14096 + err = nl80211_parse_tx_bitrate_mask(info, attrs, attr, 14097 + &tid_conf->txrate_mask); 14098 + if (err) 14099 + return err; 14100 + 14101 + tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE); 14102 + } 14103 + tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE); 14183 14104 } 14184 14105 14185 14106 if (peer) ··· 15316 15191 } 15317 15192 nla_nest_end(msg, nest); 15318 15193 15319 - nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES); 15320 - if (!nest) 15321 - goto nla_put_failure; 15322 - for (i = 0; i < req->n_channels; i++) { 15323 - if (nla_put_u32(msg, i, req->channels[i]->center_freq)) 15194 + if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) { 15195 + nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ); 15196 + if (!nest) 15324 15197 goto nla_put_failure; 15198 + for (i = 0; i < req->n_channels; i++) { 15199 + if (nla_put_u32(msg, i, 15200 + ieee80211_channel_to_khz(req->channels[i]))) 15201 + goto nla_put_failure; 15202 + } 15203 + nla_nest_end(msg, nest); 15204 + } else { 15205 + nest = nla_nest_start_noflag(msg, 15206 + NL80211_ATTR_SCAN_FREQUENCIES); 15207 + if (!nest) 15208 + goto nla_put_failure; 15209 + for (i = 0; i < req->n_channels; i++) { 15210 + if (nla_put_u32(msg, i, req->channels[i]->center_freq)) 15211 + goto nla_put_failure; 15212 + } 15213 + nla_nest_end(msg, nest); 15325 15214 } 15326 - nla_nest_end(msg, nest); 15327 15215 15328 15216 if (req->ie && 15329 15217 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) ··· 16347 16209 netdev->ifindex)) || 16348 16210 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), 16349 16211 NL80211_ATTR_PAD) || 16350 - nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || 16212 + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) || 16213 + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) || 16351 16214 (sig_dbm && 16352 16215 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || 16353 16216 nla_put(msg, NL80211_ATTR_FRAME, len, buf) || ··· 16365 16226 return -ENOBUFS; 16366 16227 } 16367 16228 16368 - void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, 16369 - const u8 *buf, size_t len, bool ack, gfp_t gfp) 16229 + static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie, 16230 + const u8 *buf, size_t len, bool ack, 16231 + gfp_t gfp, enum nl80211_commands command) 16370 16232 { 16371 16233 struct wiphy *wiphy = wdev->wiphy; 16372 16234 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ··· 16375 16235 struct sk_buff *msg; 16376 16236 void *hdr; 16377 16237 16378 - trace_cfg80211_mgmt_tx_status(wdev, cookie, ack); 16238 + if (command == NL80211_CMD_FRAME_TX_STATUS) 16239 + trace_cfg80211_mgmt_tx_status(wdev, cookie, ack); 16240 + else 16241 + trace_cfg80211_control_port_tx_status(wdev, cookie, ack); 16379 16242 16380 16243 msg = nlmsg_new(100 + len, gfp); 16381 16244 if (!msg) 16382 16245 return; 16383 16246 16384 - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS); 16247 + hdr = nl80211hdr_put(msg, 0, 0, 0, command); 16385 16248 if (!hdr) { 16386 16249 nlmsg_free(msg); 16387 16250 return; ··· 16407 16264 NL80211_MCGRP_MLME, gfp); 16408 16265 return; 16409 16266 16410 - nla_put_failure: 16267 + nla_put_failure: 16411 16268 nlmsg_free(msg); 16269 + } 16270 + 16271 + void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie, 16272 + const u8 *buf, size_t len, bool ack, 16273 + gfp_t gfp) 16274 + { 16275 + nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp, 16276 + NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS); 16277 + } 16278 + EXPORT_SYMBOL(cfg80211_control_port_tx_status); 16279 + 16280 + void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, 16281 + const u8 *buf, size_t len, bool ack, gfp_t gfp) 16282 + { 16283 + nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp, 16284 + NL80211_CMD_FRAME_TX_STATUS); 16412 16285 } 16413 16286 EXPORT_SYMBOL(cfg80211_mgmt_tx_status); 16414 16287 ··· 16994 16835 } 16995 16836 EXPORT_SYMBOL(cfg80211_probe_status); 16996 16837 16997 - void cfg80211_report_obss_beacon(struct wiphy *wiphy, 16998 - const u8 *frame, size_t len, 16999 - int freq, int sig_dbm) 16838 + void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame, 16839 + size_t len, int freq, int sig_dbm) 17000 16840 { 17001 16841 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 17002 16842 struct sk_buff *msg; ··· 17018 16860 17019 16861 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 17020 16862 (freq && 17021 - nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || 16863 + (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 16864 + KHZ_TO_MHZ(freq)) || 16865 + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, 16866 + freq % 1000))) || 17022 16867 (sig_dbm && 17023 16868 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || 17024 16869 nla_put(msg, NL80211_ATTR_FRAME, len, frame)) ··· 17038 16877 spin_unlock_bh(&rdev->beacon_registrations_lock); 17039 16878 nlmsg_free(msg); 17040 16879 } 17041 - EXPORT_SYMBOL(cfg80211_report_obss_beacon); 16880 + EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz); 17042 16881 17043 16882 #ifdef CONFIG_PM 17044 16883 static int cfg80211_net_detect_results(struct sk_buff *msg,
+6 -3
net/wireless/rdev-ops.h
··· 748 748 struct net_device *dev, 749 749 const void *buf, size_t len, 750 750 const u8 *dest, __be16 proto, 751 - const bool noencrypt) 751 + const bool noencrypt, u64 *cookie) 752 752 { 753 753 int ret; 754 754 trace_rdev_tx_control_port(&rdev->wiphy, dev, buf, len, 755 755 dest, proto, noencrypt); 756 756 ret = rdev->ops->tx_control_port(&rdev->wiphy, dev, buf, len, 757 - dest, proto, noencrypt); 758 - trace_rdev_return_int(&rdev->wiphy, ret); 757 + dest, proto, noencrypt, cookie); 758 + if (cookie) 759 + trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 760 + else 761 + trace_rdev_return_int(&rdev->wiphy, ret); 759 762 return ret; 760 763 } 761 764
+5 -2
net/wireless/sme.c
··· 5 5 * (for nl80211's connect() and wext) 6 6 * 7 7 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 8 - * Copyright (C) 2009 Intel Corporation. All rights reserved. 8 + * Copyright (C) 2009, 2020 Intel Corporation. All rights reserved. 9 9 * Copyright 2017 Intel Deutschland GmbH 10 10 */ 11 11 ··· 1118 1118 1119 1119 if (wiphy_ext_feature_isset( 1120 1120 wdev->wiphy, 1121 - NL80211_EXT_FEATURE_BEACON_PROTECTION)) 1121 + NL80211_EXT_FEATURE_BEACON_PROTECTION) || 1122 + wiphy_ext_feature_isset( 1123 + wdev->wiphy, 1124 + NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) 1122 1125 max_key_idx = 7; 1123 1126 for (i = 0; i <= max_key_idx; i++) 1124 1127 rdev_del_key(rdev, dev, i, false, NULL);
+21 -4
net/wireless/trace.h
··· 2840 2840 __entry->freq = freq; 2841 2841 __entry->sig_dbm = sig_dbm; 2842 2842 ), 2843 - TP_printk(WDEV_PR_FMT ", freq: %d, sig dbm: %d", 2844 - WDEV_PR_ARG, __entry->freq, __entry->sig_dbm) 2843 + TP_printk(WDEV_PR_FMT ", freq: "KHZ_F", sig dbm: %d", 2844 + WDEV_PR_ARG, PR_KHZ(__entry->freq), __entry->sig_dbm) 2845 2845 ); 2846 2846 2847 2847 TRACE_EVENT(cfg80211_mgmt_tx_status, 2848 + TP_PROTO(struct wireless_dev *wdev, u64 cookie, bool ack), 2849 + TP_ARGS(wdev, cookie, ack), 2850 + TP_STRUCT__entry( 2851 + WDEV_ENTRY 2852 + __field(u64, cookie) 2853 + __field(bool, ack) 2854 + ), 2855 + TP_fast_assign( 2856 + WDEV_ASSIGN; 2857 + __entry->cookie = cookie; 2858 + __entry->ack = ack; 2859 + ), 2860 + TP_printk(WDEV_PR_FMT", cookie: %llu, ack: %s", 2861 + WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack)) 2862 + ); 2863 + 2864 + TRACE_EVENT(cfg80211_control_port_tx_status, 2848 2865 TP_PROTO(struct wireless_dev *wdev, u64 cookie, bool ack), 2849 2866 TP_ARGS(wdev, cookie, ack), 2850 2867 TP_STRUCT__entry( ··· 3138 3121 __entry->freq = freq; 3139 3122 __entry->sig_dbm = sig_dbm; 3140 3123 ), 3141 - TP_printk(WIPHY_PR_FMT ", freq: %d, sig_dbm: %d", 3142 - WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm) 3124 + TP_printk(WIPHY_PR_FMT ", freq: "KHZ_F", sig_dbm: %d", 3125 + WIPHY_PR_ARG, PR_KHZ(__entry->freq), __entry->sig_dbm) 3143 3126 ); 3144 3127 3145 3128 TRACE_EVENT(cfg80211_tdls_oper_request,
+7 -3
net/wireless/util.c
··· 92 92 return MHZ_TO_KHZ(5000 + chan * 5); 93 93 break; 94 94 case NL80211_BAND_6GHZ: 95 - /* see 802.11ax D4.1 27.3.22.2 */ 95 + /* see 802.11ax D6.1 27.3.23.2 */ 96 + if (chan == 2) 97 + return MHZ_TO_KHZ(5935); 96 98 if (chan <= 253) 97 - return 5940 + chan * 5; 99 + return MHZ_TO_KHZ(5950 + chan * 5); 98 100 break; 99 101 case NL80211_BAND_60GHZ: 100 102 if (chan < 7) ··· 242 240 int max_key_idx = 5; 243 241 244 242 if (wiphy_ext_feature_isset(&rdev->wiphy, 245 - NL80211_EXT_FEATURE_BEACON_PROTECTION)) 243 + NL80211_EXT_FEATURE_BEACON_PROTECTION) || 244 + wiphy_ext_feature_isset(&rdev->wiphy, 245 + NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) 246 246 max_key_idx = 7; 247 247 if (key_idx < 0 || key_idx > max_key_idx) 248 248 return -EINVAL;