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

Merge tag 'mac80211-next-for-net-next-2021-08-20' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Minor updates:
* BSS coloring support
* MEI commands for Intel platforms
* various fixes/cleanups

* tag 'mac80211-next-for-net-next-2021-08-20' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next:
cfg80211: fix BSS color notify trace enum confusion
mac80211: Fix insufficient headroom issue for AMSDU
mac80211: add support for BSS color change
nl80211: add support for BSS coloring
mac80211: Use flex-array for radiotap header bitmap
mac80211: radiotap: Use BIT() instead of shifts
mac80211: Remove unnecessary variable and label
mac80211: include <linux/rbtree.h>
mac80211: Fix monitor MTU limit so that A-MSDUs get through
mac80211: remove unnecessary NULL check in ieee80211_register_hw()
mac80211: Reject zero MAC address in sta_info_insert_check()
nl80211: vendor-cmd: add Intel vendor commands for iwlmei usage
====================

Link: https://lore.kernel.org/r/20210820105329.48674-1-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+764 -63
+92
include/net/cfg80211.h
··· 1253 1253 }; 1254 1254 1255 1255 /** 1256 + * struct cfg80211_color_change_settings - color change settings 1257 + * 1258 + * Used for bss color change 1259 + * 1260 + * @beacon_color_change: beacon data while performing the color countdown 1261 + * @counter_offsets_beacon: offsets of the counters within the beacon (tail) 1262 + * @counter_offsets_presp: offsets of the counters within the probe response 1263 + * @beacon_next: beacon data to be used after the color change 1264 + * @count: number of beacons until the color change 1265 + * @color: the color used after the change 1266 + */ 1267 + struct cfg80211_color_change_settings { 1268 + struct cfg80211_beacon_data beacon_color_change; 1269 + u16 counter_offset_beacon; 1270 + u16 counter_offset_presp; 1271 + struct cfg80211_beacon_data beacon_next; 1272 + u8 count; 1273 + u8 color; 1274 + }; 1275 + 1276 + /** 1256 1277 * struct iface_combination_params - input parameters for interface combinations 1257 1278 * 1258 1279 * Used to pass interface combination parameters ··· 4016 3995 * given TIDs. This callback may sleep. 4017 3996 * 4018 3997 * @set_sar_specs: Update the SAR (TX power) settings. 3998 + * 3999 + * @color_change: Initiate a color change. 4019 4000 */ 4020 4001 struct cfg80211_ops { 4021 4002 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ··· 4345 4322 const u8 *peer, u8 tids); 4346 4323 int (*set_sar_specs)(struct wiphy *wiphy, 4347 4324 struct cfg80211_sar_specs *sar); 4325 + int (*color_change)(struct wiphy *wiphy, 4326 + struct net_device *dev, 4327 + struct cfg80211_color_change_settings *params); 4348 4328 }; 4349 4329 4350 4330 /* ··· 8243 8217 * @wiphy: the wiphy 8244 8218 */ 8245 8219 void cfg80211_bss_flush(struct wiphy *wiphy); 8220 + 8221 + /** 8222 + * cfg80211_bss_color_notify - notify about bss color event 8223 + * @dev: network device 8224 + * @gfp: allocation flags 8225 + * @cmd: the actual event we want to notify 8226 + * @count: the number of TBTTs until the color change happens 8227 + * @color_bitmap: representations of the colors that the local BSS is aware of 8228 + */ 8229 + int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, 8230 + enum nl80211_commands cmd, u8 count, 8231 + u64 color_bitmap); 8232 + 8233 + /** 8234 + * cfg80211_obss_color_collision_notify - notify about bss color collision 8235 + * @dev: network device 8236 + * @color_bitmap: representations of the colors that the local BSS is aware of 8237 + */ 8238 + static inline int cfg80211_obss_color_collision_notify(struct net_device *dev, 8239 + u64 color_bitmap) 8240 + { 8241 + return cfg80211_bss_color_notify(dev, GFP_KERNEL, 8242 + NL80211_CMD_OBSS_COLOR_COLLISION, 8243 + 0, color_bitmap); 8244 + } 8245 + 8246 + /** 8247 + * cfg80211_color_change_started_notify - notify color change start 8248 + * @dev: the device on which the color is switched 8249 + * @count: the number of TBTTs until the color change happens 8250 + * 8251 + * Inform the userspace about the color change that has started. 8252 + */ 8253 + static inline int cfg80211_color_change_started_notify(struct net_device *dev, 8254 + u8 count) 8255 + { 8256 + return cfg80211_bss_color_notify(dev, GFP_KERNEL, 8257 + NL80211_CMD_COLOR_CHANGE_STARTED, 8258 + count, 0); 8259 + } 8260 + 8261 + /** 8262 + * cfg80211_color_change_aborted_notify - notify color change abort 8263 + * @dev: the device on which the color is switched 8264 + * 8265 + * Inform the userspace about the color change that has aborted. 8266 + */ 8267 + static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) 8268 + { 8269 + return cfg80211_bss_color_notify(dev, GFP_KERNEL, 8270 + NL80211_CMD_COLOR_CHANGE_ABORTED, 8271 + 0, 0); 8272 + } 8273 + 8274 + /** 8275 + * cfg80211_color_change_notify - notify color change completion 8276 + * @dev: the device on which the color was switched 8277 + * 8278 + * Inform the userspace about the color change that has completed. 8279 + */ 8280 + static inline int cfg80211_color_change_notify(struct net_device *dev) 8281 + { 8282 + return cfg80211_bss_color_notify(dev, GFP_KERNEL, 8283 + NL80211_CMD_COLOR_CHANGE_COMPLETED, 8284 + 0, 0); 8285 + } 8246 8286 8247 8287 #endif /* __NET_CFG80211_H */
+5
include/net/ieee80211_radiotap.h
··· 43 43 * @it_present: (first) present word 44 44 */ 45 45 __le32 it_present; 46 + 47 + /** 48 + * @it_optional: all remaining presence bitmaps 49 + */ 50 + __le32 it_optional[]; 46 51 } __packed; 47 52 48 53 /* version is always 0 */
+29
include/net/mac80211.h
··· 1711 1711 * protected by fq->lock. 1712 1712 * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see 1713 1713 * &enum ieee80211_offload_flags. 1714 + * @color_change_active: marks whether a color change is ongoing. Internally it is 1715 + * write-protected by sdata_lock and local->mtx so holding either is fine 1716 + * for read access. 1717 + * @color_change_color: the bss color that will be used after the change. 1714 1718 */ 1715 1719 struct ieee80211_vif { 1716 1720 enum nl80211_iftype type; ··· 1742 1738 bool rx_mcast_action_reg; 1743 1739 1744 1740 bool txqs_stopped[IEEE80211_NUM_ACS]; 1741 + 1742 + bool color_change_active; 1743 + u8 color_change_color; 1745 1744 1746 1745 /* must be last */ 1747 1746 u8 drv_priv[] __aligned(sizeof(void *)); ··· 5015 5008 bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif); 5016 5009 5017 5010 /** 5011 + * ieee80211_color_change_finish - notify mac80211 about color change 5012 + * @vif: &struct ieee80211_vif pointer from the add_interface callback. 5013 + * 5014 + * After a color change announcement was scheduled and the counter in this 5015 + * announcement hits 1, this function must be called by the driver to 5016 + * notify mac80211 that the color can be changed 5017 + */ 5018 + void ieee80211_color_change_finish(struct ieee80211_vif *vif); 5019 + 5020 + /** 5018 5021 * ieee80211_proberesp_get - retrieve a Probe Response template 5019 5022 * @hw: pointer obtained from ieee80211_alloc_hw(). 5020 5023 * @vif: &struct ieee80211_vif pointer from the add_interface callback. ··· 6787 6770 struct sk_buff * 6788 6771 ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw, 6789 6772 struct ieee80211_vif *vif); 6773 + 6774 + /** 6775 + * ieeee80211_obss_color_collision_notify - notify userland about a BSS color 6776 + * collision. 6777 + * 6778 + * @vif: &struct ieee80211_vif pointer from the add_interface callback. 6779 + * @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is 6780 + * aware of. 6781 + */ 6782 + void 6783 + ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif, 6784 + u64 color_bitmap); 6790 6785 6791 6786 /** 6792 6787 * ieee80211_is_tx_data - check if frame is a data frame
+77
include/uapi/linux/nl80211-vnd-intel.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* 3 + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation 4 + * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 + * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 + */ 7 + #ifndef __VENDOR_CMD_INTEL_H__ 8 + #define __VENDOR_CMD_INTEL_H__ 9 + 10 + #define INTEL_OUI 0x001735 11 + 12 + /** 13 + * enum iwl_mvm_vendor_cmd - supported vendor commands 14 + * @IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO: reports CSME connection info. 15 + * @IWL_MVM_VENDOR_CMD_HOST_GET_OWNERSHIP: asks for ownership on the device. 16 + * @IWL_MVM_VENDOR_CMD_ROAMING_FORBIDDEN_EVENT: notifies if roaming is allowed. 17 + * It contains a &IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN and a 18 + * &IWL_MVM_VENDOR_ATTR_VIF_ADDR attributes. 19 + */ 20 + 21 + enum iwl_mvm_vendor_cmd { 22 + IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO = 0x2d, 23 + IWL_MVM_VENDOR_CMD_HOST_GET_OWNERSHIP = 0x30, 24 + IWL_MVM_VENDOR_CMD_ROAMING_FORBIDDEN_EVENT = 0x32, 25 + }; 26 + 27 + enum iwl_vendor_auth_akm_mode { 28 + IWL_VENDOR_AUTH_OPEN, 29 + IWL_VENDOR_AUTH_RSNA = 0x6, 30 + IWL_VENDOR_AUTH_RSNA_PSK, 31 + IWL_VENDOR_AUTH_SAE = 0x9, 32 + IWL_VENDOR_AUTH_MAX, 33 + }; 34 + 35 + /** 36 + * enum iwl_mvm_vendor_attr - attributes used in vendor commands 37 + * @__IWL_MVM_VENDOR_ATTR_INVALID: attribute 0 is invalid 38 + * @IWL_MVM_VENDOR_ATTR_VIF_ADDR: interface MAC address 39 + * @IWL_MVM_VENDOR_ATTR_ADDR: MAC address 40 + * @IWL_MVM_VENDOR_ATTR_SSID: SSID (binary attribute, 0..32 octets) 41 + * @IWL_MVM_VENDOR_ATTR_STA_CIPHER: the cipher to use for the station with the 42 + * mac address specified in &IWL_MVM_VENDOR_ATTR_ADDR. 43 + * @IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN: u8 attribute. Indicates whether 44 + * roaming is forbidden or not. Value 1 means roaming is forbidden, 45 + * 0 mean roaming is allowed. 46 + * @IWL_MVM_VENDOR_ATTR_AUTH_MODE: u32 attribute. Authentication mode type 47 + * as specified in &enum iwl_vendor_auth_akm_mode. 48 + * @IWL_MVM_VENDOR_ATTR_CHANNEL_NUM: u8 attribute. Contains channel number. 49 + * @IWL_MVM_VENDOR_ATTR_BAND: u8 attribute. 50 + * 0 for 2.4 GHz band, 1 for 5.2GHz band and 2 for 6GHz band. 51 + * @IWL_MVM_VENDOR_ATTR_COLLOC_CHANNEL: u32 attribute. Channel number of 52 + * collocated AP. Relevant for 6GHz AP info. 53 + * @IWL_MVM_VENDOR_ATTR_COLLOC_ADDR: MAC address of a collocated AP. 54 + * Relevant for 6GHz AP info. 55 + * 56 + * @NUM_IWL_MVM_VENDOR_ATTR: number of vendor attributes 57 + * @MAX_IWL_MVM_VENDOR_ATTR: highest vendor attribute number 58 + 59 + */ 60 + enum iwl_mvm_vendor_attr { 61 + __IWL_MVM_VENDOR_ATTR_INVALID = 0x00, 62 + IWL_MVM_VENDOR_ATTR_VIF_ADDR = 0x02, 63 + IWL_MVM_VENDOR_ATTR_ADDR = 0x0a, 64 + IWL_MVM_VENDOR_ATTR_SSID = 0x3d, 65 + IWL_MVM_VENDOR_ATTR_STA_CIPHER = 0x51, 66 + IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN = 0x64, 67 + IWL_MVM_VENDOR_ATTR_AUTH_MODE = 0x65, 68 + IWL_MVM_VENDOR_ATTR_CHANNEL_NUM = 0x66, 69 + IWL_MVM_VENDOR_ATTR_BAND = 0x69, 70 + IWL_MVM_VENDOR_ATTR_COLLOC_CHANNEL = 0x70, 71 + IWL_MVM_VENDOR_ATTR_COLLOC_ADDR = 0x71, 72 + 73 + NUM_IWL_MVM_VENDOR_ATTR, 74 + MAX_IWL_MVM_VENDOR_ATTR = NUM_IWL_MVM_VENDOR_ATTR - 1, 75 + }; 76 + 77 + #endif /* __VENDOR_CMD_INTEL_H__ */
+43
include/uapi/linux/nl80211.h
··· 1185 1185 * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to 1186 1186 * specify the wiphy index to be applied to. 1187 1187 * 1188 + * @NL80211_CMD_OBSS_COLOR_COLLISION: This notification is sent out whenever 1189 + * mac80211/drv detects a bss color collision. 1190 + * 1191 + * @NL80211_CMD_COLOR_CHANGE_REQUEST: This command is used to indicate that 1192 + * userspace wants to change the BSS color. 1193 + * 1194 + * @NL80211_CMD_COLOR_CHANGE_STARTED: Notify userland, that a color change has 1195 + * started 1196 + * 1197 + * @NL80211_CMD_COLOR_CHANGE_ABORTED: Notify userland, that the color change has 1198 + * been aborted 1199 + * 1200 + * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change 1201 + * has completed 1202 + * 1188 1203 * @NL80211_CMD_MAX: highest used command number 1189 1204 * @__NL80211_CMD_AFTER_LAST: internal use 1190 1205 */ ··· 1431 1416 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, 1432 1417 1433 1418 NL80211_CMD_SET_SAR_SPECS, 1419 + 1420 + NL80211_CMD_OBSS_COLOR_COLLISION, 1421 + 1422 + NL80211_CMD_COLOR_CHANGE_REQUEST, 1423 + 1424 + NL80211_CMD_COLOR_CHANGE_STARTED, 1425 + NL80211_CMD_COLOR_CHANGE_ABORTED, 1426 + NL80211_CMD_COLOR_CHANGE_COMPLETED, 1434 1427 1435 1428 /* add new commands above here */ 1436 1429 ··· 2583 2560 * disassoc events to indicate that an immediate reconnect to the AP 2584 2561 * is desired. 2585 2562 * 2563 + * @NL80211_ATTR_OBSS_COLOR_BITMAP: bitmap of the u64 BSS colors for the 2564 + * %NL80211_CMD_OBSS_COLOR_COLLISION event. 2565 + * 2566 + * @NL80211_ATTR_COLOR_CHANGE_COUNT: u8 attribute specifying the number of TBTT's 2567 + * until the color switch event. 2568 + * @NL80211_ATTR_COLOR_CHANGE_COLOR: u8 attribute specifying the color that we are 2569 + * switching to 2570 + * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE 2571 + * information for the time while performing a color switch. 2572 + * 2586 2573 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2587 2574 * @NL80211_ATTR_MAX: highest attribute number currently defined 2588 2575 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 3089 3056 NL80211_ATTR_SAR_SPEC, 3090 3057 3091 3058 NL80211_ATTR_DISABLE_HE, 3059 + 3060 + NL80211_ATTR_OBSS_COLOR_BITMAP, 3061 + 3062 + NL80211_ATTR_COLOR_CHANGE_COUNT, 3063 + NL80211_ATTR_COLOR_CHANGE_COLOR, 3064 + NL80211_ATTR_COLOR_CHANGE_ELEMS, 3092 3065 3093 3066 /* add attributes here, update the policy in nl80211.c */ 3094 3067 ··· 5992 5953 * frame protection for all management frames exchanged during the 5993 5954 * negotiation and range measurement procedure. 5994 5955 * 5956 + * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision 5957 + * detection and change announcemnts. 5958 + * 5995 5959 * @NUM_NL80211_EXT_FEATURES: number of extended features. 5996 5960 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 5997 5961 */ ··· 6059 6017 NL80211_EXT_FEATURE_SECURE_LTF, 6060 6018 NL80211_EXT_FEATURE_SECURE_RTT, 6061 6019 NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, 6020 + NL80211_EXT_FEATURE_BSS_COLOR, 6062 6021 6063 6022 /* add new features before the definition below */ 6064 6023 NUM_NL80211_EXT_FEATURES,
+223 -11
net/mac80211/cfg.c
··· 828 828 return ret; 829 829 } 830 830 831 - static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 832 - const u8 *resp, size_t resp_len, 833 - const struct ieee80211_csa_settings *csa) 831 + static int 832 + ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 833 + const u8 *resp, size_t resp_len, 834 + const struct ieee80211_csa_settings *csa, 835 + const struct ieee80211_color_change_settings *cca) 834 836 { 835 837 struct probe_resp *new, *old; 836 838 ··· 852 850 memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp, 853 851 csa->n_counter_offsets_presp * 854 852 sizeof(new->cntdwn_counter_offsets[0])); 853 + else if (cca) 854 + new->cntdwn_counter_offsets[0] = cca->counter_offset_presp; 855 855 856 856 rcu_assign_pointer(sdata->u.ap.probe_resp, new); 857 857 if (old) ··· 959 955 960 956 static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, 961 957 struct cfg80211_beacon_data *params, 962 - const struct ieee80211_csa_settings *csa) 958 + const struct ieee80211_csa_settings *csa, 959 + const struct ieee80211_color_change_settings *cca) 963 960 { 964 961 struct beacon_data *new, *old; 965 962 int new_head_len, new_tail_len; ··· 1009 1004 memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon, 1010 1005 csa->n_counter_offsets_beacon * 1011 1006 sizeof(new->cntdwn_counter_offsets[0])); 1007 + } else if (cca) { 1008 + new->cntdwn_current_counter = cca->count; 1009 + new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon; 1012 1010 } 1013 1011 1014 1012 /* copy in head */ ··· 1028 1020 memcpy(new->tail, old->tail, new_tail_len); 1029 1021 1030 1022 err = ieee80211_set_probe_resp(sdata, params->probe_resp, 1031 - params->probe_resp_len, csa); 1023 + params->probe_resp_len, csa, cca); 1032 1024 if (err < 0) { 1033 1025 kfree(new); 1034 1026 return err; ··· 1183 1175 if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) 1184 1176 sdata->vif.bss_conf.beacon_tx_rate = params->beacon_rate; 1185 1177 1186 - err = ieee80211_assign_beacon(sdata, &params->beacon, NULL); 1178 + err = ieee80211_assign_beacon(sdata, &params->beacon, NULL, NULL); 1187 1179 if (err < 0) 1188 1180 goto error; 1189 1181 changed |= err; ··· 1238 1230 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1239 1231 sdata_assert_lock(sdata); 1240 1232 1241 - /* don't allow changing the beacon while CSA is in place - offset 1233 + /* don't allow changing the beacon while a countdown is in place - offset 1242 1234 * of channel switch counter may change 1243 1235 */ 1244 - if (sdata->vif.csa_active) 1236 + if (sdata->vif.csa_active || sdata->vif.color_change_active) 1245 1237 return -EBUSY; 1246 1238 1247 1239 old = sdata_dereference(sdata->u.ap.beacon, sdata); 1248 1240 if (!old) 1249 1241 return -ENOENT; 1250 1242 1251 - err = ieee80211_assign_beacon(sdata, params, NULL); 1243 + err = ieee80211_assign_beacon(sdata, params, NULL, NULL); 1252 1244 if (err < 0) 1253 1245 return err; 1254 1246 ieee80211_bss_info_change_notify(sdata, err); ··· 3164 3156 switch (sdata->vif.type) { 3165 3157 case NL80211_IFTYPE_AP: 3166 3158 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, 3167 - NULL); 3159 + NULL, NULL); 3168 3160 kfree(sdata->u.ap.next_beacon); 3169 3161 sdata->u.ap.next_beacon = NULL; 3170 3162 ··· 3330 3322 csa.n_counter_offsets_presp = params->n_counter_offsets_presp; 3331 3323 csa.count = params->count; 3332 3324 3333 - err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa); 3325 + err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa, NULL); 3334 3326 if (err < 0) { 3335 3327 kfree(sdata->u.ap.next_beacon); 3336 3328 return err; ··· 3419 3411 return 0; 3420 3412 } 3421 3413 3414 + static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) 3415 + { 3416 + sdata->vif.color_change_active = false; 3417 + kfree(sdata->u.ap.next_beacon); 3418 + sdata->u.ap.next_beacon = NULL; 3419 + 3420 + cfg80211_color_change_aborted_notify(sdata->dev); 3421 + } 3422 + 3422 3423 static int 3423 3424 __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 3424 3425 struct cfg80211_csa_settings *params) ··· 3495 3478 ieee80211_vif_unreserve_chanctx(sdata); 3496 3479 goto out; 3497 3480 } 3481 + 3482 + /* if there is a color change in progress, abort it */ 3483 + if (sdata->vif.color_change_active) 3484 + ieee80211_color_change_abort(sdata); 3498 3485 3499 3486 err = ieee80211_set_csa_beacon(sdata, params, &changed); 3500 3487 if (err) { ··· 4151 4130 return local->ops->set_sar_specs(&local->hw, sar); 4152 4131 } 4153 4132 4133 + static int 4134 + ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata, 4135 + u32 *changed) 4136 + { 4137 + switch (sdata->vif.type) { 4138 + case NL80211_IFTYPE_AP: { 4139 + int ret; 4140 + 4141 + ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, 4142 + NULL, NULL); 4143 + kfree(sdata->u.ap.next_beacon); 4144 + sdata->u.ap.next_beacon = NULL; 4145 + 4146 + if (ret < 0) 4147 + return ret; 4148 + 4149 + *changed |= ret; 4150 + break; 4151 + } 4152 + default: 4153 + WARN_ON_ONCE(1); 4154 + return -EINVAL; 4155 + } 4156 + 4157 + return 0; 4158 + } 4159 + 4160 + static int 4161 + ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata, 4162 + struct cfg80211_color_change_settings *params, 4163 + u32 *changed) 4164 + { 4165 + struct ieee80211_color_change_settings color_change = {}; 4166 + int err; 4167 + 4168 + switch (sdata->vif.type) { 4169 + case NL80211_IFTYPE_AP: 4170 + sdata->u.ap.next_beacon = 4171 + cfg80211_beacon_dup(&params->beacon_next); 4172 + if (!sdata->u.ap.next_beacon) 4173 + return -ENOMEM; 4174 + 4175 + if (params->count <= 1) 4176 + break; 4177 + 4178 + color_change.counter_offset_beacon = 4179 + params->counter_offset_beacon; 4180 + color_change.counter_offset_presp = 4181 + params->counter_offset_presp; 4182 + color_change.count = params->count; 4183 + 4184 + err = ieee80211_assign_beacon(sdata, &params->beacon_color_change, 4185 + NULL, &color_change); 4186 + if (err < 0) { 4187 + kfree(sdata->u.ap.next_beacon); 4188 + return err; 4189 + } 4190 + *changed |= err; 4191 + break; 4192 + default: 4193 + return -EOPNOTSUPP; 4194 + } 4195 + 4196 + return 0; 4197 + } 4198 + 4199 + static void 4200 + ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata, 4201 + u8 color, int enable, u32 changed) 4202 + { 4203 + sdata->vif.bss_conf.he_bss_color.color = color; 4204 + sdata->vif.bss_conf.he_bss_color.enabled = enable; 4205 + changed |= BSS_CHANGED_HE_BSS_COLOR; 4206 + 4207 + ieee80211_bss_info_change_notify(sdata, changed); 4208 + } 4209 + 4210 + static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata) 4211 + { 4212 + struct ieee80211_local *local = sdata->local; 4213 + u32 changed = 0; 4214 + int err; 4215 + 4216 + sdata_assert_lock(sdata); 4217 + lockdep_assert_held(&local->mtx); 4218 + 4219 + sdata->vif.color_change_active = false; 4220 + 4221 + err = ieee80211_set_after_color_change_beacon(sdata, &changed); 4222 + if (err) { 4223 + cfg80211_color_change_aborted_notify(sdata->dev); 4224 + return err; 4225 + } 4226 + 4227 + ieee80211_color_change_bss_config_notify(sdata, 4228 + sdata->vif.color_change_color, 4229 + 1, changed); 4230 + cfg80211_color_change_notify(sdata->dev); 4231 + 4232 + return 0; 4233 + } 4234 + 4235 + void ieee80211_color_change_finalize_work(struct work_struct *work) 4236 + { 4237 + struct ieee80211_sub_if_data *sdata = 4238 + container_of(work, struct ieee80211_sub_if_data, 4239 + color_change_finalize_work); 4240 + struct ieee80211_local *local = sdata->local; 4241 + 4242 + sdata_lock(sdata); 4243 + mutex_lock(&local->mtx); 4244 + 4245 + /* AP might have been stopped while waiting for the lock. */ 4246 + if (!sdata->vif.color_change_active) 4247 + goto unlock; 4248 + 4249 + if (!ieee80211_sdata_running(sdata)) 4250 + goto unlock; 4251 + 4252 + ieee80211_color_change_finalize(sdata); 4253 + 4254 + unlock: 4255 + mutex_unlock(&local->mtx); 4256 + sdata_unlock(sdata); 4257 + } 4258 + 4259 + void ieee80211_color_change_finish(struct ieee80211_vif *vif) 4260 + { 4261 + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 4262 + 4263 + ieee80211_queue_work(&sdata->local->hw, 4264 + &sdata->color_change_finalize_work); 4265 + } 4266 + EXPORT_SYMBOL_GPL(ieee80211_color_change_finish); 4267 + 4268 + void 4269 + ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif, 4270 + u64 color_bitmap) 4271 + { 4272 + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 4273 + 4274 + if (sdata->vif.color_change_active || sdata->vif.csa_active) 4275 + return; 4276 + 4277 + cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap); 4278 + } 4279 + EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify); 4280 + 4281 + static int 4282 + ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev, 4283 + struct cfg80211_color_change_settings *params) 4284 + { 4285 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 4286 + struct ieee80211_local *local = sdata->local; 4287 + u32 changed = 0; 4288 + int err; 4289 + 4290 + sdata_assert_lock(sdata); 4291 + 4292 + mutex_lock(&local->mtx); 4293 + 4294 + /* don't allow another color change if one is already active or if csa 4295 + * is active 4296 + */ 4297 + if (sdata->vif.color_change_active || sdata->vif.csa_active) { 4298 + err = -EBUSY; 4299 + goto out; 4300 + } 4301 + 4302 + err = ieee80211_set_color_change_beacon(sdata, params, &changed); 4303 + if (err) 4304 + goto out; 4305 + 4306 + sdata->vif.color_change_active = true; 4307 + sdata->vif.color_change_color = params->color; 4308 + 4309 + cfg80211_color_change_started_notify(sdata->dev, params->count); 4310 + 4311 + if (changed) 4312 + ieee80211_color_change_bss_config_notify(sdata, 0, 0, changed); 4313 + else 4314 + /* if the beacon didn't change, we can finalize immediately */ 4315 + ieee80211_color_change_finalize(sdata); 4316 + 4317 + out: 4318 + mutex_unlock(&local->mtx); 4319 + 4320 + return err; 4321 + } 4322 + 4154 4323 const struct cfg80211_ops mac80211_config_ops = { 4155 4324 .add_virtual_intf = ieee80211_add_iface, 4156 4325 .del_virtual_intf = ieee80211_del_iface, ··· 4444 4233 .set_tid_config = ieee80211_set_tid_config, 4445 4234 .reset_tid_config = ieee80211_reset_tid_config, 4446 4235 .set_sar_specs = ieee80211_set_sar_specs, 4236 + .color_change = ieee80211_color_change, 4447 4237 };
+4 -11
net/mac80211/ibss.c
··· 489 489 const struct cfg80211_bss_ies *ies; 490 490 u16 capability = WLAN_CAPABILITY_IBSS; 491 491 u64 tsf; 492 - int ret = 0; 493 492 494 493 sdata_assert_lock(sdata); 495 494 ··· 500 501 ifibss->ssid_len, IEEE80211_BSS_TYPE_IBSS, 501 502 IEEE80211_PRIVACY(ifibss->privacy)); 502 503 503 - if (WARN_ON(!cbss)) { 504 - ret = -EINVAL; 505 - goto out; 506 - } 504 + if (WARN_ON(!cbss)) 505 + return -EINVAL; 507 506 508 507 rcu_read_lock(); 509 508 ies = rcu_dereference(cbss->ies); ··· 517 520 sdata->vif.bss_conf.basic_rates, 518 521 capability, tsf, &ifibss->chandef, 519 522 NULL, csa_settings); 520 - if (!presp) { 521 - ret = -ENOMEM; 522 - goto out; 523 - } 523 + if (!presp) 524 + return -ENOMEM; 524 525 525 526 rcu_assign_pointer(ifibss->presp, presp); 526 527 if (old_presp) 527 528 kfree_rcu(old_presp, rcu_head); 528 529 529 530 return BSS_CHANGED_BEACON; 530 - out: 531 - return ret; 532 531 } 533 532 534 533 int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
+12
net/mac80211/ieee80211_i.h
··· 25 25 #include <linux/leds.h> 26 26 #include <linux/idr.h> 27 27 #include <linux/rhashtable.h> 28 + #include <linux/rbtree.h> 28 29 #include <net/ieee80211_radiotap.h> 29 30 #include <net/cfg80211.h> 30 31 #include <net/mac80211.h> ··· 242 241 int n_counter_offsets_beacon; 243 242 int n_counter_offsets_presp; 244 243 244 + u8 count; 245 + }; 246 + 247 + struct ieee80211_color_change_settings { 248 + u16 counter_offset_beacon; 249 + u16 counter_offset_presp; 245 250 u8 count; 246 251 }; 247 252 ··· 929 922 struct work_struct csa_finalize_work; 930 923 bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ 931 924 struct cfg80211_chan_def csa_chandef; 925 + 926 + struct work_struct color_change_finalize_work; 932 927 933 928 struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ 934 929 struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */ ··· 1895 1886 void ieee80211_csa_finalize_work(struct work_struct *work); 1896 1887 int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 1897 1888 struct cfg80211_csa_settings *params); 1889 + 1890 + /* color change handling */ 1891 + void ieee80211_color_change_finalize_work(struct work_struct *work); 1898 1892 1899 1893 /* interface handling */ 1900 1894 #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+11 -2
net/mac80211/iface.c
··· 462 462 sdata_unlock(sdata); 463 463 464 464 cancel_work_sync(&sdata->csa_finalize_work); 465 + cancel_work_sync(&sdata->color_change_finalize_work); 465 466 466 467 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 467 468 ··· 1532 1531 INIT_WORK(&sdata->work, ieee80211_iface_work); 1533 1532 INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); 1534 1533 INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); 1534 + INIT_WORK(&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work); 1535 1535 INIT_LIST_HEAD(&sdata->assigned_chanctx_list); 1536 1536 INIT_LIST_HEAD(&sdata->reserved_chanctx_list); 1537 1537 ··· 2003 2001 2004 2002 netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); 2005 2003 2006 - /* MTU range: 256 - 2304 */ 2004 + /* MTU range is normally 256 - 2304, where the upper limit is 2005 + * the maximum MSDU size. Monitor interfaces send and receive 2006 + * MPDU and A-MSDU frames which may be much larger so we do 2007 + * not impose an upper limit in that case. 2008 + */ 2007 2009 ndev->min_mtu = 256; 2008 - ndev->max_mtu = local->hw.max_mtu; 2010 + if (type == NL80211_IFTYPE_MONITOR) 2011 + ndev->max_mtu = 0; 2012 + else 2013 + ndev->max_mtu = local->hw.max_mtu; 2009 2014 2010 2015 ret = cfg80211_register_netdevice(ndev); 2011 2016 if (ret) {
+1 -1
net/mac80211/main.c
··· 1020 1020 1021 1021 iftd = &sband->iftype_data[i]; 1022 1022 1023 - supp_he = supp_he || (iftd && iftd->he_cap.has_he); 1023 + supp_he = supp_he || iftd->he_cap.has_he; 1024 1024 } 1025 1025 1026 1026 /* HT, VHT, HE require QoS, thus >= 4 queues */
+17 -12
net/mac80211/rx.c
··· 359 359 360 360 put_unaligned_le32(it_present_val, it_present); 361 361 362 - pos = (void *)(it_present + 1); 362 + /* This references through an offset into it_optional[] rather 363 + * than via it_present otherwise later uses of pos will cause 364 + * the compiler to think we have walked past the end of the 365 + * struct member. 366 + */ 367 + pos = (void *)&rthdr->it_optional[it_present - rthdr->it_optional]; 363 368 364 369 /* the order of the following fields is important */ 365 370 ··· 377 372 ieee80211_calculate_rx_timestamp(local, status, 378 373 mpdulen, 0), 379 374 pos); 380 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); 375 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_TSFT)); 381 376 pos += 8; 382 377 } 383 378 ··· 401 396 *pos = 0; 402 397 } else { 403 398 int shift = 0; 404 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 399 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_RATE)); 405 400 if (status->bw == RATE_INFO_BW_10) 406 401 shift = 1; 407 402 else if (status->bw == RATE_INFO_BW_5) ··· 438 433 !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { 439 434 *pos = status->signal; 440 435 rthdr->it_present |= 441 - cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); 436 + cpu_to_le32(BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL)); 442 437 pos++; 443 438 } 444 439 ··· 464 459 if (status->encoding == RX_ENC_HT) { 465 460 unsigned int stbc; 466 461 467 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); 462 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_MCS)); 468 463 *pos++ = local->hw.radiotap_mcs_details; 469 464 *pos = 0; 470 465 if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) ··· 488 483 while ((pos - (u8 *)rthdr) & 3) 489 484 pos++; 490 485 rthdr->it_present |= 491 - cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS); 486 + cpu_to_le32(BIT(IEEE80211_RADIOTAP_AMPDU_STATUS)); 492 487 put_unaligned_le32(status->ampdu_reference, pos); 493 488 pos += 4; 494 489 if (status->flag & RX_FLAG_AMPDU_LAST_KNOWN) ··· 515 510 if (status->encoding == RX_ENC_VHT) { 516 511 u16 known = local->hw.radiotap_vht_details; 517 512 518 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); 513 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_VHT)); 519 514 put_unaligned_le16(known, pos); 520 515 pos += 2; 521 516 /* flags */ ··· 559 554 u8 flags = IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT; 560 555 561 556 rthdr->it_present |= 562 - cpu_to_le32(1 << IEEE80211_RADIOTAP_TIMESTAMP); 557 + cpu_to_le32(BIT(IEEE80211_RADIOTAP_TIMESTAMP)); 563 558 564 559 /* ensure 8 byte alignment */ 565 560 while ((pos - (u8 *)rthdr) & 7) ··· 647 642 /* ensure 2 byte alignment */ 648 643 while ((pos - (u8 *)rthdr) & 1) 649 644 pos++; 650 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE); 645 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_HE)); 651 646 memcpy(pos, &he, sizeof(he)); 652 647 pos += sizeof(he); 653 648 } ··· 657 652 /* ensure 2 byte alignment */ 658 653 while ((pos - (u8 *)rthdr) & 1) 659 654 pos++; 660 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE_MU); 655 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_HE_MU)); 661 656 memcpy(pos, &he_mu, sizeof(he_mu)); 662 657 pos += sizeof(he_mu); 663 658 } 664 659 665 660 if (status->flag & RX_FLAG_NO_PSDU) { 666 661 rthdr->it_present |= 667 - cpu_to_le32(1 << IEEE80211_RADIOTAP_ZERO_LEN_PSDU); 662 + cpu_to_le32(BIT(IEEE80211_RADIOTAP_ZERO_LEN_PSDU)); 668 663 *pos++ = status->zero_length_psdu_type; 669 664 } 670 665 ··· 672 667 /* ensure 2 byte alignment */ 673 668 while ((pos - (u8 *)rthdr) & 1) 674 669 pos++; 675 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_LSIG); 670 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_LSIG)); 676 671 memcpy(pos, &lsig, sizeof(lsig)); 677 672 pos += sizeof(lsig); 678 673 }
+1 -1
net/mac80211/sta_info.c
··· 543 543 return -ENETDOWN; 544 544 545 545 if (WARN_ON(ether_addr_equal(sta->sta.addr, sdata->vif.addr) || 546 - is_multicast_ether_addr(sta->sta.addr))) 546 + !is_valid_ether_addr(sta->sta.addr))) 547 547 return -EINVAL; 548 548 549 549 /* The RCU read lock is required by rhashtable due to
+8 -8
net/mac80211/status.c
··· 305 305 memset(rthdr, 0, rtap_len); 306 306 rthdr->it_len = cpu_to_le16(rtap_len); 307 307 rthdr->it_present = 308 - cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | 309 - (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); 308 + cpu_to_le32(BIT(IEEE80211_RADIOTAP_TX_FLAGS) | 309 + BIT(IEEE80211_RADIOTAP_DATA_RETRIES)); 310 310 pos = (unsigned char *)(rthdr + 1); 311 311 312 312 /* ··· 331 331 sband->bitrates[info->status.rates[0].idx].bitrate; 332 332 333 333 if (legacy_rate) { 334 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); 334 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_RATE)); 335 335 *pos = DIV_ROUND_UP(legacy_rate, 5 * (1 << shift)); 336 336 /* padding for tx flags */ 337 337 pos += 2; ··· 358 358 359 359 if (status && status->rate && 360 360 (status->rate->flags & RATE_INFO_FLAGS_MCS)) { 361 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); 361 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_MCS)); 362 362 pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS | 363 363 IEEE80211_RADIOTAP_MCS_HAVE_GI | 364 364 IEEE80211_RADIOTAP_MCS_HAVE_BW; ··· 374 374 (IEEE80211_RADIOTAP_VHT_KNOWN_GI | 375 375 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH); 376 376 377 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); 377 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_VHT)); 378 378 379 379 /* required alignment from rthdr */ 380 380 pos = (u8 *)rthdr + ALIGN(pos - (u8 *)rthdr, 2); ··· 419 419 (status->rate->flags & RATE_INFO_FLAGS_HE_MCS)) { 420 420 struct ieee80211_radiotap_he *he; 421 421 422 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_HE); 422 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_HE)); 423 423 424 424 /* required alignment from rthdr */ 425 425 pos = (u8 *)rthdr + ALIGN(pos - (u8 *)rthdr, 2); ··· 495 495 /* IEEE80211_RADIOTAP_MCS 496 496 * IEEE80211_RADIOTAP_VHT */ 497 497 if (info->status.rates[0].flags & IEEE80211_TX_RC_MCS) { 498 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); 498 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_MCS)); 499 499 pos[0] = IEEE80211_RADIOTAP_MCS_HAVE_MCS | 500 500 IEEE80211_RADIOTAP_MCS_HAVE_GI | 501 501 IEEE80211_RADIOTAP_MCS_HAVE_BW; ··· 512 512 (IEEE80211_RADIOTAP_VHT_KNOWN_GI | 513 513 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH); 514 514 515 - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); 515 + rthdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_VHT)); 516 516 517 517 /* required alignment from rthdr */ 518 518 pos = (u8 *)rthdr + ALIGN(pos - (u8 *)rthdr, 2);
+21 -12
net/mac80211/tx.c
··· 3242 3242 if (info->control.flags & IEEE80211_TX_CTRL_AMSDU) 3243 3243 return true; 3244 3244 3245 - if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr))) 3245 + if (!ieee80211_amsdu_realloc_pad(local, skb, 3246 + sizeof(*amsdu_hdr) + 3247 + local->hw.extra_tx_headroom)) 3246 3248 return false; 3247 3249 3248 3250 data = skb_push(skb, sizeof(*amsdu_hdr)); ··· 4784 4782 static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata, 4785 4783 struct beacon_data *beacon) 4786 4784 { 4785 + u8 *beacon_data, count, max_count = 1; 4787 4786 struct probe_resp *resp; 4788 - u8 *beacon_data; 4789 4787 size_t beacon_data_len; 4788 + u16 *bcn_offsets; 4790 4789 int i; 4791 - u8 count = beacon->cntdwn_current_counter; 4792 4790 4793 4791 switch (sdata->vif.type) { 4794 4792 case NL80211_IFTYPE_AP: ··· 4808 4806 } 4809 4807 4810 4808 rcu_read_lock(); 4811 - for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; ++i) { 4812 - resp = rcu_dereference(sdata->u.ap.probe_resp); 4809 + resp = rcu_dereference(sdata->u.ap.probe_resp); 4813 4810 4814 - if (beacon->cntdwn_counter_offsets[i]) { 4815 - if (WARN_ON_ONCE(beacon->cntdwn_counter_offsets[i] >= 4816 - beacon_data_len)) { 4811 + bcn_offsets = beacon->cntdwn_counter_offsets; 4812 + count = beacon->cntdwn_current_counter; 4813 + if (sdata->vif.csa_active) 4814 + max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM; 4815 + 4816 + for (i = 0; i < max_count; ++i) { 4817 + if (bcn_offsets[i]) { 4818 + if (WARN_ON_ONCE(bcn_offsets[i] >= beacon_data_len)) { 4817 4819 rcu_read_unlock(); 4818 4820 return; 4819 4821 } 4820 - 4821 - beacon_data[beacon->cntdwn_counter_offsets[i]] = count; 4822 + beacon_data[bcn_offsets[i]] = count; 4822 4823 } 4823 4824 4824 - if (sdata->vif.type == NL80211_IFTYPE_AP && resp) 4825 - resp->data[resp->cntdwn_counter_offsets[i]] = count; 4825 + if (sdata->vif.type == NL80211_IFTYPE_AP && resp) { 4826 + u16 *resp_offsets = resp->cntdwn_counter_offsets; 4827 + 4828 + resp->data[resp_offsets[i]] = count; 4829 + } 4826 4830 } 4827 4831 rcu_read_unlock(); 4828 4832 } ··· 5038 5030 if (offs) { 5039 5031 offs->tim_offset = beacon->head_len; 5040 5032 offs->tim_length = skb->len - beacon->head_len; 5033 + offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; 5041 5034 5042 5035 /* for AP the csa offsets are from tail */ 5043 5036 csa_off_base = skb->len;
+157
net/wireless/nl80211.c
··· 759 759 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, 760 760 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), 761 761 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG }, 762 + [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 }, 763 + [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 }, 764 + [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 }, 765 + [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy), 762 766 }; 763 767 764 768 /* policy for the key attributes */ ··· 14804 14800 return ret; 14805 14801 } 14806 14802 14803 + static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) 14804 + { 14805 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 14806 + struct cfg80211_color_change_settings params = {}; 14807 + struct net_device *dev = info->user_ptr[1]; 14808 + struct wireless_dev *wdev = dev->ieee80211_ptr; 14809 + struct nlattr **tb; 14810 + u16 offset; 14811 + int err; 14812 + 14813 + if (!rdev->ops->color_change) 14814 + return -EOPNOTSUPP; 14815 + 14816 + if (!wiphy_ext_feature_isset(&rdev->wiphy, 14817 + NL80211_EXT_FEATURE_BSS_COLOR)) 14818 + return -EOPNOTSUPP; 14819 + 14820 + if (wdev->iftype != NL80211_IFTYPE_AP) 14821 + return -EOPNOTSUPP; 14822 + 14823 + if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] || 14824 + !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] || 14825 + !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS]) 14826 + return -EINVAL; 14827 + 14828 + params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]); 14829 + params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]); 14830 + 14831 + err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next); 14832 + if (err) 14833 + return err; 14834 + 14835 + tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL); 14836 + if (!tb) 14837 + return -ENOMEM; 14838 + 14839 + err = nla_parse_nested(tb, NL80211_ATTR_MAX, 14840 + info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS], 14841 + nl80211_policy, info->extack); 14842 + if (err) 14843 + goto out; 14844 + 14845 + err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change); 14846 + if (err) 14847 + goto out; 14848 + 14849 + if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) { 14850 + err = -EINVAL; 14851 + goto out; 14852 + } 14853 + 14854 + if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) { 14855 + err = -EINVAL; 14856 + goto out; 14857 + } 14858 + 14859 + offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]); 14860 + if (offset >= params.beacon_color_change.tail_len) { 14861 + err = -EINVAL; 14862 + goto out; 14863 + } 14864 + 14865 + if (params.beacon_color_change.tail[offset] != params.count) { 14866 + err = -EINVAL; 14867 + goto out; 14868 + } 14869 + 14870 + params.counter_offset_beacon = offset; 14871 + 14872 + if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) { 14873 + if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) != 14874 + sizeof(u16)) { 14875 + err = -EINVAL; 14876 + goto out; 14877 + } 14878 + 14879 + offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]); 14880 + if (offset >= params.beacon_color_change.probe_resp_len) { 14881 + err = -EINVAL; 14882 + goto out; 14883 + } 14884 + 14885 + if (params.beacon_color_change.probe_resp[offset] != 14886 + params.count) { 14887 + err = -EINVAL; 14888 + goto out; 14889 + } 14890 + 14891 + params.counter_offset_presp = offset; 14892 + } 14893 + 14894 + wdev_lock(wdev); 14895 + err = rdev_color_change(rdev, dev, &params); 14896 + wdev_unlock(wdev); 14897 + 14898 + out: 14899 + kfree(tb); 14900 + return err; 14901 + } 14902 + 14807 14903 #define NL80211_FLAG_NEED_WIPHY 0x01 14808 14904 #define NL80211_FLAG_NEED_NETDEV 0x02 14809 14905 #define NL80211_FLAG_NEED_RTNL 0x04 ··· 15897 15793 .doit = nl80211_set_sar_specs, 15898 15794 .flags = GENL_UNS_ADMIN_PERM, 15899 15795 .internal_flags = NL80211_FLAG_NEED_WIPHY | 15796 + NL80211_FLAG_NEED_RTNL, 15797 + }, 15798 + { 15799 + .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST, 15800 + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 15801 + .doit = nl80211_color_change, 15802 + .flags = GENL_UNS_ADMIN_PERM, 15803 + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 15900 15804 NL80211_FLAG_NEED_RTNL, 15901 15805 }, 15902 15806 }; ··· 17535 17423 count, quiet); 17536 17424 } 17537 17425 EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); 17426 + 17427 + int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp, 17428 + enum nl80211_commands cmd, u8 count, 17429 + u64 color_bitmap) 17430 + { 17431 + struct wireless_dev *wdev = dev->ieee80211_ptr; 17432 + struct wiphy *wiphy = wdev->wiphy; 17433 + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 17434 + struct sk_buff *msg; 17435 + void *hdr; 17436 + 17437 + ASSERT_WDEV_LOCK(wdev); 17438 + 17439 + trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); 17440 + 17441 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 17442 + if (!msg) 17443 + return -ENOMEM; 17444 + 17445 + hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); 17446 + if (!hdr) 17447 + goto nla_put_failure; 17448 + 17449 + if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) 17450 + goto nla_put_failure; 17451 + 17452 + if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED && 17453 + nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count)) 17454 + goto nla_put_failure; 17455 + 17456 + if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION && 17457 + nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP, 17458 + color_bitmap, NL80211_ATTR_PAD)) 17459 + goto nla_put_failure; 17460 + 17461 + genlmsg_end(msg, hdr); 17462 + 17463 + return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), 17464 + msg, 0, NL80211_MCGRP_MLME, gfp); 17465 + 17466 + nla_put_failure: 17467 + nlmsg_free(msg); 17468 + return -EINVAL; 17469 + } 17470 + EXPORT_SYMBOL(cfg80211_bss_color_notify); 17538 17471 17539 17472 void 17540 17473 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
+4 -5
net/wireless/radiotap.c
··· 115 115 iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len); 116 116 iterator->_arg_index = 0; 117 117 iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present); 118 - iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header); 118 + iterator->_arg = (uint8_t *)radiotap_header->it_optional; 119 119 iterator->_reset_on_ext = 0; 120 - iterator->_next_bitmap = &radiotap_header->it_present; 121 - iterator->_next_bitmap++; 120 + iterator->_next_bitmap = radiotap_header->it_optional; 122 121 iterator->_vns = vns; 123 122 iterator->current_namespace = &radiotap_ns; 124 123 iterator->is_radiotap_ns = 1; 125 124 126 125 /* find payload start allowing for extended bitmap(s) */ 127 126 128 - if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) { 127 + if (iterator->_bitmap_shifter & (BIT(IEEE80211_RADIOTAP_EXT))) { 129 128 if ((unsigned long)iterator->_arg - 130 129 (unsigned long)iterator->_rtheader + sizeof(uint32_t) > 131 130 (unsigned long)iterator->_max_length) 132 131 return -EINVAL; 133 132 while (get_unaligned_le32(iterator->_arg) & 134 - (1 << IEEE80211_RADIOTAP_EXT)) { 133 + (BIT(IEEE80211_RADIOTAP_EXT))) { 135 134 iterator->_arg += sizeof(uint32_t); 136 135 137 136 /*
+13
net/wireless/rdev-ops.h
··· 1368 1368 return ret; 1369 1369 } 1370 1370 1371 + static inline int rdev_color_change(struct cfg80211_registered_device *rdev, 1372 + struct net_device *dev, 1373 + struct cfg80211_color_change_settings *params) 1374 + { 1375 + int ret; 1376 + 1377 + trace_rdev_color_change(&rdev->wiphy, dev, params); 1378 + ret = rdev->ops->color_change(&rdev->wiphy, dev, params); 1379 + trace_rdev_return_int(&rdev->wiphy, ret); 1380 + 1381 + return ret; 1382 + } 1383 + 1371 1384 #endif /* __CFG80211_RDEV_OPS */
+46
net/wireless/trace.h
··· 3597 3597 WIPHY_PR_ARG, __entry->type, __entry->num) 3598 3598 ); 3599 3599 3600 + TRACE_EVENT(rdev_color_change, 3601 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 3602 + struct cfg80211_color_change_settings *params), 3603 + TP_ARGS(wiphy, netdev, params), 3604 + TP_STRUCT__entry( 3605 + WIPHY_ENTRY 3606 + NETDEV_ENTRY 3607 + __field(u8, count) 3608 + __field(u16, bcn_ofs) 3609 + __field(u16, pres_ofs) 3610 + ), 3611 + TP_fast_assign( 3612 + WIPHY_ASSIGN; 3613 + NETDEV_ASSIGN; 3614 + __entry->count = params->count; 3615 + __entry->bcn_ofs = params->counter_offset_beacon; 3616 + __entry->pres_ofs = params->counter_offset_presp; 3617 + ), 3618 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT 3619 + ", count: %u", 3620 + WIPHY_PR_ARG, NETDEV_PR_ARG, 3621 + __entry->count) 3622 + ); 3623 + 3624 + TRACE_EVENT(cfg80211_bss_color_notify, 3625 + TP_PROTO(struct net_device *netdev, 3626 + enum nl80211_commands cmd, 3627 + u8 count, u64 color_bitmap), 3628 + TP_ARGS(netdev, cmd, count, color_bitmap), 3629 + TP_STRUCT__entry( 3630 + NETDEV_ENTRY 3631 + __field(u32, cmd) 3632 + __field(u8, count) 3633 + __field(u64, color_bitmap) 3634 + ), 3635 + TP_fast_assign( 3636 + NETDEV_ASSIGN; 3637 + __entry->cmd = cmd; 3638 + __entry->count = count; 3639 + __entry->color_bitmap = color_bitmap; 3640 + ), 3641 + TP_printk(NETDEV_PR_FMT ", cmd: %x, count: %u, bitmap: %llx", 3642 + NETDEV_PR_ARG, __entry->cmd, __entry->count, 3643 + __entry->color_bitmap) 3644 + ); 3645 + 3600 3646 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 3601 3647 3602 3648 #undef TRACE_INCLUDE_PATH