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-2020-04-25' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
One batch of changes, containing:
* hwsim improvements from Jouni and myself, to be able to
test more scenarios easily
* some more HE (802.11ax) support
* some initial S1G (sub 1 GHz) work for fractional MHz channels
* some (action) frame registration updates to help DPP support
* along with other various improvements/fixes
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+900 -469
+1 -2
drivers/net/wireless/ath/ath11k/mac.c
··· 1178 1178 sizeof(arg->peer_he_cap_macinfo)); 1179 1179 memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info, 1180 1180 sizeof(arg->peer_he_cap_phyinfo)); 1181 - memcpy(&arg->peer_he_ops, &vif->bss_conf.he_operation, 1182 - sizeof(arg->peer_he_ops)); 1181 + arg->peer_he_ops = vif->bss_conf.he_oper.params; 1183 1182 1184 1183 /* the top most byte is used to indicate BSS color info */ 1185 1184 arg->peer_he_ops &= 0xffffff;
+12 -14
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 3249 3249 return 0; 3250 3250 } 3251 3251 3252 - static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, 3253 - struct wireless_dev *wdev, 3254 - u16 frame_type, bool reg) 3252 + static void ath6kl_update_mgmt_frame_registrations(struct wiphy *wiphy, 3253 + struct wireless_dev *wdev, 3254 + struct mgmt_frame_regs *upd) 3255 3255 { 3256 3256 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3257 3257 3258 - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n", 3259 - __func__, frame_type, reg); 3260 - if (frame_type == IEEE80211_STYPE_PROBE_REQ) { 3261 - /* 3262 - * Note: This notification callback is not allowed to sleep, so 3263 - * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we 3264 - * hardcode target to report Probe Request frames all the time. 3265 - */ 3266 - vif->probe_req_report = reg; 3267 - } 3258 + /* 3259 + * FIXME: send WMI_PROBE_REQ_REPORT_CMD here instead of hardcoding 3260 + * the reporting in the target all the time, this callback 3261 + * *is* allowed to sleep after all. 3262 + */ 3263 + vif->probe_req_report = 3264 + upd->interface_stypes & BIT(IEEE80211_STYPE_PROBE_REQ >> 4); 3268 3265 } 3269 3266 3270 3267 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, ··· 3461 3464 .remain_on_channel = ath6kl_remain_on_channel, 3462 3465 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, 3463 3466 .mgmt_tx = ath6kl_mgmt_tx, 3464 - .mgmt_frame_register = ath6kl_mgmt_frame_register, 3467 + .update_mgmt_frame_registrations = 3468 + ath6kl_update_mgmt_frame_registrations, 3465 3469 .get_antenna = ath6kl_get_antenna, 3466 3470 .sched_scan_start = ath6kl_cfg80211_sscan_start, 3467 3471 .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
+7 -12
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
··· 5031 5031 } 5032 5032 5033 5033 static void 5034 - brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy, 5035 - struct wireless_dev *wdev, 5036 - u16 frame_type, bool reg) 5034 + brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy, 5035 + struct wireless_dev *wdev, 5036 + struct mgmt_frame_regs *upd) 5037 5037 { 5038 5038 struct brcmf_cfg80211_vif *vif; 5039 - u16 mgmt_type; 5040 5039 5041 - brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg); 5042 - 5043 - mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; 5044 5040 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); 5045 - if (reg) 5046 - vif->mgmt_rx_reg |= BIT(mgmt_type); 5047 - else 5048 - vif->mgmt_rx_reg &= ~BIT(mgmt_type); 5041 + 5042 + vif->mgmt_rx_reg = upd->interface_stypes; 5049 5043 } 5050 5044 5051 5045 ··· 5454 5460 .change_station = brcmf_cfg80211_change_station, 5455 5461 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 5456 5462 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 5457 - .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register, 5463 + .update_mgmt_frame_registrations = 5464 + brcmf_cfg80211_update_mgmt_frame_registrations, 5458 5465 .mgmt_tx = brcmf_cfg80211_mgmt_tx, 5459 5466 .remain_on_channel = brcmf_p2p_remain_on_channel, 5460 5467 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
+3 -3
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /****************************************************************************** 3 3 * 4 - * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 4 + * Copyright(c) 2005 - 2014, 2018 - 2020 Intel Corporation. All rights reserved. 5 5 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 6 6 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 7 - * Copyright(c) 2018 - 2019 Intel Corporation 8 7 * 9 8 * Contact Information: 10 9 * Intel Linux Wireless <linuxwifi@intel.com> ··· 1429 1430 */ 1430 1431 if (ieee80211_get_vht_max_nss(&vht_cap, 1431 1432 IEEE80211_VHT_CHANWIDTH_160MHZ, 1432 - 0, true) < sta->rx_nss) 1433 + 0, true, 1434 + sta->rx_nss) < sta->rx_nss) 1433 1435 return RATE_MCS_CHAN_WIDTH_80; 1434 1436 return RATE_MCS_CHAN_WIDTH_160; 1435 1437 case IEEE80211_STA_RX_BW_80:
+63
drivers/net/wireless/mac80211_hwsim.c
··· 1068 1068 return res; 1069 1069 } 1070 1070 1071 + static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw, 1072 + const u8 *addr, bool add) 1073 + { 1074 + struct mac80211_hwsim_data *data = hw->priv; 1075 + u32 _portid = READ_ONCE(data->wmediumd); 1076 + struct sk_buff *skb; 1077 + void *msg_head; 1078 + 1079 + if (!_portid && !hwsim_virtio_enabled) 1080 + return; 1081 + 1082 + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1083 + if (!skb) 1084 + return; 1085 + 1086 + msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, 1087 + add ? HWSIM_CMD_ADD_MAC_ADDR : 1088 + HWSIM_CMD_DEL_MAC_ADDR); 1089 + if (!msg_head) { 1090 + pr_debug("mac80211_hwsim: problem with msg_head\n"); 1091 + goto nla_put_failure; 1092 + } 1093 + 1094 + if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, 1095 + ETH_ALEN, data->addresses[1].addr)) 1096 + goto nla_put_failure; 1097 + 1098 + if (nla_put(skb, HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN, addr)) 1099 + goto nla_put_failure; 1100 + 1101 + genlmsg_end(skb, msg_head); 1102 + 1103 + if (hwsim_virtio_enabled) 1104 + hwsim_tx_virtio(data, skb); 1105 + else 1106 + hwsim_unicast_netgroup(data, skb, _portid); 1107 + return; 1108 + nla_put_failure: 1109 + nlmsg_free(skb); 1110 + } 1111 + 1071 1112 static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate) 1072 1113 { 1073 1114 u16 result = 0; ··· 1586 1545 vif->addr); 1587 1546 hwsim_set_magic(vif); 1588 1547 1548 + if (vif->type != NL80211_IFTYPE_MONITOR) 1549 + mac80211_hwsim_config_mac_nl(hw, vif->addr, true); 1550 + 1589 1551 vif->cab_queue = 0; 1590 1552 vif->hw_queue[IEEE80211_AC_VO] = 0; 1591 1553 vif->hw_queue[IEEE80211_AC_VI] = 1; ··· 1628 1584 vif->addr); 1629 1585 hwsim_check_magic(vif); 1630 1586 hwsim_clear_magic(vif); 1587 + if (vif->type != NL80211_IFTYPE_MONITOR) 1588 + mac80211_hwsim_config_mac_nl(hw, vif->addr, false); 1631 1589 } 1632 1590 1633 1591 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, ··· 1827 1781 data->rx_filter = 0; 1828 1782 if (*total_flags & FIF_ALLMULTI) 1829 1783 data->rx_filter |= FIF_ALLMULTI; 1784 + if (*total_flags & FIF_MCAST_ACTION) 1785 + data->rx_filter |= FIF_MCAST_ACTION; 1830 1786 1831 1787 *total_flags = data->rx_filter; 1832 1788 } ··· 2152 2104 hwsim->hw_scan_vif = NULL; 2153 2105 hwsim->tmp_chan = NULL; 2154 2106 mutex_unlock(&hwsim->mutex); 2107 + mac80211_hwsim_config_mac_nl(hwsim->hw, hwsim->scan_addr, 2108 + false); 2155 2109 return; 2156 2110 } 2157 2111 ··· 2227 2177 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data)); 2228 2178 mutex_unlock(&hwsim->mutex); 2229 2179 2180 + mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true); 2230 2181 wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n"); 2231 2182 2232 2183 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0); ··· 2271 2220 pr_debug("hwsim sw_scan request, prepping stuff\n"); 2272 2221 2273 2222 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN); 2223 + mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true); 2274 2224 hwsim->scanning = true; 2275 2225 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data)); 2276 2226 ··· 2288 2236 2289 2237 pr_debug("hwsim sw_scan_complete\n"); 2290 2238 hwsim->scanning = false; 2239 + mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, false); 2291 2240 eth_zero_addr(hwsim->scan_addr); 2292 2241 2293 2242 mutex_unlock(&hwsim->mutex); ··· 2466 2413 WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN); 2467 2414 } 2468 2415 2416 + static int mac80211_hwsim_tx_last_beacon(struct ieee80211_hw *hw) 2417 + { 2418 + return 1; 2419 + } 2420 + 2469 2421 #define HWSIM_COMMON_OPS \ 2470 2422 .tx = mac80211_hwsim_tx, \ 2471 2423 .start = mac80211_hwsim_start, \ ··· 2481 2423 .config = mac80211_hwsim_config, \ 2482 2424 .configure_filter = mac80211_hwsim_configure_filter, \ 2483 2425 .bss_info_changed = mac80211_hwsim_bss_info_changed, \ 2426 + .tx_last_beacon = mac80211_hwsim_tx_last_beacon, \ 2484 2427 .sta_add = mac80211_hwsim_sta_add, \ 2485 2428 .sta_remove = mac80211_hwsim_sta_remove, \ 2486 2429 .sta_notify = mac80211_hwsim_sta_notify, \ ··· 3062 3003 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; 3063 3004 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS); 3064 3005 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION); 3006 + wiphy_ext_feature_set(hw->wiphy, 3007 + NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS); 3008 + wiphy_ext_feature_set(hw->wiphy, 3009 + NL80211_EXT_FEATURE_BEACON_RATE_LEGACY); 3065 3010 3066 3011 hw->wiphy->interface_modes = param->iftypes; 3067 3012
+8
drivers/net/wireless/mac80211_hwsim.h
··· 75 75 * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted 76 76 * @HWSIM_CMD_GET_RADIO: fetch information about existing radios, uses: 77 77 * %HWSIM_ATTR_RADIO_ID 78 + * @HWSIM_CMD_ADD_MAC_ADDR: add a receive MAC address (given in the 79 + * %HWSIM_ATTR_ADDR_RECEIVER attribute) to a device identified by 80 + * %HWSIM_ATTR_ADDR_TRANSMITTER. This lets wmediumd forward frames 81 + * to this receiver address for a given station. 82 + * @HWSIM_CMD_DEL_MAC_ADDR: remove the MAC address again, the attributes 83 + * are the same as to @HWSIM_CMD_ADD_MAC_ADDR. 78 84 * @__HWSIM_CMD_MAX: enum limit 79 85 */ 80 86 enum { ··· 91 85 HWSIM_CMD_NEW_RADIO, 92 86 HWSIM_CMD_DEL_RADIO, 93 87 HWSIM_CMD_GET_RADIO, 88 + HWSIM_CMD_ADD_MAC_ADDR, 89 + HWSIM_CMD_DEL_MAC_ADDR, 94 90 __HWSIM_CMD_MAX, 95 91 }; 96 92 #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
+6 -10
drivers/net/wireless/marvell/mwifiex/cfg80211.c
··· 269 269 * CFG802.11 operation handler to register a mgmt frame. 270 270 */ 271 271 static void 272 - mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy, 273 - struct wireless_dev *wdev, 274 - u16 frame_type, bool reg) 272 + mwifiex_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy, 273 + struct wireless_dev *wdev, 274 + struct mgmt_frame_regs *upd) 275 275 { 276 276 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 277 - u32 mask; 278 - 279 - if (reg) 280 - mask = priv->mgmt_frame_mask | BIT(frame_type >> 4); 281 - else 282 - mask = priv->mgmt_frame_mask & ~BIT(frame_type >> 4); 277 + u32 mask = upd->interface_stypes; 283 278 284 279 if (mask != priv->mgmt_frame_mask) { 285 280 priv->mgmt_frame_mask = mask; ··· 4182 4187 .del_key = mwifiex_cfg80211_del_key, 4183 4188 .set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key, 4184 4189 .mgmt_tx = mwifiex_cfg80211_mgmt_tx, 4185 - .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register, 4190 + .update_mgmt_frame_registrations = 4191 + mwifiex_cfg80211_update_mgmt_frame_registrations, 4186 4192 .remain_on_channel = mwifiex_cfg80211_remain_on_channel, 4187 4193 .cancel_remain_on_channel = mwifiex_cfg80211_cancel_remain_on_channel, 4188 4194 .set_default_key = mwifiex_cfg80211_set_default_key,
+44 -41
drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
··· 389 389 } 390 390 391 391 static void 392 - qtnf_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, 393 - u16 frame_type, bool reg) 392 + qtnf_update_mgmt_frame_registrations(struct wiphy *wiphy, 393 + struct wireless_dev *wdev, 394 + struct mgmt_frame_regs *upd) 394 395 { 395 396 struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev); 396 - u16 mgmt_type; 397 - u16 new_mask; 398 - u16 qlink_frame_type = 0; 397 + u16 new_mask = upd->interface_stypes; 398 + u16 old_mask = vif->mgmt_frames_bitmask; 399 + static const struct { 400 + u16 mask, qlink_type; 401 + } updates[] = { 402 + { 403 + .mask = BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | 404 + BIT(IEEE80211_STYPE_ASSOC_REQ >> 4), 405 + .qlink_type = QLINK_MGMT_FRAME_ASSOC_REQ, 406 + }, 407 + { 408 + .mask = BIT(IEEE80211_STYPE_AUTH >> 4), 409 + .qlink_type = QLINK_MGMT_FRAME_AUTH, 410 + }, 411 + { 412 + .mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4), 413 + .qlink_type = QLINK_MGMT_FRAME_PROBE_REQ, 414 + }, 415 + { 416 + .mask = BIT(IEEE80211_STYPE_ACTION >> 4), 417 + .qlink_type = QLINK_MGMT_FRAME_ACTION, 418 + }, 419 + }; 420 + unsigned int i; 399 421 400 - mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; 401 - 402 - if (reg) 403 - new_mask = vif->mgmt_frames_bitmask | BIT(mgmt_type); 404 - else 405 - new_mask = vif->mgmt_frames_bitmask & ~BIT(mgmt_type); 406 - 407 - if (new_mask == vif->mgmt_frames_bitmask) 422 + if (new_mask == old_mask) 408 423 return; 409 424 410 - switch (frame_type & IEEE80211_FCTL_STYPE) { 411 - case IEEE80211_STYPE_REASSOC_REQ: 412 - case IEEE80211_STYPE_ASSOC_REQ: 413 - qlink_frame_type = QLINK_MGMT_FRAME_ASSOC_REQ; 414 - break; 415 - case IEEE80211_STYPE_AUTH: 416 - qlink_frame_type = QLINK_MGMT_FRAME_AUTH; 417 - break; 418 - case IEEE80211_STYPE_PROBE_REQ: 419 - qlink_frame_type = QLINK_MGMT_FRAME_PROBE_REQ; 420 - break; 421 - case IEEE80211_STYPE_ACTION: 422 - qlink_frame_type = QLINK_MGMT_FRAME_ACTION; 423 - break; 424 - default: 425 - pr_warn("VIF%u.%u: unsupported frame type: %X\n", 426 - vif->mac->macid, vif->vifid, 427 - (frame_type & IEEE80211_FCTL_STYPE) >> 4); 428 - return; 429 - } 425 + for (i = 0; i < ARRAY_SIZE(updates); i++) { 426 + u16 mask = updates[i].mask; 427 + u16 qlink_frame_type = updates[i].qlink_type; 428 + bool reg; 430 429 431 - if (qtnf_cmd_send_register_mgmt(vif, qlink_frame_type, reg)) { 432 - pr_warn("VIF%u.%u: failed to %sregister mgmt frame type 0x%x\n", 433 - vif->mac->macid, vif->vifid, reg ? "" : "un", 434 - frame_type); 435 - return; 430 + /* the ! are here due to the assoc/reassoc merge */ 431 + if (!(new_mask & mask) == !(old_mask & mask)) 432 + continue; 433 + 434 + reg = new_mask & mask; 435 + 436 + if (qtnf_cmd_send_register_mgmt(vif, qlink_frame_type, reg)) 437 + pr_warn("VIF%u.%u: failed to %sregister qlink frame type 0x%x\n", 438 + vif->mac->macid, vif->vifid, reg ? "" : "un", 439 + qlink_frame_type); 436 440 } 437 441 438 442 vif->mgmt_frames_bitmask = new_mask; 439 - pr_debug("VIF%u.%u: %sregistered mgmt frame type 0x%x\n", 440 - vif->mac->macid, vif->vifid, reg ? "" : "un", frame_type); 441 443 } 442 444 443 445 static int ··· 1019 1017 .change_beacon = qtnf_change_beacon, 1020 1018 .stop_ap = qtnf_stop_ap, 1021 1019 .set_wiphy_params = qtnf_set_wiphy_params, 1022 - .mgmt_frame_register = qtnf_mgmt_frame_register, 1020 + .update_mgmt_frame_registrations = 1021 + qtnf_update_mgmt_frame_registrations, 1023 1022 .mgmt_tx = qtnf_mgmt_tx, 1024 1023 .change_station = qtnf_change_station, 1025 1024 .del_station = qtnf_del_station,
-24
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
··· 3163 3163 return ret; 3164 3164 } 3165 3165 3166 - static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, 3167 - struct wireless_dev *wdev, 3168 - u16 frame_type, bool reg) 3169 - { 3170 - struct net_device *ndev = wdev_to_ndev(wdev); 3171 - struct adapter *adapter; 3172 - 3173 - if (ndev == NULL) 3174 - goto exit; 3175 - 3176 - adapter = (struct adapter *)rtw_netdev_priv(ndev); 3177 - 3178 - #ifdef DEBUG_CFG80211 3179 - DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter), 3180 - frame_type, reg); 3181 - #endif 3182 - 3183 - if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) 3184 - return; 3185 - exit: 3186 - return; 3187 - } 3188 - 3189 3166 #if defined(CONFIG_PNO_SUPPORT) 3190 3167 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy, 3191 3168 struct net_device *dev, ··· 3374 3397 .change_bss = cfg80211_rtw_change_bss, 3375 3398 3376 3399 .mgmt_tx = cfg80211_rtw_mgmt_tx, 3377 - .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register, 3378 3400 3379 3401 #if defined(CONFIG_PNO_SUPPORT) 3380 3402 .sched_scan_start = cfg80211_rtw_sched_scan_start,
+17 -19
drivers/staging/wilc1000/cfg80211.c
··· 1217 1217 return 0; 1218 1218 } 1219 1219 1220 - void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, 1221 - u16 frame_type, bool reg) 1220 + void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy, 1221 + struct wireless_dev *wdev, 1222 + struct mgmt_frame_regs *upd) 1222 1223 { 1223 1224 struct wilc *wl = wiphy_priv(wiphy); 1224 1225 struct wilc_vif *vif = netdev_priv(wdev->netdev); 1226 + u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4); 1227 + u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4); 1225 1228 1226 - if (!frame_type) 1227 - return; 1229 + if (wl->initialized) { 1230 + bool prev = vif->mgmt_reg_stypes & presp_bit; 1231 + bool now = upd->interface_stypes & presp_bit; 1228 1232 1229 - switch (frame_type) { 1230 - case IEEE80211_STYPE_PROBE_REQ: 1231 - vif->frame_reg[0].type = frame_type; 1232 - vif->frame_reg[0].reg = reg; 1233 - break; 1233 + if (now != prev) 1234 + wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now); 1234 1235 1235 - case IEEE80211_STYPE_ACTION: 1236 - vif->frame_reg[1].type = frame_type; 1237 - vif->frame_reg[1].reg = reg; 1238 - break; 1236 + prev = vif->mgmt_reg_stypes & action_bit; 1237 + now = upd->interface_stypes & action_bit; 1239 1238 1240 - default: 1241 - break; 1239 + if (now != prev) 1240 + wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now); 1242 1241 } 1243 1242 1244 - if (!wl->initialized) 1245 - return; 1246 - wilc_frame_register(vif, frame_type, reg); 1243 + vif->mgmt_reg_stypes = 1244 + upd->interface_stypes & (presp_bit | action_bit); 1247 1245 } 1248 1246 1249 1247 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, ··· 1663 1665 .cancel_remain_on_channel = cancel_remain_on_channel, 1664 1666 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait, 1665 1667 .mgmt_tx = mgmt_tx, 1666 - .mgmt_frame_register = wilc_mgmt_frame_register, 1668 + .update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations, 1667 1669 .set_power_mgmt = set_power_mgmt, 1668 1670 .set_cqm_rssi_config = set_cqm_rssi_config, 1669 1671
+3 -2
drivers/staging/wilc1000/cfg80211.h
··· 21 21 struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, 22 22 const char *name, 23 23 struct net_device *real_dev); 24 - void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, 25 - u16 frame_type, bool reg); 24 + void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy, 25 + struct wireless_dev *wdev, 26 + struct mgmt_frame_regs *upd); 26 27 struct wilc_vif *wilc_get_interface(struct wilc *wl); 27 28 struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl); 28 29 void wlan_deinit_locks(struct wilc *wilc);
+9 -12
drivers/staging/wilc1000/netdev.c
··· 571 571 struct wilc *wl = vif->wilc; 572 572 unsigned char mac_add[ETH_ALEN] = {0}; 573 573 int ret = 0; 574 + struct mgmt_frame_regs mgmt_regs = {}; 574 575 575 576 if (!wl || !wl->dev) { 576 577 netdev_err(ndev, "device not ready\n"); ··· 603 602 return -EINVAL; 604 603 } 605 604 606 - wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, 607 - vif->ndev->ieee80211_ptr, 608 - vif->frame_reg[0].type, 609 - vif->frame_reg[0].reg); 610 - wilc_mgmt_frame_register(vif->ndev->ieee80211_ptr->wiphy, 611 - vif->ndev->ieee80211_ptr, 612 - vif->frame_reg[1].type, 613 - vif->frame_reg[1].reg); 605 + mgmt_regs.interface_stypes = vif->mgmt_reg_stypes; 606 + /* so we detect a change */ 607 + vif->mgmt_reg_stypes = 0; 608 + wilc_update_mgmt_frame_registrations(vif->ndev->ieee80211_ptr->wiphy, 609 + vif->ndev->ieee80211_ptr, 610 + &mgmt_regs); 614 611 netif_wake_queue(ndev); 615 612 wl->open_ifcs++; 616 613 vif->mac_opened = 1; ··· 791 792 srcu_idx = srcu_read_lock(&wilc->srcu); 792 793 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { 793 794 u16 type = le16_to_cpup((__le16 *)buff); 795 + u32 type_bit = BIT(type >> 4); 794 796 795 797 if (vif->priv.p2p_listen_state && 796 - ((type == vif->frame_reg[0].type && 797 - vif->frame_reg[0].reg) || 798 - (type == vif->frame_reg[1].type && 799 - vif->frame_reg[1].reg))) 798 + vif->mgmt_reg_stypes & type_bit) 800 799 wilc_wfi_p2p_rx(vif, buff, size); 801 800 802 801 if (vif->monitor_flag)
+1 -8
drivers/staging/wilc1000/netdev.h
··· 24 24 #define PMKID_FOUND 1 25 25 #define NUM_STA_ASSOCIATED 8 26 26 27 - #define NUM_REG_FRAME 2 28 - 29 27 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 30 28 #define DEFAULT_LINK_SPEED 72 31 29 ··· 149 151 u64 inc_roc_cookie; 150 152 }; 151 153 152 - struct frame_reg { 153 - u16 type; 154 - bool reg; 155 - }; 156 - 157 154 #define MAX_TCP_SESSION 25 158 155 #define MAX_PENDING_ACKS 256 159 156 ··· 180 187 u8 iftype; 181 188 int monitor_flag; 182 189 int mac_opened; 183 - struct frame_reg frame_reg[NUM_REG_FRAME]; 190 + u32 mgmt_reg_stypes; 184 191 struct net_device_stats netstats; 185 192 struct wilc *wilc; 186 193 u8 bssid[ETH_ALEN];
+20 -3
include/linux/ieee80211.h
··· 9 9 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH 11 11 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH 12 - * Copyright (c) 2018 - 2019 Intel Corporation 12 + * Copyright (c) 2018 - 2020 Intel Corporation 13 13 */ 14 14 15 15 #ifndef LINUX_IEEE80211_H ··· 859 859 * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ: 40 MHz channel width 860 860 * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ: 80 MHz channel width 861 861 * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ: 160 MHz or 80+80 MHz channel width 862 + * @IEEE80211_OPMODE_NOTIF_BW_160_80P80: 160 / 80+80 MHz indicator flag 862 863 * @IEEE80211_OPMODE_NOTIF_RX_NSS_MASK: number of spatial streams mask 863 864 * (the NSS value is the value of this field + 1) 864 865 * @IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT: number of spatial streams shift ··· 867 866 * using a beamforming steering matrix 868 867 */ 869 868 enum ieee80211_vht_opmode_bits { 870 - IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK = 3, 869 + IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK = 0x03, 871 870 IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ = 0, 872 871 IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ = 1, 873 872 IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ = 2, 874 873 IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ = 3, 874 + IEEE80211_OPMODE_NOTIF_BW_160_80P80 = 0x04, 875 875 IEEE80211_OPMODE_NOTIF_RX_NSS_MASK = 0x70, 876 876 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT = 4, 877 877 IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF = 0x80, ··· 1067 1065 /* Supported rates membership selectors */ 1068 1066 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 1069 1067 #define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 1068 + #define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 1070 1069 1071 1070 /* mgmt header + 1 byte category code */ 1072 1071 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) ··· 1734 1731 * @ext_nss_bw_capable: indicates whether or not the local transmitter 1735 1732 * (rate scaling algorithm) can deal with the new logic 1736 1733 * (dot11VHTExtendedNSSBWCapable) 1734 + * @max_vht_nss: current maximum NSS as advertised by the STA in 1735 + * operating mode notification, can be 0 in which case the 1736 + * capability data will be used to derive this (from MCS support) 1737 1737 * 1738 1738 * Due to the VHT Extended NSS Bandwidth Support, the maximum NSS can 1739 1739 * vary for a given BW/MCS. This function parses the data. ··· 1745 1739 */ 1746 1740 int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, 1747 1741 enum ieee80211_vht_chanwidth bw, 1748 - int mcs, bool ext_nss_bw_capable); 1742 + int mcs, bool ext_nss_bw_capable, 1743 + unsigned int max_vht_nss); 1749 1744 1750 1745 /* 802.11ax HE MAC capabilities */ 1751 1746 #define IEEE80211_HE_MAC_CAP0_HTC_HE 0x01 ··· 3329 3322 /* convert time units */ 3330 3323 #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) 3331 3324 #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) 3325 + 3326 + /* convert frequencies */ 3327 + #define MHZ_TO_KHZ(freq) ((freq) * 1000) 3328 + #define KHZ_TO_MHZ(freq) ((freq) / 1000) 3329 + 3330 + /* convert powers */ 3331 + #define DBI_TO_MBI(gain) ((gain) * 100) 3332 + #define MBI_TO_DBI(gain) ((gain) / 100) 3333 + #define DBM_TO_MBM(gain) ((gain) * 100) 3334 + #define MBM_TO_DBM(gain) ((gain) / 100) 3332 3335 3333 3336 /** 3334 3337 * ieee80211_action_contains_tpc - checks if the frame contains TPC element
+120 -14
include/net/cfg80211.h
··· 128 128 * with cfg80211. 129 129 * 130 130 * @center_freq: center frequency in MHz 131 + * @freq_offset: offset from @center_freq, in KHz 131 132 * @hw_value: hardware-specific value for the channel 132 133 * @flags: channel flags from &enum ieee80211_channel_flags. 133 134 * @orig_flags: channel flags at registration time, used by regulatory ··· 150 149 struct ieee80211_channel { 151 150 enum nl80211_band band; 152 151 u32 center_freq; 152 + u16 freq_offset; 153 153 u16 hw_value; 154 154 u32 flags; 155 155 int max_antenna_gain; ··· 619 617 * If edmg is requested (i.e. the .channels member is non-zero), 620 618 * chan will define the primary channel and all other 621 619 * parameters are ignored. 620 + * @freq1_offset: offset from @center_freq1, in KHz 622 621 */ 623 622 struct cfg80211_chan_def { 624 623 struct ieee80211_channel *chan; ··· 627 624 u32 center_freq1; 628 625 u32 center_freq2; 629 626 struct ieee80211_edmg edmg; 627 + u16 freq1_offset; 630 628 }; 631 629 632 630 /** ··· 717 713 return (chandef1->chan == chandef2->chan && 718 714 chandef1->width == chandef2->width && 719 715 chandef1->center_freq1 == chandef2->center_freq1 && 716 + chandef1->freq1_offset == chandef2->freq1_offset && 720 717 chandef1->center_freq2 == chandef2->center_freq2); 721 718 } 722 719 ··· 1059 1054 * @ht_required: stations must support HT 1060 1055 * @vht_required: stations must support VHT 1061 1056 * @twt_responder: Enable Target Wait Time 1057 + * @he_required: stations must support HE 1062 1058 * @flags: flags, as defined in enum cfg80211_ap_settings_flags 1063 1059 * @he_obss_pd: OBSS Packet Detection settings 1064 1060 * @he_bss_color: BSS Color settings ··· 1089 1083 const struct ieee80211_vht_cap *vht_cap; 1090 1084 const struct ieee80211_he_cap_elem *he_cap; 1091 1085 const struct ieee80211_he_operation *he_oper; 1092 - bool ht_required, vht_required; 1086 + bool ht_required, vht_required, he_required; 1093 1087 bool twt_responder; 1094 1088 u32 flags; 1095 1089 struct ieee80211_he_obss_pd he_obss_pd; ··· 3391 3385 }; 3392 3386 3393 3387 /** 3388 + * struct mgmt_frame_regs - management frame registrations data 3389 + * @global_stypes: bitmap of management frame subtypes registered 3390 + * for the entire device 3391 + * @interface_stypes: bitmap of management frame subtypes registered 3392 + * for the given interface 3393 + * @global_mcast_rx: mcast RX is needed globally for these subtypes 3394 + * @interface_mcast_stypes: mcast RX is needed on this interface 3395 + * for these subtypes 3396 + */ 3397 + struct mgmt_frame_regs { 3398 + u32 global_stypes, interface_stypes; 3399 + u32 global_mcast_stypes, interface_mcast_stypes; 3400 + }; 3401 + 3402 + /** 3394 3403 * struct cfg80211_ops - backend description for wireless configuration 3395 3404 * 3396 3405 * This struct is registered by fullmac card drivers and/or wireless stacks ··· 3629 3608 * The driver should not call cfg80211_sched_scan_stopped() for a requested 3630 3609 * stop (when this method returns 0). 3631 3610 * 3632 - * @mgmt_frame_register: Notify driver that a management frame type was 3633 - * registered. The callback is allowed to sleep. 3611 + * @update_mgmt_frame_registrations: Notify the driver that management frame 3612 + * registrations were updated. The callback is allowed to sleep. 3634 3613 * 3635 3614 * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. 3636 3615 * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may ··· 3953 3932 struct net_device *dev, 3954 3933 u32 rate, u32 pkts, u32 intvl); 3955 3934 3956 - void (*mgmt_frame_register)(struct wiphy *wiphy, 3957 - struct wireless_dev *wdev, 3958 - u16 frame_type, bool reg); 3935 + void (*update_mgmt_frame_registrations)(struct wiphy *wiphy, 3936 + struct wireless_dev *wdev, 3937 + struct mgmt_frame_regs *upd); 3959 3938 3960 3939 int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); 3961 3940 int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); ··· 5036 5015 * by cfg80211 on change_interface 5037 5016 * @mgmt_registrations: list of registrations for management frames 5038 5017 * @mgmt_registrations_lock: lock for the list 5018 + * @mgmt_registrations_update_wk: update work to defer from atomic context 5039 5019 * @mtx: mutex used to lock data in this struct, may be used by drivers 5040 5020 * and some API functions require it held 5041 5021 * @beacon_interval: beacon interval used on this device for transmitting ··· 5067 5045 * @pmsr_list: (private) peer measurement requests 5068 5046 * @pmsr_lock: (private) peer measurements requests/results lock 5069 5047 * @pmsr_free_wk: (private) peer measurements cleanup work 5048 + * @unprot_beacon_reported: (private) timestamp of last 5049 + * unprotected beacon report 5070 5050 */ 5071 5051 struct wireless_dev { 5072 5052 struct wiphy *wiphy; ··· 5082 5058 5083 5059 struct list_head mgmt_registrations; 5084 5060 spinlock_t mgmt_registrations_lock; 5061 + struct work_struct mgmt_registrations_update_wk; 5085 5062 5086 5063 struct mutex mtx; 5087 5064 ··· 5146 5121 struct list_head pmsr_list; 5147 5122 spinlock_t pmsr_lock; 5148 5123 struct work_struct pmsr_free_wk; 5124 + 5125 + unsigned long unprot_beacon_reported; 5149 5126 }; 5150 5127 5151 5128 static inline u8 *wdev_address(struct wireless_dev *wdev) ··· 5183 5156 */ 5184 5157 5185 5158 /** 5159 + * ieee80211_channel_equal - compare two struct ieee80211_channel 5160 + * 5161 + * @a: 1st struct ieee80211_channel 5162 + * @b: 2nd struct ieee80211_channel 5163 + * Return: true if center frequency of @a == @b 5164 + */ 5165 + static inline bool 5166 + ieee80211_channel_equal(struct ieee80211_channel *a, 5167 + struct ieee80211_channel *b) 5168 + { 5169 + return (a->center_freq == b->center_freq && 5170 + a->freq_offset == b->freq_offset); 5171 + } 5172 + 5173 + /** 5174 + * ieee80211_channel_to_khz - convert ieee80211_channel to frequency in KHz 5175 + * @chan: struct ieee80211_channel to convert 5176 + * Return: The corresponding frequency (in KHz) 5177 + */ 5178 + static inline u32 5179 + ieee80211_channel_to_khz(const struct ieee80211_channel *chan) 5180 + { 5181 + return MHZ_TO_KHZ(chan->center_freq) + chan->freq_offset; 5182 + } 5183 + 5184 + /** 5185 + * ieee80211_channel_to_freq_khz - convert channel number to frequency 5186 + * @chan: channel number 5187 + * @band: band, necessary due to channel number overlap 5188 + * Return: The corresponding frequency (in KHz), or 0 if the conversion failed. 5189 + */ 5190 + u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band); 5191 + 5192 + /** 5186 5193 * ieee80211_channel_to_frequency - convert channel number to frequency 5187 5194 * @chan: channel number 5188 5195 * @band: band, necessary due to channel number overlap 5189 5196 * Return: The corresponding frequency (in MHz), or 0 if the conversion failed. 5190 5197 */ 5191 - int ieee80211_channel_to_frequency(int chan, enum nl80211_band band); 5198 + static inline int 5199 + ieee80211_channel_to_frequency(int chan, enum nl80211_band band) 5200 + { 5201 + return KHZ_TO_MHZ(ieee80211_channel_to_freq_khz(chan, band)); 5202 + } 5203 + 5204 + /** 5205 + * ieee80211_freq_khz_to_channel - convert frequency to channel number 5206 + * @freq: center frequency in KHz 5207 + * Return: The corresponding channel, or 0 if the conversion failed. 5208 + */ 5209 + int ieee80211_freq_khz_to_channel(u32 freq); 5192 5210 5193 5211 /** 5194 5212 * ieee80211_frequency_to_channel - convert frequency to channel number 5195 - * @freq: center frequency 5213 + * @freq: center frequency in MHz 5196 5214 * Return: The corresponding channel, or 0 if the conversion failed. 5197 5215 */ 5198 - int ieee80211_frequency_to_channel(int freq); 5216 + static inline int 5217 + ieee80211_frequency_to_channel(int freq) 5218 + { 5219 + return ieee80211_freq_khz_to_channel(MHZ_TO_KHZ(freq)); 5220 + } 5221 + 5222 + /** 5223 + * ieee80211_get_channel_khz - get channel struct from wiphy for specified 5224 + * frequency 5225 + * @wiphy: the struct wiphy to get the channel for 5226 + * @freq: the center frequency (in KHz) of the channel 5227 + * Return: The channel struct from @wiphy at @freq. 5228 + */ 5229 + struct ieee80211_channel * 5230 + ieee80211_get_channel_khz(struct wiphy *wiphy, u32 freq); 5199 5231 5200 5232 /** 5201 5233 * ieee80211_get_channel - get channel struct from wiphy for specified frequency 5202 5234 * 5203 5235 * @wiphy: the struct wiphy to get the channel for 5204 - * @freq: the center frequency of the channel 5205 - * 5236 + * @freq: the center frequency (in MHz) of the channel 5206 5237 * Return: The channel struct from @wiphy at @freq. 5207 5238 */ 5208 - struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq); 5239 + static inline struct ieee80211_channel * 5240 + ieee80211_get_channel(struct wiphy *wiphy, int freq) 5241 + { 5242 + return ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(freq)); 5243 + } 5209 5244 5210 5245 /** 5211 5246 * ieee80211_get_response_rate - get basic rate for a given rate ··· 6224 6135 /** 6225 6136 * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame 6226 6137 * @dev: network device 6227 - * @buf: deauthentication frame (header + body) 6138 + * @buf: received management frame (header + body) 6228 6139 * @len: length of the frame data 6229 6140 * 6230 6141 * This function is called whenever a received deauthentication or dissassoc 6231 6142 * frame has been dropped in station mode because of MFP being used but the 6232 - * frame was not protected. This function may sleep. 6143 + * frame was not protected. This is also used to notify reception of a Beacon 6144 + * frame that was dropped because it did not include a valid MME MIC while 6145 + * beacon protection was enabled (BIGTK configured in station mode). 6146 + * 6147 + * This function may sleep. 6233 6148 */ 6234 6149 void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, 6235 6150 const u8 *buf, size_t len); ··· 7294 7201 */ 7295 7202 bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, 7296 7203 u8 *op_class); 7204 + 7205 + /** 7206 + * ieee80211_chandef_to_khz - convert chandef to frequency in KHz 7207 + * 7208 + * @chandef: the chandef to convert 7209 + * 7210 + * Returns the center frequency of chandef (1st segment) in KHz. 7211 + */ 7212 + static inline u32 7213 + ieee80211_chandef_to_khz(const struct cfg80211_chan_def *chandef) 7214 + { 7215 + return MHZ_TO_KHZ(chandef->center_freq1) + chandef->freq1_offset; 7216 + } 7297 7217 7298 7218 /* 7299 7219 * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
+30 -5
include/net/mac80211.h
··· 508 508 * mode only, set if the AP advertises TWT responder role) 509 509 * @twt_responder: does this BSS support TWT requester (relevant for managed 510 510 * mode only, set if the AP advertises TWT responder role) 511 + * @twt_protected: does this BSS support protected TWT frames 511 512 * @assoc: association status 512 513 * @ibss_joined: indicates whether this station is part of an IBSS 513 514 * or not ··· 604 603 * nontransmitted BSSIDs 605 604 * @profile_periodicity: the least number of beacon frames need to be received 606 605 * in order to discover all the nontransmitted BSSIDs in the set. 607 - * @he_operation: HE operation information of the AP we are connected to 606 + * @he_oper: HE operation information of the AP we are connected to 608 607 * @he_obss_pd: OBSS Packet Detection parameters. 609 608 * @he_bss_color: BSS coloring settings, if BSS supports HE 610 609 */ ··· 619 618 bool he_support; 620 619 bool twt_requester; 621 620 bool twt_responder; 621 + bool twt_protected; 622 622 /* association related data */ 623 623 bool assoc, ibss_joined; 624 624 bool ibss_creator; ··· 668 666 u8 bssid_indicator; 669 667 bool ema_ap; 670 668 u8 profile_periodicity; 671 - struct ieee80211_he_operation he_operation; 669 + struct { 670 + u32 params; 671 + u16 nss_set; 672 + } he_oper; 672 673 struct ieee80211_he_obss_pd he_obss_pd; 673 674 struct cfg80211_he_bss_color he_bss_color; 674 675 }; ··· 823 818 * @IEEE80211_TX_CTRL_AMSDU: This frame is an A-MSDU frame 824 819 * @IEEE80211_TX_CTRL_FAST_XMIT: This frame is going through the fast_xmit path 825 820 * @IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP: This frame skips mesh path lookup 821 + * @IEEE80211_TX_CTRL_HW_80211_ENCAP: This frame uses hardware encapsulation 822 + * (header conversion) 826 823 * 827 824 * These flags are used in tx_info->control.flags. 828 825 */ ··· 1340 1333 * @freq: frequency the radio was tuned to when receiving this frame, in MHz 1341 1334 * This field must be set for management frames, but isn't strictly needed 1342 1335 * for data (other) frames - for those it only affects radiotap reporting. 1336 + * @freq_offset: @freq has a positive offset of 500Khz. 1343 1337 * @signal: signal strength when receiving this frame, either in dBm, in dB or 1344 1338 * unspecified depending on the hardware capabilities flags 1345 1339 * @IEEE80211_HW_SIGNAL_* ··· 1371 1363 u32 device_timestamp; 1372 1364 u32 ampdu_reference; 1373 1365 u32 flag; 1374 - u16 freq; 1366 + u16 freq: 13, freq_offset: 1; 1375 1367 u8 enc_flags; 1376 1368 u8 encoding:2, bw:3, he_ru:3; 1377 1369 u8 he_gi:2, he_dcm:1; ··· 1386 1378 u8 ampdu_delimiter_crc; 1387 1379 u8 zero_length_psdu_type; 1388 1380 }; 1381 + 1382 + static inline u32 1383 + ieee80211_rx_status_to_khz(struct ieee80211_rx_status *rx_status) 1384 + { 1385 + return MHZ_TO_KHZ(rx_status->freq) + 1386 + (rx_status->freq_offset ? 500 : 0); 1387 + } 1389 1388 1390 1389 /** 1391 1390 * struct ieee80211_vendor_radiotap - vendor radiotap data information ··· 1635 1620 * monitor interface (if that is requested.) 1636 1621 * @probe_req_reg: probe requests should be reported to mac80211 for this 1637 1622 * interface. 1623 + * @rx_mcast_action_reg: multicast Action frames should be reported to mac80211 1624 + * for this interface. 1638 1625 * @drv_priv: data area for driver use, will always be aligned to 1639 1626 * sizeof(void \*). 1640 1627 * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) ··· 1664 1647 struct dentry *debugfs_dir; 1665 1648 #endif 1666 1649 1667 - unsigned int probe_req_reg; 1650 + bool probe_req_reg; 1651 + bool rx_mcast_action_reg; 1668 1652 1669 1653 bool txqs_stopped[IEEE80211_NUM_ACS]; 1670 1654 ··· 3109 3091 * @FIF_PSPOLL: pass PS Poll frames 3110 3092 * 3111 3093 * @FIF_PROBE_REQ: pass probe request frames 3094 + * 3095 + * @FIF_MCAST_ACTION: pass multicast Action frames 3112 3096 */ 3113 3097 enum ieee80211_filter_flags { 3114 3098 FIF_ALLMULTI = 1<<1, ··· 3121 3101 FIF_OTHER_BSS = 1<<6, 3122 3102 FIF_PSPOLL = 1<<7, 3123 3103 FIF_PROBE_REQ = 1<<8, 3104 + FIF_MCAST_ACTION = 1<<9, 3124 3105 }; 3125 3106 3126 3107 /** ··· 3138 3117 * @IEEE80211_AMPDU_RX_START: start RX aggregation 3139 3118 * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation 3140 3119 * @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either 3141 - * call ieee80211_start_tx_ba_cb_irqsafe() or return the special 3120 + * call ieee80211_start_tx_ba_cb_irqsafe() or 3121 + * call ieee80211_start_tx_ba_cb_irqsafe() with status 3122 + * %IEEE80211_AMPDU_TX_START_DELAY_ADDBA to delay addba after 3123 + * ieee80211_start_tx_ba_cb_irqsafe is called, or just return the special 3142 3124 * status %IEEE80211_AMPDU_TX_START_IMMEDIATE. 3143 3125 * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational 3144 3126 * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting ··· 3167 3143 }; 3168 3144 3169 3145 #define IEEE80211_AMPDU_TX_START_IMMEDIATE 1 3146 + #define IEEE80211_AMPDU_TX_START_DELAY_ADDBA 2 3170 3147 3171 3148 /** 3172 3149 * struct ieee80211_ampdu_params - AMPDU action parameters
-7
include/net/regulatory.h
··· 231 231 struct ieee80211_reg_rule reg_rules[]; 232 232 }; 233 233 234 - #define MHZ_TO_KHZ(freq) ((freq) * 1000) 235 - #define KHZ_TO_MHZ(freq) ((freq) / 1000) 236 - #define DBI_TO_MBI(gain) ((gain) * 100) 237 - #define MBI_TO_DBI(gain) ((gain) / 100) 238 - #define DBM_TO_MBM(gain) ((gain) * 100) 239 - #define MBM_TO_DBM(gain) ((gain) / 100) 240 - 241 234 #define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ 242 235 { \ 243 236 .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
+23
include/uapi/linux/nl80211.h
··· 687 687 * four bytes for vendor frames including the OUI. The registration 688 688 * cannot be dropped, but is removed automatically when the netlink 689 689 * socket is closed. Multiple registrations can be made. 690 + * The %NL80211_ATTR_RECEIVE_MULTICAST flag attribute can be given if 691 + * %NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS is available, in which 692 + * case the registration can also be modified to include/exclude the 693 + * flag, rather than requiring unregistration to change it. 690 694 * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for 691 695 * backward compatibility 692 696 * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This ··· 1155 1151 * @NL80211_CMD_SET_TID_CONFIG: Data frame TID specific configuration 1156 1152 * is passed using %NL80211_ATTR_TID_CONFIG attribute. 1157 1153 * 1154 + * @NL80211_CMD_UNPROT_BEACON: Unprotected or incorrectly protected Beacon 1155 + * frame. This event is used to indicate that a received Beacon frame was 1156 + * dropped because it did not include a valid MME MIC while beacon 1157 + * protection was enabled (BIGTK configured in station mode). 1158 + * 1158 1159 * @NL80211_CMD_MAX: highest used command number 1159 1160 * @__NL80211_CMD_AFTER_LAST: internal use 1160 1161 */ ··· 1385 1376 NL80211_CMD_PROBE_MESH_LINK, 1386 1377 1387 1378 NL80211_CMD_SET_TID_CONFIG, 1379 + 1380 + NL80211_CMD_UNPROT_BEACON, 1388 1381 1389 1382 /* add new commands above here */ 1390 1383 ··· 2481 2470 * no roaming occurs between the reauth threshold and PMK expiration, 2482 2471 * disassociation is still forced. 2483 2472 * 2473 + * @NL80211_ATTR_RECEIVE_MULTICAST: multicast flag for the 2474 + * %NL80211_CMD_REGISTER_FRAME command, see the description there. 2475 + * 2484 2476 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2485 2477 * @NL80211_ATTR_MAX: highest attribute number currently defined 2486 2478 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 2958 2944 2959 2945 NL80211_ATTR_PMK_LIFETIME, 2960 2946 NL80211_ATTR_PMK_REAUTH_THRESHOLD, 2947 + 2948 + NL80211_ATTR_RECEIVE_MULTICAST, 2961 2949 2962 2950 /* add attributes here, update the policy in nl80211.c */ 2963 2951 ··· 5690 5674 * 5691 5675 * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection 5692 5676 * and can receive key configuration for BIGTK using key indexes 6 and 7. 5677 + * @NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT: The driver supports Beacon 5678 + * protection as a client only and cannot transmit protected beacons. 5693 5679 * 5694 5680 * @NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH: The driver can disable the 5695 5681 * forwarding of preauth frames over the control port. They are then ··· 5701 5683 * 5702 5684 * @NL80211_EXT_FEATURE_DEL_IBSS_STA: The driver supports removing stations 5703 5685 * in IBSS mode, essentially by dropping their state. 5686 + * 5687 + * @NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS: management frame registrations 5688 + * are possible for multicast frames and those will be reported properly. 5704 5689 * 5705 5690 * @NUM_NL80211_EXT_FEATURES: number of extended features. 5706 5691 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. ··· 5756 5735 NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH, 5757 5736 NL80211_EXT_FEATURE_PROTECTED_TWT, 5758 5737 NL80211_EXT_FEATURE_DEL_IBSS_STA, 5738 + NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS, 5739 + NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT, 5759 5740 5760 5741 /* add new features before the definition below */ 5761 5742 NUM_NL80211_EXT_FEATURES,
+79 -58
net/mac80211/agg-tx.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 - 2019 Intel Corporation 12 + * Copyright (C) 2018 - 2020 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/ieee80211.h> ··· 448 448 ieee80211_stop_tx_ba_session(&sta->sta, tid); 449 449 } 450 450 451 - void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 451 + static void ieee80211_send_addba_with_timeout(struct sta_info *sta, 452 + struct tid_ampdu_tx *tid_tx) 452 453 { 453 - struct tid_ampdu_tx *tid_tx; 454 - struct ieee80211_local *local = sta->local; 455 454 struct ieee80211_sub_if_data *sdata = sta->sdata; 456 - struct ieee80211_ampdu_params params = { 457 - .sta = &sta->sta, 458 - .action = IEEE80211_AMPDU_TX_START, 459 - .tid = tid, 460 - .buf_size = 0, 461 - .amsdu = false, 462 - .timeout = 0, 463 - }; 464 - int ret; 455 + struct ieee80211_local *local = sta->local; 456 + u8 tid = tid_tx->tid; 465 457 u16 buf_size; 466 - 467 - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 468 - 469 - /* 470 - * Start queuing up packets for this aggregation session. 471 - * We're going to release them once the driver is OK with 472 - * that. 473 - */ 474 - clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 475 - 476 - ieee80211_agg_stop_txq(sta, tid); 477 - 478 - /* 479 - * Make sure no packets are being processed. This ensures that 480 - * we have a valid starting sequence number and that in-flight 481 - * packets have been flushed out and no packets for this TID 482 - * will go into the driver during the ampdu_action call. 483 - */ 484 - synchronize_net(); 485 - 486 - params.ssn = sta->tid_seq[tid] >> 4; 487 - ret = drv_ampdu_action(local, sdata, &params); 488 - if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) { 489 - /* 490 - * We didn't send the request yet, so don't need to check 491 - * here if we already got a response, just mark as driver 492 - * ready immediately. 493 - */ 494 - set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); 495 - } else if (ret) { 496 - ht_dbg(sdata, 497 - "BA request denied - HW unavailable for %pM tid %d\n", 498 - sta->sta.addr, tid); 499 - spin_lock_bh(&sta->lock); 500 - ieee80211_agg_splice_packets(sdata, tid_tx, tid); 501 - ieee80211_assign_tid_tx(sta, tid, NULL); 502 - ieee80211_agg_splice_finish(sdata, tid); 503 - spin_unlock_bh(&sta->lock); 504 - 505 - ieee80211_agg_start_txq(sta, tid, false); 506 - 507 - kfree_rcu(tid_tx, rcu_head); 508 - return; 509 - } 510 458 511 459 /* activate the timer for the recipient's addBA response */ 512 460 mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); ··· 480 532 481 533 /* send AddBA request */ 482 534 ieee80211_send_addba_request(sdata, sta->sta.addr, tid, 483 - tid_tx->dialog_token, params.ssn, 535 + tid_tx->dialog_token, 536 + sta->tid_seq[tid] >> 4, 484 537 buf_size, tid_tx->timeout); 538 + 539 + WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)); 540 + } 541 + 542 + void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 543 + { 544 + struct tid_ampdu_tx *tid_tx; 545 + struct ieee80211_local *local = sta->local; 546 + struct ieee80211_sub_if_data *sdata = sta->sdata; 547 + struct ieee80211_ampdu_params params = { 548 + .sta = &sta->sta, 549 + .action = IEEE80211_AMPDU_TX_START, 550 + .tid = tid, 551 + .buf_size = 0, 552 + .amsdu = false, 553 + .timeout = 0, 554 + }; 555 + int ret; 556 + 557 + tid_tx = rcu_dereference_protected_tid_tx(sta, tid); 558 + 559 + /* 560 + * Start queuing up packets for this aggregation session. 561 + * We're going to release them once the driver is OK with 562 + * that. 563 + */ 564 + clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 565 + 566 + ieee80211_agg_stop_txq(sta, tid); 567 + 568 + /* 569 + * Make sure no packets are being processed. This ensures that 570 + * we have a valid starting sequence number and that in-flight 571 + * packets have been flushed out and no packets for this TID 572 + * will go into the driver during the ampdu_action call. 573 + */ 574 + synchronize_net(); 575 + 576 + params.ssn = sta->tid_seq[tid] >> 4; 577 + ret = drv_ampdu_action(local, sdata, &params); 578 + if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) { 579 + return; 580 + } else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) { 581 + /* 582 + * We didn't send the request yet, so don't need to check 583 + * here if we already got a response, just mark as driver 584 + * ready immediately. 585 + */ 586 + set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); 587 + } else if (ret) { 588 + ht_dbg(sdata, 589 + "BA request denied - HW unavailable for %pM tid %d\n", 590 + sta->sta.addr, tid); 591 + spin_lock_bh(&sta->lock); 592 + ieee80211_agg_splice_packets(sdata, tid_tx, tid); 593 + ieee80211_assign_tid_tx(sta, tid, NULL); 594 + ieee80211_agg_splice_finish(sdata, tid); 595 + spin_unlock_bh(&sta->lock); 596 + 597 + ieee80211_agg_start_txq(sta, tid, false); 598 + 599 + kfree_rcu(tid_tx, rcu_head); 600 + return; 601 + } 602 + 603 + ieee80211_send_addba_with_timeout(sta, tid_tx); 485 604 } 486 605 487 606 /* ··· 768 753 769 754 if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) 770 755 return; 756 + 757 + if (!test_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)) { 758 + ieee80211_send_addba_with_timeout(sta, tid_tx); 759 + /* RESPONSE_RECEIVED state whould trigger the flow again */ 760 + return; 761 + } 771 762 772 763 if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) 773 764 ieee80211_agg_tx_operational(local, sta, tid);
+60 -27
net/mac80211/cfg.c
··· 994 994 BSS_CHANGED_TWT | 995 995 BSS_CHANGED_HE_OBSS_PD | 996 996 BSS_CHANGED_HE_BSS_COLOR; 997 - int err; 997 + int i, err; 998 998 int prev_beacon_int; 999 999 1000 1000 old = sdata_dereference(sdata->u.ap.beacon, sdata); ··· 1084 1084 if (params->p2p_opp_ps) 1085 1085 sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= 1086 1086 IEEE80211_P2P_OPPPS_ENABLE_BIT; 1087 + 1088 + sdata->beacon_rate_set = false; 1089 + if (wiphy_ext_feature_isset(local->hw.wiphy, 1090 + NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) { 1091 + for (i = 0; i < NUM_NL80211_BANDS; i++) { 1092 + sdata->beacon_rateidx_mask[i] = 1093 + params->beacon_rate.control[i].legacy; 1094 + if (sdata->beacon_rateidx_mask[i]) 1095 + sdata->beacon_rate_set = true; 1096 + } 1097 + } 1087 1098 1088 1099 err = ieee80211_assign_beacon(sdata, &params->beacon, NULL); 1089 1100 if (err < 0) { ··· 1200 1189 ieee80211_free_keys(sdata, true); 1201 1190 1202 1191 sdata->vif.bss_conf.enable_beacon = false; 1192 + sdata->beacon_rate_set = false; 1203 1193 sdata->vif.bss_conf.ssid_len = 0; 1204 1194 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 1205 1195 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); ··· 1961 1949 const u8 *old_ie; 1962 1950 struct ieee80211_sub_if_data *sdata = container_of(ifmsh, 1963 1951 struct ieee80211_sub_if_data, u.mesh); 1952 + int i; 1964 1953 1965 1954 /* allocate information elements */ 1966 1955 new_ie = NULL; ··· 1999 1986 2000 1987 sdata->vif.bss_conf.beacon_int = setup->beacon_interval; 2001 1988 sdata->vif.bss_conf.dtim_period = setup->dtim_period; 1989 + 1990 + sdata->beacon_rate_set = false; 1991 + if (wiphy_ext_feature_isset(sdata->local->hw.wiphy, 1992 + NL80211_EXT_FEATURE_BEACON_RATE_LEGACY)) { 1993 + for (i = 0; i < NUM_NL80211_BANDS; i++) { 1994 + sdata->beacon_rateidx_mask[i] = 1995 + setup->beacon_rate.control[i].legacy; 1996 + if (sdata->beacon_rateidx_mask[i]) 1997 + sdata->beacon_rate_set = true; 1998 + } 1999 + } 2002 2000 2003 2001 return 0; 2004 2002 } ··· 3311 3287 goto out; 3312 3288 } 3313 3289 3290 + if (params->chandef.chan->freq_offset) { 3291 + /* this may work, but is untested */ 3292 + err = -EOPNOTSUPP; 3293 + goto out; 3294 + } 3295 + 3314 3296 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 3315 3297 3316 3298 ch_switch.timestamp = 0; ··· 3428 3398 return 0; 3429 3399 } 3430 3400 3431 - static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, 3401 + static void 3402 + ieee80211_update_mgmt_frame_registrations(struct wiphy *wiphy, 3432 3403 struct wireless_dev *wdev, 3433 - u16 frame_type, bool reg) 3404 + struct mgmt_frame_regs *upd) 3434 3405 { 3435 3406 struct ieee80211_local *local = wiphy_priv(wiphy); 3436 3407 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3408 + u32 preq_mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4); 3409 + u32 action_mask = BIT(IEEE80211_STYPE_ACTION >> 4); 3410 + bool global_change, intf_change; 3437 3411 3438 - switch (frame_type) { 3439 - case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 3440 - if (reg) { 3441 - local->probe_req_reg++; 3442 - sdata->vif.probe_req_reg++; 3443 - } else { 3444 - if (local->probe_req_reg) 3445 - local->probe_req_reg--; 3412 + global_change = 3413 + (local->probe_req_reg != !!(upd->global_stypes & preq_mask)) || 3414 + (local->rx_mcast_action_reg != 3415 + !!(upd->global_mcast_stypes & action_mask)); 3416 + local->probe_req_reg = upd->global_stypes & preq_mask; 3417 + local->rx_mcast_action_reg = upd->global_mcast_stypes & action_mask; 3446 3418 3447 - if (sdata->vif.probe_req_reg) 3448 - sdata->vif.probe_req_reg--; 3449 - } 3419 + intf_change = (sdata->vif.probe_req_reg != 3420 + !!(upd->interface_stypes & preq_mask)) || 3421 + (sdata->vif.rx_mcast_action_reg != 3422 + !!(upd->interface_mcast_stypes & action_mask)); 3423 + sdata->vif.probe_req_reg = upd->interface_stypes & preq_mask; 3424 + sdata->vif.rx_mcast_action_reg = 3425 + upd->interface_mcast_stypes & action_mask; 3450 3426 3451 - if (!local->open_count) 3452 - break; 3427 + if (!local->open_count) 3428 + return; 3453 3429 3454 - if (sdata->vif.probe_req_reg == 1) 3455 - drv_config_iface_filter(local, sdata, FIF_PROBE_REQ, 3456 - FIF_PROBE_REQ); 3457 - else if (sdata->vif.probe_req_reg == 0) 3458 - drv_config_iface_filter(local, sdata, 0, 3459 - FIF_PROBE_REQ); 3430 + if (intf_change && ieee80211_sdata_running(sdata)) 3431 + drv_config_iface_filter(local, sdata, 3432 + sdata->vif.probe_req_reg ? 3433 + FIF_PROBE_REQ : 0, 3434 + FIF_PROBE_REQ); 3460 3435 3436 + if (global_change) 3461 3437 ieee80211_configure_filter(local); 3462 - break; 3463 - default: 3464 - break; 3465 - } 3466 3438 } 3467 3439 3468 3440 static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) ··· 4049 4017 .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait, 4050 4018 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, 4051 4019 .set_cqm_rssi_range_config = ieee80211_set_cqm_rssi_range_config, 4052 - .mgmt_frame_register = ieee80211_mgmt_frame_register, 4020 + .update_mgmt_frame_registrations = 4021 + ieee80211_update_mgmt_frame_registrations, 4053 4022 .set_antenna = ieee80211_set_antenna, 4054 4023 .get_antenna = ieee80211_get_antenna, 4055 4024 .set_rekey_data = ieee80211_set_rekey_data,
+1
net/mac80211/chan.c
··· 533 533 struct cfg80211_chan_def *chandef = &local->_oper_chandef; 534 534 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 535 535 chandef->center_freq1 = chandef->chan->center_freq; 536 + chandef->freq1_offset = chandef->chan->freq_offset; 536 537 chandef->center_freq2 = 0; 537 538 538 539 /* NOTE: Disabling radar is only valid here for
+1 -1
net/mac80211/debugfs_netdev.c
··· 236 236 237 237 /* STA attributes */ 238 238 IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 239 - IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 239 + IEEE80211_IF_FILE(aid, vif.bss_conf.aid, DEC); 240 240 IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS); 241 241 242 242 static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
+5 -8
net/mac80211/he.c
··· 57 57 58 58 void 59 59 ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif, 60 - const struct ieee80211_he_operation *he_op_ie_elem) 60 + const struct ieee80211_he_operation *he_op_ie) 61 61 { 62 - struct ieee80211_he_operation *he_operation = 63 - &vif->bss_conf.he_operation; 64 - 65 - if (!he_op_ie_elem) { 66 - memset(he_operation, 0, sizeof(*he_operation)); 62 + memset(&vif->bss_conf.he_oper, 0, sizeof(vif->bss_conf.he_oper)); 63 + if (!he_op_ie) 67 64 return; 68 - } 69 65 70 - vif->bss_conf.he_operation = *he_op_ie_elem; 66 + vif->bss_conf.he_oper.params = __le32_to_cpu(he_op_ie->he_oper_params); 67 + vif->bss_conf.he_oper.nss_set = __le16_to_cpu(he_op_ie->he_mcs_nss_set); 71 68 } 72 69 73 70 void
+5
net/mac80211/ibss.c
··· 1758 1758 int i; 1759 1759 int ret; 1760 1760 1761 + if (params->chandef.chan->freq_offset) { 1762 + /* this may work, but is untested */ 1763 + return -EOPNOTSUPP; 1764 + } 1765 + 1761 1766 ret = cfg80211_chandef_dfs_required(local->hw.wiphy, 1762 1767 &params->chandef, 1763 1768 sdata->wdev.iftype);
+6 -3
net/mac80211/ieee80211_i.h
··· 450 450 451 451 u8 bssid[ETH_ALEN] __aligned(2); 452 452 453 - u16 aid; 454 - 455 453 bool powersave; /* powersave requested for this iface */ 456 454 bool broken_ap; /* AP is broken -- turn off powersave */ 457 455 bool have_beacon; ··· 962 964 bool rc_has_vht_mcs_mask[NUM_NL80211_BANDS]; 963 965 u16 rc_rateidx_vht_mcs_mask[NUM_NL80211_BANDS][NL80211_VHT_NSS_MAX]; 964 966 967 + /* Beacon frame (non-MCS) rate (as a bitmap) */ 968 + u32 beacon_rateidx_mask[NUM_NL80211_BANDS]; 969 + bool beacon_rate_set; 970 + 965 971 union { 966 972 struct ieee80211_if_ap ap; 967 973 struct ieee80211_if_wds wds; ··· 1171 1169 /* number of interfaces with corresponding FIF_ flags */ 1172 1170 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, 1173 1171 fif_probe_req; 1174 - int probe_req_reg; 1172 + bool probe_req_reg; 1173 + bool rx_mcast_action_reg; 1175 1174 unsigned int filter_flags; /* FIF_* */ 1176 1175 1177 1176 bool wiphy_ciphers_allocated;
+5
net/mac80211/iface.c
··· 644 644 local->fif_probe_req++; 645 645 } 646 646 647 + if (sdata->vif.probe_req_reg) 648 + drv_config_iface_filter(local, sdata, 649 + FIF_PROBE_REQ, 650 + FIF_PROBE_REQ); 651 + 647 652 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 648 653 sdata->vif.type != NL80211_IFTYPE_NAN) 649 654 changed |= ieee80211_reset_erp_info(sdata);
+8 -3
net/mac80211/main.c
··· 64 64 if (local->fif_pspoll) 65 65 new_flags |= FIF_PSPOLL; 66 66 67 + if (local->rx_mcast_action_reg) 68 + new_flags |= FIF_MCAST_ACTION; 69 + 67 70 spin_lock_bh(&local->filter_lock); 68 71 changed_flags = local->filter_flags ^ new_flags; 69 72 ··· 107 104 chandef.chan = local->tmp_channel; 108 105 chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 109 106 chandef.center_freq1 = chandef.chan->center_freq; 107 + chandef.freq1_offset = chandef.chan->freq_offset; 110 108 } else 111 109 chandef = local->_oper_chandef; 112 110 113 111 WARN(!cfg80211_chandef_valid(&chandef), 114 - "control:%d MHz width:%d center: %d/%d MHz", 115 - chandef.chan->center_freq, chandef.width, 116 - chandef.center_freq1, chandef.center_freq2); 112 + "control:%d.%03d MHz width:%d center: %d.%03d/%d MHz", 113 + chandef.chan->center_freq, chandef.chan->freq_offset, 114 + chandef.width, chandef.center_freq1, chandef.freq1_offset, 115 + chandef.center_freq2); 117 116 118 117 if (!cfg80211_chandef_identical(&chandef, &local->_oper_chandef)) 119 118 local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
+1
net/mac80211/mesh.c
··· 994 994 /* stop the beacon */ 995 995 ifmsh->mesh_id_len = 0; 996 996 sdata->vif.bss_conf.enable_beacon = false; 997 + sdata->beacon_rate_set = false; 997 998 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 998 999 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 999 1000
+47 -15
net/mac80211/mlme.c
··· 162 162 chandef->chan = channel; 163 163 chandef->width = NL80211_CHAN_WIDTH_20_NOHT; 164 164 chandef->center_freq1 = channel->center_freq; 165 + chandef->freq1_offset = channel->freq_offset; 165 166 166 167 if (!ht_oper || !sta_ht_cap.ht_supported) { 167 168 ret = IEEE80211_STA_DISABLE_HT | ··· 397 396 return 0; 398 397 399 398 sdata_info(sdata, 400 - "AP %pM changed bandwidth, new config is %d MHz, width %d (%d/%d MHz)\n", 401 - ifmgd->bssid, chandef.chan->center_freq, chandef.width, 402 - chandef.center_freq1, chandef.center_freq2); 399 + "AP %pM changed bandwidth, new config is %d.%03d MHz, " 400 + "width %d (%d.%03d/%d MHz)\n", 401 + ifmgd->bssid, chandef.chan->center_freq, 402 + chandef.chan->freq_offset, chandef.width, 403 + chandef.center_freq1, chandef.freq1_offset, 404 + chandef.center_freq2); 403 405 404 406 if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | 405 407 IEEE80211_STA_DISABLE_VHT | ··· 1368 1364 if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, 1369 1365 IEEE80211_CHAN_DISABLED)) { 1370 1366 sdata_info(sdata, 1371 - "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", 1367 + "AP %pM switches to unsupported channel " 1368 + "(%d.%03d MHz, width:%d, CF1/2: %d.%03d/%d MHz), " 1369 + "disconnecting\n", 1372 1370 ifmgd->associated->bssid, 1373 1371 csa_ie.chandef.chan->center_freq, 1372 + csa_ie.chandef.chan->freq_offset, 1374 1373 csa_ie.chandef.width, csa_ie.chandef.center_freq1, 1374 + csa_ie.chandef.freq1_offset, 1375 1375 csa_ie.chandef.center_freq2); 1376 1376 ieee80211_queue_work(&local->hw, 1377 1377 &ifmgd->csa_connection_drop_work); ··· 2956 2948 } 2957 2949 2958 2950 if (status_code != WLAN_STATUS_SUCCESS) { 2951 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2952 + 2953 + if (auth_alg == WLAN_AUTH_SAE && 2954 + status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED) 2955 + return; 2956 + 2959 2957 sdata_info(sdata, "%pM denied authentication (status %d)\n", 2960 2958 mgmt->sa, status_code); 2961 2959 ieee80211_destroy_auth_data(sdata, false); 2962 - cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2963 2960 event.u.mlme.status = MLME_DENIED; 2964 2961 event.u.mlme.reason = status_code; 2965 2962 drv_event_callback(sdata->local, sdata, &event); ··· 3162 3149 *have_higher_than_11mbit = true; 3163 3150 3164 3151 /* 3165 - * Skip HT and VHT BSS membership selectors since they're not 3166 - * rates. 3152 + * Skip HT, VHT and HE BSS membership selectors since they're 3153 + * not rates. 3167 3154 * 3168 3155 * Note: Even though the membership selector and the basic 3169 3156 * rate flag share the same bit, they are not exactly 3170 3157 * the same. 3171 3158 */ 3172 3159 if (supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY) || 3173 - supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) 3160 + supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY) || 3161 + supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY)) 3174 3162 continue; 3175 3163 3176 3164 for (j = 0; j < sband->n_bitrates; j++) { ··· 3263 3249 return false; 3264 3250 } 3265 3251 3266 - ifmgd->aid = aid; 3252 + sdata->vif.bss_conf.aid = aid; 3267 3253 ifmgd->tdls_chan_switch_prohibited = 3268 3254 elems->ext_capab && elems->ext_capab_len >= 5 && 3269 3255 (elems->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED); ··· 3398 3384 sta); 3399 3385 3400 3386 bss_conf->he_support = sta->sta.he_cap.has_he; 3387 + if (elems->rsnx && elems->rsnx_len && 3388 + (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) && 3389 + wiphy_ext_feature_isset(local->hw.wiphy, 3390 + NL80211_EXT_FEATURE_PROTECTED_TWT)) 3391 + bss_conf->twt_protected = true; 3392 + else 3393 + bss_conf->twt_protected = false; 3394 + 3401 3395 changed |= ieee80211_recalc_twt_req(sdata, sta, elems); 3402 3396 } else { 3403 3397 bss_conf->he_support = false; 3404 3398 bss_conf->twt_requester = false; 3399 + bss_conf->twt_protected = false; 3405 3400 } 3406 3401 3407 3402 if (bss_conf->he_support) { ··· 3544 3521 bss_conf->protected_keep_alive = false; 3545 3522 } 3546 3523 3547 - /* set AID and assoc capability, 3524 + /* set assoc capability (AID was already set earlier), 3548 3525 * ieee80211_set_associated() will tell the driver */ 3549 - bss_conf->aid = aid; 3550 3526 bss_conf->assoc_capability = capab_info; 3551 3527 ieee80211_set_associated(sdata, cbss, changed); 3552 3528 ··· 3683 3661 3684 3662 sdata_assert_lock(sdata); 3685 3663 3686 - channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); 3664 + channel = ieee80211_get_channel_khz(local->hw.wiphy, 3665 + ieee80211_rx_status_to_khz(rx_status)); 3687 3666 if (!channel) 3688 3667 return; 3689 3668 ··· 3900 3877 return; 3901 3878 } 3902 3879 3903 - if (rx_status->freq != chanctx_conf->def.chan->center_freq) { 3880 + if (ieee80211_rx_status_to_khz(rx_status) != 3881 + ieee80211_channel_to_khz(chanctx_conf->def.chan)) { 3904 3882 rcu_read_unlock(); 3905 3883 return; 3906 3884 } ··· 3972 3948 mgmt->bssid, bssid); 3973 3949 3974 3950 if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && 3975 - ieee80211_check_tim(elems.tim, elems.tim_len, ifmgd->aid)) { 3951 + ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { 3976 3952 if (local->hw.conf.dynamic_ps_timeout > 0) { 3977 3953 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 3978 3954 local->hw.conf.flags &= ~IEEE80211_CONF_PS; ··· 5046 5022 * doesn't happen any more, but keep the workaround so 5047 5023 * in case some *other* APs are buggy in different ways 5048 5024 * we can connect -- with a warning. 5025 + * Allow this workaround only in case the AP provided at least 5026 + * one rate. 5049 5027 */ 5050 - if (!basic_rates && min_rate_index >= 0) { 5028 + if (min_rate_index < 0) { 5029 + sdata_info(sdata, 5030 + "No legacy rates in association response\n"); 5031 + 5032 + sta_info_free(local, new_sta); 5033 + return -EINVAL; 5034 + } else if (!basic_rates) { 5051 5035 sdata_info(sdata, 5052 5036 "No basic rates, using min rate instead\n"); 5053 5037 basic_rates = BIT(min_rate_index);
+4
net/mac80211/offchannel.c
··· 557 557 558 558 lockdep_assert_held(&local->mtx); 559 559 560 + if (channel->freq_offset) 561 + /* this may work, but is untested */ 562 + return -EOPNOTSUPP; 563 + 560 564 if (local->use_chanctx && !local->ops->remain_on_channel) 561 565 return -EOPNOTSUPP; 562 566
+2 -1
net/mac80211/rc80211_minstrel_ht.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 3 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org> 4 + * Copyright (C) 2019-2020 Intel Corporation 4 5 */ 5 6 #include <linux/netdevice.h> 6 7 #include <linux/types.h> ··· 491 490 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; 492 491 tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); 493 492 494 - if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) { 493 + if (tmp_cck_tp > tmp_mcs_tp) { 495 494 for(i = 0; i < MAX_THR_RATES; i++) { 496 495 minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], 497 496 tmp_mcs_tp_rate);
+15 -2
net/mac80211/rx.c
··· 412 412 pos++; 413 413 414 414 /* IEEE80211_RADIOTAP_CHANNEL */ 415 + /* TODO: frequency offset in KHz */ 415 416 put_unaligned_le16(status->freq, pos); 416 417 pos += 2; 417 418 if (status->bw == RATE_INFO_BW_10) ··· 1985 1984 1986 1985 if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || 1987 1986 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + 1988 - NUM_DEFAULT_BEACON_KEYS) 1987 + NUM_DEFAULT_BEACON_KEYS) { 1988 + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, 1989 + skb->data, 1990 + skb->len); 1989 1991 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 1992 + } 1990 1993 1991 1994 rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx); 1992 1995 if (!rx->key) ··· 2135 2130 2136 2131 /* either the frame has been decrypted or will be dropped */ 2137 2132 status->flag |= RX_FLAG_DECRYPTED; 2133 + 2134 + if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) 2135 + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, 2136 + skb->data, skb->len); 2138 2137 2139 2138 return result; 2140 2139 } ··· 2420 2411 return -EACCES; 2421 2412 } 2422 2413 if (unlikely(ieee80211_is_beacon(fc) && rx->key && 2423 - ieee80211_get_mmie_keyidx(rx->skb) < 0)) 2414 + ieee80211_get_mmie_keyidx(rx->skb) < 0)) { 2415 + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, 2416 + rx->skb->data, 2417 + rx->skb->len); 2424 2418 return -EACCES; 2419 + } 2425 2420 /* 2426 2421 * When using MFP, Action frames are not allowed prior to 2427 2422 * having configured keys.
+3 -1
net/mac80211/scan.c
··· 275 275 return; 276 276 } 277 277 278 - channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); 278 + channel = ieee80211_get_channel_khz(local->hw.wiphy, 279 + ieee80211_rx_status_to_khz(rx_status)); 279 280 280 281 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 281 282 return; ··· 897 896 898 897 local->scan_chandef.chan = chan; 899 898 local->scan_chandef.center_freq1 = chan->center_freq; 899 + local->scan_chandef.freq1_offset = chan->freq_offset; 900 900 local->scan_chandef.center_freq2 = 0; 901 901 switch (scan_req->scan_width) { 902 902 case NL80211_BSS_CHAN_WIDTH_5:
+4
net/mac80211/sta_info.h
··· 3 3 * Copyright 2002-2005, Devicescape Software, Inc. 4 4 * Copyright 2013-2014 Intel Mobile Communications GmbH 5 5 * Copyright(c) 2015-2017 Intel Deutschland GmbH 6 + * Copyright(c) 2020 Intel Corporation 6 7 */ 7 8 8 9 #ifndef STA_INFO_H ··· 69 68 * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP. 70 69 * @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX 71 70 * until pending frames are delivered 71 + * @WLAN_STA_USES_ENCRYPTION: This station was configured for encryption, 72 + * so drop all packets without a key later. 72 73 * 73 74 * @NUM_WLAN_STA_FLAGS: number of defined flags 74 75 */ ··· 119 116 #define HT_AGG_STATE_WANT_STOP 5 120 117 #define HT_AGG_STATE_START_CB 6 121 118 #define HT_AGG_STATE_STOP_CB 7 119 + #define HT_AGG_STATE_SENT_ADDBA 8 122 120 123 121 DECLARE_EWMA(avg_signal, 10, 8) 124 122 enum ieee80211_agg_stop_reason {
+5 -2
net/mac80211/tdls.c
··· 226 226 static void 227 227 ieee80211_tdls_add_aid(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) 228 228 { 229 - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 230 229 u8 *pos = skb_put(skb, 4); 231 230 232 231 *pos++ = WLAN_EID_AID; 233 232 *pos++ = 2; /* len */ 234 - put_unaligned_le16(ifmgd->aid, pos); 233 + put_unaligned_le16(sdata->vif.bss_conf.aid, pos); 235 234 } 236 235 237 236 /* translate numbering in the WMM parameter IE to the mac80211 notation */ ··· 1565 1566 struct sk_buff *skb = NULL; 1566 1567 u32 ch_sw_tm_ie; 1567 1568 int ret; 1569 + 1570 + if (chandef->chan->freq_offset) 1571 + /* this may work, but is untested */ 1572 + return -EOPNOTSUPP; 1568 1573 1569 1574 mutex_lock(&local->sta_mtx); 1570 1575 sta = sta_info_get(sdata, addr);
+33 -8
net/mac80211/trace.h
··· 37 37 #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" 38 38 39 39 #define CHANDEF_ENTRY __field(u32, control_freq) \ 40 + __field(u32, freq_offset) \ 40 41 __field(u32, chan_width) \ 41 42 __field(u32, center_freq1) \ 43 + __field(u32, freq1_offset) \ 42 44 __field(u32, center_freq2) 43 45 #define CHANDEF_ASSIGN(c) \ 44 46 __entry->control_freq = (c) ? ((c)->chan ? (c)->chan->center_freq : 0) : 0; \ 47 + __entry->freq_offset = (c) ? ((c)->chan ? (c)->chan->freq_offset : 0) : 0; \ 45 48 __entry->chan_width = (c) ? (c)->width : 0; \ 46 49 __entry->center_freq1 = (c) ? (c)->center_freq1 : 0; \ 50 + __entry->freq1_offset = (c) ? (c)->freq1_offset : 0; \ 47 51 __entry->center_freq2 = (c) ? (c)->center_freq2 : 0; 48 - #define CHANDEF_PR_FMT " control:%d MHz width:%d center: %d/%d MHz" 49 - #define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ 50 - __entry->center_freq1, __entry->center_freq2 52 + #define CHANDEF_PR_FMT " control:%d.%03d MHz width:%d center: %d.%03d/%d MHz" 53 + #define CHANDEF_PR_ARG __entry->control_freq, __entry->freq_offset, __entry->chan_width, \ 54 + __entry->center_freq1, __entry->freq1_offset, __entry->center_freq2 51 55 52 56 #define MIN_CHANDEF_ENTRY \ 53 57 __field(u32, min_control_freq) \ 58 + __field(u32, min_freq_offset) \ 54 59 __field(u32, min_chan_width) \ 55 60 __field(u32, min_center_freq1) \ 61 + __field(u32, min_freq1_offset) \ 56 62 __field(u32, min_center_freq2) 57 63 58 64 #define MIN_CHANDEF_ASSIGN(c) \ 59 65 __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0; \ 66 + __entry->min_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0; \ 60 67 __entry->min_chan_width = (c)->width; \ 61 68 __entry->min_center_freq1 = (c)->center_freq1; \ 69 + __entry->freq1_offset = (c)->freq1_offset; \ 62 70 __entry->min_center_freq2 = (c)->center_freq2; 63 - #define MIN_CHANDEF_PR_FMT " min_control:%d MHz min_width:%d min_center: %d/%d MHz" 64 - #define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_chan_width, \ 65 - __entry->min_center_freq1, __entry->min_center_freq2 71 + #define MIN_CHANDEF_PR_FMT " min_control:%d.%03d MHz min_width:%d min_center: %d.%03d/%d MHz" 72 + #define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_freq_offset, \ 73 + __entry->min_chan_width, \ 74 + __entry->min_center_freq1, __entry->min_freq1_offset, \ 75 + __entry->min_center_freq2 66 76 67 77 #define CHANCTX_ENTRY CHANDEF_ENTRY \ 68 78 MIN_CHANDEF_ENTRY \ ··· 422 412 __field(s32, cqm_rssi_hyst) 423 413 __field(u32, channel_width) 424 414 __field(u32, channel_cfreq1) 415 + __field(u32, channel_cfreq1_offset) 425 416 __dynamic_array(u32, arp_addr_list, 426 417 info->arp_addr_cnt > IEEE80211_BSS_ARP_ADDR_LIST_LEN ? 427 418 IEEE80211_BSS_ARP_ADDR_LIST_LEN : ··· 463 452 __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; 464 453 __entry->channel_width = info->chandef.width; 465 454 __entry->channel_cfreq1 = info->chandef.center_freq1; 455 + __entry->channel_cfreq1_offset = info->chandef.freq1_offset; 466 456 __entry->arp_addr_cnt = info->arp_addr_cnt; 467 457 memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, 468 458 sizeof(u32) * (info->arp_addr_cnt > IEEE80211_BSS_ARP_ADDR_LIST_LEN ? ··· 1235 1223 LOCAL_ENTRY 1236 1224 VIF_ENTRY 1237 1225 __field(int, center_freq) 1226 + __field(int, freq_offset) 1238 1227 __field(unsigned int, duration) 1239 1228 __field(u32, type) 1240 1229 ), ··· 1244 1231 LOCAL_ASSIGN; 1245 1232 VIF_ASSIGN; 1246 1233 __entry->center_freq = chan->center_freq; 1234 + __entry->freq_offset = chan->freq_offset; 1247 1235 __entry->duration = duration; 1248 1236 __entry->type = type; 1249 1237 ), 1250 1238 1251 1239 TP_printk( 1252 - LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms type=%d", 1240 + LOCAL_PR_FMT VIF_PR_FMT " freq:%d.%03dMHz duration:%dms type=%d", 1253 1241 LOCAL_PR_ARG, VIF_PR_ARG, 1254 - __entry->center_freq, __entry->duration, __entry->type 1242 + __entry->center_freq, __entry->freq_offset, 1243 + __entry->duration, __entry->type 1255 1244 ) 1256 1245 ); 1257 1246 ··· 1561 1546 1562 1547 struct trace_chandef_entry { 1563 1548 u32 control_freq; 1549 + u32 freq_offset; 1564 1550 u32 chan_width; 1565 1551 u32 center_freq1; 1552 + u32 freq1_offset; 1566 1553 u32 center_freq2; 1567 1554 } __packed; 1568 1555 ··· 1614 1597 sizeof(local_vifs[i].vif.vif_name)); 1615 1598 SWITCH_ENTRY_ASSIGN(old_chandef.control_freq, 1616 1599 old_ctx->def.chan->center_freq); 1600 + SWITCH_ENTRY_ASSIGN(old_chandef.freq_offset, 1601 + old_ctx->def.chan->freq_offset); 1617 1602 SWITCH_ENTRY_ASSIGN(old_chandef.chan_width, 1618 1603 old_ctx->def.width); 1619 1604 SWITCH_ENTRY_ASSIGN(old_chandef.center_freq1, 1620 1605 old_ctx->def.center_freq1); 1606 + SWITCH_ENTRY_ASSIGN(old_chandef.freq1_offset, 1607 + old_ctx->def.freq1_offset); 1621 1608 SWITCH_ENTRY_ASSIGN(old_chandef.center_freq2, 1622 1609 old_ctx->def.center_freq2); 1623 1610 SWITCH_ENTRY_ASSIGN(new_chandef.control_freq, 1624 1611 new_ctx->def.chan->center_freq); 1612 + SWITCH_ENTRY_ASSIGN(new_chandef.freq_offset, 1613 + new_ctx->def.chan->freq_offset); 1625 1614 SWITCH_ENTRY_ASSIGN(new_chandef.chan_width, 1626 1615 new_ctx->def.width); 1627 1616 SWITCH_ENTRY_ASSIGN(new_chandef.center_freq1, 1628 1617 new_ctx->def.center_freq1); 1618 + SWITCH_ENTRY_ASSIGN(new_chandef.freq1_offset, 1619 + new_ctx->def.freq1_offset); 1629 1620 SWITCH_ENTRY_ASSIGN(new_chandef.center_freq2, 1630 1621 new_ctx->def.center_freq2); 1631 1622 }
+5 -2
net/mac80211/tx.c
··· 4883 4883 txrc.bss_conf = &sdata->vif.bss_conf; 4884 4884 txrc.skb = skb; 4885 4885 txrc.reported_rate.idx = -1; 4886 - txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; 4886 + if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band]) 4887 + txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band]; 4888 + else 4889 + txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; 4887 4890 txrc.bss = true; 4888 4891 rate_control_get_rate(sdata, NULL, &txrc); 4889 4892 ··· 5009 5006 pspoll = skb_put_zero(skb, sizeof(*pspoll)); 5010 5007 pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | 5011 5008 IEEE80211_STYPE_PSPOLL); 5012 - pspoll->aid = cpu_to_le16(ifmgd->aid); 5009 + pspoll->aid = cpu_to_le16(sdata->vif.bss_conf.aid); 5013 5010 5014 5011 /* aid in PS-Poll has its two MSBs each set to 1 */ 5015 5012 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
+8 -2
net/mac80211/vht.c
··· 4 4 * 5 5 * Portions of this file 6 6 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 7 - * Copyright (C) 2018 - 2019 Intel Corporation 7 + * Copyright (C) 2018 - 2020 Intel Corporation 8 8 */ 9 9 10 10 #include <linux/ieee80211.h> ··· 575 575 576 576 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { 577 577 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: 578 + /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */ 578 579 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; 579 580 break; 580 581 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ: 582 + /* ignore IEEE80211_OPMODE_NOTIF_BW_160_80P80 must not be set */ 581 583 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_40; 582 584 break; 583 585 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ: 584 - sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80; 586 + if (opmode & IEEE80211_OPMODE_NOTIF_BW_160_80P80) 587 + sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; 588 + else 589 + sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80; 585 590 break; 586 591 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ: 592 + /* legacy only, no longer used by newer spec */ 587 593 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160; 588 594 break; 589 595 }
+41 -30
net/wireless/chan.c
··· 27 27 return; 28 28 29 29 chandef->chan = chan; 30 + chandef->freq1_offset = chan->freq_offset; 30 31 chandef->center_freq2 = 0; 31 32 chandef->edmg.bw_config = 0; 32 33 chandef->edmg.channels = 0; ··· 147 146 if (!chandef->chan) 148 147 return false; 149 148 149 + if (chandef->freq1_offset >= 1000) 150 + return false; 151 + 150 152 control_freq = chandef->chan->center_freq; 151 153 152 154 switch (chandef->width) { ··· 157 153 case NL80211_CHAN_WIDTH_10: 158 154 case NL80211_CHAN_WIDTH_20: 159 155 case NL80211_CHAN_WIDTH_20_NOHT: 160 - if (chandef->center_freq1 != control_freq) 156 + if (ieee80211_chandef_to_khz(chandef) != 157 + ieee80211_channel_to_khz(chandef->chan)) 161 158 return false; 162 159 if (chandef->center_freq2) 163 160 return false; ··· 391 386 { 392 387 u32 start_freq; 393 388 394 - if (bandwidth <= 20) 389 + bandwidth = MHZ_TO_KHZ(bandwidth); 390 + if (bandwidth <= MHZ_TO_KHZ(20)) 395 391 start_freq = center_freq; 396 392 else 397 - start_freq = center_freq - bandwidth/2 + 10; 393 + start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10); 398 394 399 395 return start_freq; 400 396 } ··· 405 399 { 406 400 u32 end_freq; 407 401 408 - if (bandwidth <= 20) 402 + bandwidth = MHZ_TO_KHZ(bandwidth); 403 + if (bandwidth <= MHZ_TO_KHZ(20)) 409 404 end_freq = center_freq; 410 405 else 411 - end_freq = center_freq + bandwidth/2 - 10; 406 + end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10); 412 407 413 408 return end_freq; 414 409 } ··· 424 417 start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 425 418 end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 426 419 427 - for (freq = start_freq; freq <= end_freq; freq += 20) { 428 - c = ieee80211_get_channel(wiphy, freq); 420 + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { 421 + c = ieee80211_get_channel_khz(wiphy, freq); 429 422 if (!c) 430 423 return -EINVAL; 431 424 ··· 456 449 return -EINVAL; 457 450 458 451 ret = cfg80211_get_chans_dfs_required(wiphy, 459 - chandef->center_freq1, 460 - width); 452 + ieee80211_chandef_to_khz(chandef), 453 + width); 461 454 if (ret < 0) 462 455 return ret; 463 456 else if (ret > 0) ··· 467 460 return 0; 468 461 469 462 ret = cfg80211_get_chans_dfs_required(wiphy, 470 - chandef->center_freq2, 471 - width); 463 + MHZ_TO_KHZ(chandef->center_freq2), 464 + width); 472 465 if (ret < 0) 473 466 return ret; 474 467 else if (ret > 0) ··· 510 503 * DFS_AVAILABLE). Return number of usable channels 511 504 * (require CAC). Allow DFS and non-DFS channel mix. 512 505 */ 513 - for (freq = start_freq; freq <= end_freq; freq += 20) { 514 - c = ieee80211_get_channel(wiphy, freq); 506 + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { 507 + c = ieee80211_get_channel_khz(wiphy, freq); 515 508 if (!c) 516 509 return -EINVAL; 517 510 ··· 543 536 if (width < 0) 544 537 return false; 545 538 546 - r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1, 547 - width); 539 + r1 = cfg80211_get_chans_dfs_usable(wiphy, 540 + MHZ_TO_KHZ(chandef->center_freq1), 541 + width); 548 542 549 543 if (r1 < 0) 550 544 return false; ··· 554 546 case NL80211_CHAN_WIDTH_80P80: 555 547 WARN_ON(!chandef->center_freq2); 556 548 r2 = cfg80211_get_chans_dfs_usable(wiphy, 557 - chandef->center_freq2, 558 - width); 549 + MHZ_TO_KHZ(chandef->center_freq2), 550 + width); 559 551 if (r2 < 0) 560 552 return false; 561 553 break; ··· 702 694 * If any channel in between is disabled or has not 703 695 * had gone through CAC return false 704 696 */ 705 - for (freq = start_freq; freq <= end_freq; freq += 20) { 706 - c = ieee80211_get_channel(wiphy, freq); 697 + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { 698 + c = ieee80211_get_channel_khz(wiphy, freq); 707 699 if (!c) 708 700 return false; 709 701 ··· 732 724 if (width < 0) 733 725 return false; 734 726 735 - r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1, 727 + r = cfg80211_get_chans_dfs_available(wiphy, 728 + MHZ_TO_KHZ(chandef->center_freq1), 736 729 width); 737 730 738 731 /* If any of channels unavailable for cf1 just return */ ··· 744 735 case NL80211_CHAN_WIDTH_80P80: 745 736 WARN_ON(!chandef->center_freq2); 746 737 r = cfg80211_get_chans_dfs_available(wiphy, 747 - chandef->center_freq2, 748 - width); 738 + MHZ_TO_KHZ(chandef->center_freq2), 739 + width); 749 740 break; 750 741 default: 751 742 WARN_ON(chandef->center_freq2); ··· 766 757 start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 767 758 end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 768 759 769 - for (freq = start_freq; freq <= end_freq; freq += 20) { 770 - c = ieee80211_get_channel(wiphy, freq); 760 + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { 761 + c = ieee80211_get_channel_khz(wiphy, freq); 771 762 if (!c) 772 763 return 0; 773 764 ··· 799 790 return 0; 800 791 801 792 t1 = cfg80211_get_chans_dfs_cac_time(wiphy, 802 - chandef->center_freq1, 793 + MHZ_TO_KHZ(chandef->center_freq1), 803 794 width); 804 795 805 796 if (!chandef->center_freq2) 806 797 return t1; 807 798 808 799 t2 = cfg80211_get_chans_dfs_cac_time(wiphy, 809 - chandef->center_freq2, 800 + MHZ_TO_KHZ(chandef->center_freq2), 810 801 width); 811 802 812 803 return max(t1, t2); ··· 822 813 start_freq = cfg80211_get_start_freq(center_freq, bandwidth); 823 814 end_freq = cfg80211_get_end_freq(center_freq, bandwidth); 824 815 825 - for (freq = start_freq; freq <= end_freq; freq += 20) { 826 - c = ieee80211_get_channel(wiphy, freq); 816 + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { 817 + c = ieee80211_get_channel_khz(wiphy, freq); 827 818 if (!c || c->flags & prohibited_flags) 828 819 return false; 829 820 } ··· 985 976 prohibited_flags |= IEEE80211_CHAN_NO_OFDM; 986 977 987 978 988 - if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, 979 + if (!cfg80211_secondary_chans_ok(wiphy, 980 + ieee80211_chandef_to_khz(chandef), 989 981 width, prohibited_flags)) 990 982 return false; 991 983 992 984 if (!chandef->center_freq2) 993 985 return true; 994 - return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2, 986 + return cfg80211_secondary_chans_ok(wiphy, 987 + MHZ_TO_KHZ(chandef->center_freq2), 995 988 width, prohibited_flags); 996 989 } 997 990 EXPORT_SYMBOL(cfg80211_chandef_usable);
+6 -4
net/wireless/core.c
··· 480 480 INIT_LIST_HEAD(&rdev->bss_list); 481 481 INIT_LIST_HEAD(&rdev->sched_scan_req_list); 482 482 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 483 - INIT_LIST_HEAD(&rdev->mlme_unreg); 484 - spin_lock_init(&rdev->mlme_unreg_lock); 485 - INIT_WORK(&rdev->mlme_unreg_wk, cfg80211_mlme_unreg_wk); 486 483 INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk, 487 484 cfg80211_dfs_channels_update_work); 488 485 #ifdef CONFIG_CFG80211_WEXT ··· 834 837 sband->channels[i].orig_mpwr = 835 838 sband->channels[i].max_power; 836 839 sband->channels[i].band = band; 840 + 841 + if (WARN_ON(sband->channels[i].freq_offset >= 1000)) 842 + return -EINVAL; 837 843 } 838 844 839 845 for (i = 0; i < sband->n_iftype_data; i++) { ··· 1030 1030 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); 1031 1031 flush_work(&rdev->destroy_work); 1032 1032 flush_work(&rdev->sched_scan_stop_wk); 1033 - flush_work(&rdev->mlme_unreg_wk); 1034 1033 flush_work(&rdev->propagate_radar_detect_wk); 1035 1034 flush_work(&rdev->propagate_cac_done_wk); 1036 1035 ··· 1093 1094 rdev->devlist_generation++; 1094 1095 1095 1096 cfg80211_mlme_purge_registrations(wdev); 1097 + flush_work(&wdev->mgmt_registrations_update_wk); 1096 1098 1097 1099 switch (wdev->iftype) { 1098 1100 case NL80211_IFTYPE_P2P_DEVICE: ··· 1238 1238 spin_lock_init(&wdev->event_lock); 1239 1239 INIT_LIST_HEAD(&wdev->mgmt_registrations); 1240 1240 spin_lock_init(&wdev->mgmt_registrations_lock); 1241 + INIT_WORK(&wdev->mgmt_registrations_update_wk, 1242 + cfg80211_mgmt_registrations_update_wk); 1241 1243 INIT_LIST_HEAD(&wdev->pmsr_list); 1242 1244 spin_lock_init(&wdev->pmsr_lock); 1243 1245 INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
+3 -6
net/wireless/core.h
··· 60 60 struct list_head beacon_registrations; 61 61 spinlock_t beacon_registrations_lock; 62 62 63 - struct list_head mlme_unreg; 64 - spinlock_t mlme_unreg_lock; 65 - struct work_struct mlme_unreg_wk; 66 - 67 63 /* protected by RTNL only */ 68 64 int num_running_ifaces; 69 65 int num_running_monitor_ifaces; ··· 381 385 struct net_device *dev); 382 386 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 383 387 u16 frame_type, const u8 *match_data, 384 - int match_len, struct netlink_ext_ack *extack); 385 - void cfg80211_mlme_unreg_wk(struct work_struct *wk); 388 + int match_len, bool multicast_rx, 389 + struct netlink_ext_ack *extack); 390 + void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk); 386 391 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); 387 392 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); 388 393 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
+57 -49
net/wireless/mlme.c
··· 426 426 427 427 __le16 frame_type; 428 428 429 + bool multicast_rx; 430 + 429 431 u8 match[]; 430 432 }; 431 433 432 - static void 433 - cfg80211_process_mlme_unregistrations(struct cfg80211_registered_device *rdev) 434 + static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev) 434 435 { 436 + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 437 + struct wireless_dev *tmp; 435 438 struct cfg80211_mgmt_registration *reg; 439 + struct mgmt_frame_regs upd = {}; 436 440 437 441 ASSERT_RTNL(); 438 442 439 - spin_lock_bh(&rdev->mlme_unreg_lock); 440 - while ((reg = list_first_entry_or_null(&rdev->mlme_unreg, 441 - struct cfg80211_mgmt_registration, 442 - list))) { 443 - list_del(&reg->list); 444 - spin_unlock_bh(&rdev->mlme_unreg_lock); 443 + rcu_read_lock(); 444 + list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) { 445 + list_for_each_entry_rcu(reg, &tmp->mgmt_registrations, list) { 446 + u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4); 447 + u32 mcast_mask = 0; 445 448 446 - if (rdev->ops->mgmt_frame_register) { 447 - u16 frame_type = le16_to_cpu(reg->frame_type); 449 + if (reg->multicast_rx) 450 + mcast_mask = mask; 448 451 449 - rdev_mgmt_frame_register(rdev, reg->wdev, 450 - frame_type, false); 452 + upd.global_stypes |= mask; 453 + upd.global_mcast_stypes |= mcast_mask; 454 + 455 + if (tmp == wdev) { 456 + upd.interface_stypes |= mask; 457 + upd.interface_mcast_stypes |= mcast_mask; 458 + } 451 459 } 452 - 453 - kfree(reg); 454 - 455 - spin_lock_bh(&rdev->mlme_unreg_lock); 456 460 } 457 - spin_unlock_bh(&rdev->mlme_unreg_lock); 461 + rcu_read_unlock(); 462 + 463 + rdev_update_mgmt_frame_registrations(rdev, wdev, &upd); 458 464 } 459 465 460 - void cfg80211_mlme_unreg_wk(struct work_struct *wk) 466 + void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk) 461 467 { 462 - struct cfg80211_registered_device *rdev; 463 - 464 - rdev = container_of(wk, struct cfg80211_registered_device, 465 - mlme_unreg_wk); 468 + struct wireless_dev *wdev = container_of(wk, struct wireless_dev, 469 + mgmt_registrations_update_wk); 466 470 467 471 rtnl_lock(); 468 - cfg80211_process_mlme_unregistrations(rdev); 472 + cfg80211_mgmt_registrations_update(wdev); 469 473 rtnl_unlock(); 470 474 } 471 475 472 476 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, 473 477 u16 frame_type, const u8 *match_data, 474 - int match_len, struct netlink_ext_ack *extack) 478 + int match_len, bool multicast_rx, 479 + struct netlink_ext_ack *extack) 475 480 { 476 - struct wiphy *wiphy = wdev->wiphy; 477 - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 478 481 struct cfg80211_mgmt_registration *reg, *nreg; 479 482 int err = 0; 480 483 u16 mgmt_type; 484 + bool update_multicast = false; 481 485 482 486 if (!wdev->wiphy->mgmt_stypes) 483 487 return -EOPNOTSUPP; ··· 532 528 continue; 533 529 534 530 if (memcmp(reg->match, match_data, mlen) == 0) { 531 + if (reg->multicast_rx != multicast_rx) { 532 + update_multicast = true; 533 + reg->multicast_rx = multicast_rx; 534 + break; 535 + } 535 536 NL_SET_ERR_MSG(extack, "Match already configured"); 536 537 err = -EALREADY; 537 538 break; 538 539 } 539 540 } 540 541 541 - if (err) { 542 - kfree(nreg); 542 + if (err) 543 543 goto out; 544 - } 545 544 546 - memcpy(nreg->match, match_data, match_len); 547 - nreg->match_len = match_len; 548 - nreg->nlportid = snd_portid; 549 - nreg->frame_type = cpu_to_le16(frame_type); 550 - nreg->wdev = wdev; 551 - list_add(&nreg->list, &wdev->mgmt_registrations); 545 + if (update_multicast) { 546 + kfree(nreg); 547 + } else { 548 + memcpy(nreg->match, match_data, match_len); 549 + nreg->match_len = match_len; 550 + nreg->nlportid = snd_portid; 551 + nreg->frame_type = cpu_to_le16(frame_type); 552 + nreg->wdev = wdev; 553 + nreg->multicast_rx = multicast_rx; 554 + list_add(&nreg->list, &wdev->mgmt_registrations); 555 + } 552 556 spin_unlock_bh(&wdev->mgmt_registrations_lock); 553 557 554 - /* process all unregistrations to avoid driver confusion */ 555 - cfg80211_process_mlme_unregistrations(rdev); 556 - 557 - if (rdev->ops->mgmt_frame_register) 558 - rdev_mgmt_frame_register(rdev, wdev, frame_type, true); 558 + cfg80211_mgmt_registrations_update(wdev); 559 559 560 560 return 0; 561 561 562 562 out: 563 + kfree(nreg); 563 564 spin_unlock_bh(&wdev->mgmt_registrations_lock); 564 565 565 566 return err; ··· 583 574 continue; 584 575 585 576 list_del(&reg->list); 586 - spin_lock(&rdev->mlme_unreg_lock); 587 - list_add_tail(&reg->list, &rdev->mlme_unreg); 588 - spin_unlock(&rdev->mlme_unreg_lock); 577 + kfree(reg); 589 578 590 - schedule_work(&rdev->mlme_unreg_wk); 579 + schedule_work(&wdev->mgmt_registrations_update_wk); 591 580 } 592 581 593 582 spin_unlock_bh(&wdev->mgmt_registrations_lock); ··· 601 594 602 595 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) 603 596 { 604 - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 597 + struct cfg80211_mgmt_registration *reg, *tmp; 605 598 606 599 spin_lock_bh(&wdev->mgmt_registrations_lock); 607 - spin_lock(&rdev->mlme_unreg_lock); 608 - list_splice_tail_init(&wdev->mgmt_registrations, &rdev->mlme_unreg); 609 - spin_unlock(&rdev->mlme_unreg_lock); 600 + list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 601 + list_del(&reg->list); 602 + kfree(reg); 603 + } 610 604 spin_unlock_bh(&wdev->mgmt_registrations_lock); 611 605 612 - cfg80211_process_mlme_unregistrations(rdev); 606 + cfg80211_mgmt_registrations_update(wdev); 613 607 } 614 608 615 609 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
+38 -6
net/wireless/nl80211.c
··· 635 635 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG }, 636 636 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1), 637 637 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100), 638 + [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG }, 638 639 }; 639 640 640 641 /* policy for the key attributes */ ··· 3861 3860 }; 3862 3861 void *hdr; 3863 3862 struct sk_buff *msg; 3863 + bool bigtk_support = false; 3864 + 3865 + if (wiphy_ext_feature_isset(&rdev->wiphy, 3866 + NL80211_EXT_FEATURE_BEACON_PROTECTION)) 3867 + bigtk_support = true; 3868 + 3869 + if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION || 3870 + dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) && 3871 + wiphy_ext_feature_isset(&rdev->wiphy, 3872 + NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) 3873 + bigtk_support = true; 3864 3874 3865 3875 if (info->attrs[NL80211_ATTR_KEY_IDX]) { 3866 3876 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 3867 - if (key_idx > 5 && 3868 - !wiphy_ext_feature_isset( 3869 - &rdev->wiphy, 3870 - NL80211_EXT_FEATURE_BEACON_PROTECTION)) 3877 + 3878 + if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) { 3879 + GENL_SET_ERR_MSG(info, "BIGTK not supported"); 3871 3880 return -EINVAL; 3881 + } 3872 3882 } 3873 3883 3874 3884 if (info->attrs[NL80211_ATTR_MAC]) ··· 4691 4679 params->ht_required = true; 4692 4680 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY) 4693 4681 params->vht_required = true; 4682 + if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY) 4683 + params->he_required = true; 4694 4684 } 4695 4685 } 4696 4686 ··· 10740 10726 if (!rdev->ops->mgmt_tx) 10741 10727 return -EOPNOTSUPP; 10742 10728 10729 + if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] && 10730 + !wiphy_ext_feature_isset(&rdev->wiphy, 10731 + NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) { 10732 + GENL_SET_ERR_MSG(info, 10733 + "multicast RX registrations are not supported"); 10734 + return -EOPNOTSUPP; 10735 + } 10736 + 10743 10737 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type, 10744 10738 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), 10745 10739 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]), 10740 + info->attrs[NL80211_ATTR_RECEIVE_MULTICAST], 10746 10741 info->extack); 10747 10742 } 10748 10743 ··· 15518 15495 if (WARN_ON(len < 2)) 15519 15496 return; 15520 15497 15521 - if (ieee80211_is_deauth(mgmt->frame_control)) 15498 + if (ieee80211_is_deauth(mgmt->frame_control)) { 15522 15499 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE; 15523 - else 15500 + } else if (ieee80211_is_disassoc(mgmt->frame_control)) { 15524 15501 cmd = NL80211_CMD_UNPROT_DISASSOCIATE; 15502 + } else if (ieee80211_is_beacon(mgmt->frame_control)) { 15503 + if (wdev->unprot_beacon_reported && 15504 + elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000) 15505 + return; 15506 + cmd = NL80211_CMD_UNPROT_BEACON; 15507 + wdev->unprot_beacon_reported = jiffies; 15508 + } else { 15509 + return; 15510 + } 15525 15511 15526 15512 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); 15527 15513 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
+7 -4
net/wireless/rdev-ops.h
··· 819 819 } 820 820 821 821 static inline void 822 - rdev_mgmt_frame_register(struct cfg80211_registered_device *rdev, 823 - struct wireless_dev *wdev, u16 frame_type, bool reg) 822 + rdev_update_mgmt_frame_registrations(struct cfg80211_registered_device *rdev, 823 + struct wireless_dev *wdev, 824 + struct mgmt_frame_regs *upd) 824 825 { 825 826 might_sleep(); 826 827 827 - trace_rdev_mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); 828 - rdev->ops->mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); 828 + trace_rdev_update_mgmt_frame_registrations(&rdev->wiphy, wdev, upd); 829 + if (rdev->ops->update_mgmt_frame_registrations) 830 + rdev->ops->update_mgmt_frame_registrations(&rdev->wiphy, wdev, 831 + upd); 829 832 trace_rdev_return_void(&rdev->wiphy); 830 833 } 831 834
+21 -19
net/wireless/reg.c
··· 1658 1658 const struct ieee80211_channel *chan) 1659 1659 { 1660 1660 const struct ieee80211_freq_range *freq_range = NULL; 1661 - u32 max_bandwidth_khz, bw_flags = 0; 1661 + u32 max_bandwidth_khz, center_freq_khz, bw_flags = 0; 1662 1662 1663 1663 freq_range = &reg_rule->freq_range; 1664 1664 1665 1665 max_bandwidth_khz = freq_range->max_bandwidth_khz; 1666 + center_freq_khz = ieee80211_channel_to_khz(chan); 1666 1667 /* Check if auto calculation requested */ 1667 1668 if (reg_rule->flags & NL80211_RRF_AUTO_BW) 1668 1669 max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); 1669 1670 1670 1671 /* If we get a reg_rule we can assume that at least 5Mhz fit */ 1671 1672 if (!cfg80211_does_bw_fit_range(freq_range, 1672 - MHZ_TO_KHZ(chan->center_freq), 1673 + center_freq_khz, 1673 1674 MHZ_TO_KHZ(10))) 1674 1675 bw_flags |= IEEE80211_CHAN_NO_10MHZ; 1675 1676 if (!cfg80211_does_bw_fit_range(freq_range, 1676 - MHZ_TO_KHZ(chan->center_freq), 1677 + center_freq_khz, 1677 1678 MHZ_TO_KHZ(20))) 1678 1679 bw_flags |= IEEE80211_CHAN_NO_20MHZ; 1679 1680 ··· 1711 1710 1712 1711 flags = chan->orig_flags; 1713 1712 1714 - reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq)); 1713 + reg_rule = freq_reg_info(wiphy, ieee80211_channel_to_khz(chan)); 1715 1714 if (IS_ERR(reg_rule)) { 1716 1715 /* 1717 1716 * We will disable all channels that do not match our ··· 1730 1729 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1731 1730 request_wiphy && request_wiphy == wiphy && 1732 1731 request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) { 1733 - pr_debug("Disabling freq %d MHz for good\n", 1734 - chan->center_freq); 1732 + pr_debug("Disabling freq %d.%03d MHz for good\n", 1733 + chan->center_freq, chan->freq_offset); 1735 1734 chan->orig_flags |= IEEE80211_CHAN_DISABLED; 1736 1735 chan->flags = chan->orig_flags; 1737 1736 } else { 1738 - pr_debug("Disabling freq %d MHz\n", 1739 - chan->center_freq); 1737 + pr_debug("Disabling freq %d.%03d MHz\n", 1738 + chan->center_freq, chan->freq_offset); 1740 1739 chan->flags |= IEEE80211_CHAN_DISABLED; 1741 1740 } 1742 1741 return; ··· 1937 1936 sband = wiphy->bands[reg_beacon->chan.band]; 1938 1937 chan = &sband->channels[chan_idx]; 1939 1938 1940 - if (likely(chan->center_freq != reg_beacon->chan.center_freq)) 1939 + if (likely(!ieee80211_channel_equal(chan, &reg_beacon->chan))) 1941 1940 return; 1942 1941 1943 1942 if (chan->beacon_found) ··· 2270 2269 u32 bw_flags = 0; 2271 2270 const struct ieee80211_reg_rule *reg_rule = NULL; 2272 2271 const struct ieee80211_power_rule *power_rule = NULL; 2273 - u32 bw; 2272 + u32 bw, center_freq_khz; 2274 2273 2274 + center_freq_khz = ieee80211_channel_to_khz(chan); 2275 2275 for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) { 2276 - reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(chan->center_freq), 2277 - regd, bw); 2276 + reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw); 2278 2277 if (!IS_ERR(reg_rule)) 2279 2278 break; 2280 2279 } 2281 2280 2282 2281 if (IS_ERR_OR_NULL(reg_rule)) { 2283 - pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", 2284 - chan->center_freq); 2282 + pr_debug("Disabling freq %d.%03d MHz as custom regd has no rule that fits it\n", 2283 + chan->center_freq, chan->freq_offset); 2285 2284 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { 2286 2285 chan->flags |= IEEE80211_CHAN_DISABLED; 2287 2286 } else { ··· 3338 3337 struct reg_beacon *pending_beacon; 3339 3338 3340 3339 list_for_each_entry(pending_beacon, &reg_pending_beacons, list) 3341 - if (beacon_chan->center_freq == 3342 - pending_beacon->chan.center_freq) 3340 + if (ieee80211_channel_equal(beacon_chan, 3341 + &pending_beacon->chan)) 3343 3342 return true; 3344 3343 return false; 3345 3344 } ··· 3368 3367 if (!reg_beacon) 3369 3368 return -ENOMEM; 3370 3369 3371 - pr_debug("Found new beacon on frequency: %d MHz (Ch %d) on %s\n", 3372 - beacon_chan->center_freq, 3373 - ieee80211_frequency_to_channel(beacon_chan->center_freq), 3370 + pr_debug("Found new beacon on frequency: %d.%03d MHz (Ch %d) on %s\n", 3371 + beacon_chan->center_freq, beacon_chan->freq_offset, 3372 + ieee80211_freq_khz_to_channel( 3373 + ieee80211_channel_to_khz(beacon_chan)), 3374 3374 wiphy_name(wiphy)); 3375 3375 3376 3376 memcpy(&reg_beacon->chan, beacon_chan,
+2 -2
net/wireless/scan.c
··· 1322 1322 return channel; 1323 1323 } 1324 1324 1325 - freq = ieee80211_channel_to_frequency(channel_number, channel->band); 1326 - alt_channel = ieee80211_get_channel(wiphy, freq); 1325 + freq = ieee80211_channel_to_freq_khz(channel_number, channel->band); 1326 + alt_channel = ieee80211_get_channel_khz(wiphy, freq); 1327 1327 if (!alt_channel) { 1328 1328 if (channel->band == NL80211_BAND_2GHZ) { 1329 1329 /*
+2
net/wireless/sme.c
··· 694 694 return; 695 695 } 696 696 697 + wdev->unprot_beacon_reported = 0; 697 698 nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr, 698 699 GFP_KERNEL); 699 700 ··· 922 921 cfg80211_hold_bss(bss_from_pub(info->bss)); 923 922 wdev->current_bss = bss_from_pub(info->bss); 924 923 924 + wdev->unprot_beacon_reported = 0; 925 925 nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), 926 926 wdev->netdev, info, GFP_KERNEL); 927 927
+26 -15
net/wireless/trace.h
··· 112 112 } while (0) 113 113 114 114 #define CHAN_ENTRY __field(enum nl80211_band, band) \ 115 - __field(u32, center_freq) 115 + __field(u32, center_freq) \ 116 + __field(u16, freq_offset) 116 117 #define CHAN_ASSIGN(chan) \ 117 118 do { \ 118 119 if (chan) { \ 119 120 __entry->band = chan->band; \ 120 121 __entry->center_freq = chan->center_freq; \ 122 + __entry->freq_offset = chan->freq_offset; \ 121 123 } else { \ 122 124 __entry->band = 0; \ 123 125 __entry->center_freq = 0; \ 126 + __entry->freq_offset = 0; \ 124 127 } \ 125 128 } while (0) 126 - #define CHAN_PR_FMT "band: %d, freq: %u" 127 - #define CHAN_PR_ARG __entry->band, __entry->center_freq 129 + #define CHAN_PR_FMT "band: %d, freq: %u.%03u" 130 + #define CHAN_PR_ARG __entry->band, __entry->center_freq, __entry->freq_offset 128 131 129 132 #define CHAN_DEF_ENTRY __field(enum nl80211_band, band) \ 130 133 __field(u32, control_freq) \ 134 + __field(u32, freq_offset) \ 131 135 __field(u32, width) \ 132 136 __field(u32, center_freq1) \ 137 + __field(u32, freq1_offset) \ 133 138 __field(u32, center_freq2) 134 139 #define CHAN_DEF_ASSIGN(chandef) \ 135 140 do { \ ··· 142 137 __entry->band = (chandef)->chan->band; \ 143 138 __entry->control_freq = \ 144 139 (chandef)->chan->center_freq; \ 140 + __entry->freq_offset = \ 141 + (chandef)->chan->freq_offset; \ 145 142 __entry->width = (chandef)->width; \ 146 143 __entry->center_freq1 = (chandef)->center_freq1;\ 144 + __entry->freq1_offset = (chandef)->freq1_offset;\ 147 145 __entry->center_freq2 = (chandef)->center_freq2;\ 148 146 } else { \ 149 147 __entry->band = 0; \ 150 148 __entry->control_freq = 0; \ 149 + __entry->freq_offset = 0; \ 151 150 __entry->width = 0; \ 152 151 __entry->center_freq1 = 0; \ 152 + __entry->freq1_offset = 0; \ 153 153 __entry->center_freq2 = 0; \ 154 154 } \ 155 155 } while (0) 156 156 #define CHAN_DEF_PR_FMT \ 157 - "band: %d, control freq: %u, width: %d, cf1: %u, cf2: %u" 157 + "band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u" 158 158 #define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \ 159 - __entry->width, __entry->center_freq1, \ 159 + __entry->freq_offset, __entry->width, \ 160 + __entry->center_freq1, __entry->freq1_offset, \ 160 161 __entry->center_freq2 161 162 162 163 #define SINFO_ENTRY __field(int, generation) \ ··· 1593 1582 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) 1594 1583 ); 1595 1584 1596 - TRACE_EVENT(rdev_mgmt_frame_register, 1585 + TRACE_EVENT(rdev_update_mgmt_frame_registrations, 1597 1586 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1598 - u16 frame_type, bool reg), 1599 - TP_ARGS(wiphy, wdev, frame_type, reg), 1587 + struct mgmt_frame_regs *upd), 1588 + TP_ARGS(wiphy, wdev, upd), 1600 1589 TP_STRUCT__entry( 1601 1590 WIPHY_ENTRY 1602 1591 WDEV_ENTRY 1603 - __field(u16, frame_type) 1604 - __field(bool, reg) 1592 + __field(u16, global_stypes) 1593 + __field(u16, interface_stypes) 1605 1594 ), 1606 1595 TP_fast_assign( 1607 1596 WIPHY_ASSIGN; 1608 1597 WDEV_ASSIGN; 1609 - __entry->frame_type = frame_type; 1610 - __entry->reg = reg; 1598 + __entry->global_stypes = upd->global_stypes; 1599 + __entry->interface_stypes = upd->interface_stypes; 1611 1600 ), 1612 - TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", frame_type: 0x%.2x, reg: %s ", 1613 - WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type, 1614 - __entry->reg ? "true" : "false") 1601 + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", global: 0x%.2x, intf: 0x%.2x", 1602 + WIPHY_PR_ARG, WDEV_PR_ARG, 1603 + __entry->global_stypes, __entry->interface_stypes) 1615 1604 ); 1616 1605 1617 1606 TRACE_EVENT(rdev_return_int_tx_rx,
+33 -25
net/wireless/util.c
··· 5 5 * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 7 * Copyright 2017 Intel Deutschland GmbH 8 - * Copyright (C) 2018-2019 Intel Corporation 8 + * Copyright (C) 2018-2020 Intel Corporation 9 9 */ 10 10 #include <linux/export.h> 11 11 #include <linux/bitops.h> ··· 72 72 } 73 73 EXPORT_SYMBOL(ieee80211_mandatory_rates); 74 74 75 - int ieee80211_channel_to_frequency(int chan, enum nl80211_band band) 75 + u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band) 76 76 { 77 77 /* see 802.11 17.3.8.3.2 and Annex J 78 78 * there are overlapping channel numbers in 5GHz and 2GHz bands */ ··· 81 81 switch (band) { 82 82 case NL80211_BAND_2GHZ: 83 83 if (chan == 14) 84 - return 2484; 84 + return MHZ_TO_KHZ(2484); 85 85 else if (chan < 14) 86 - return 2407 + chan * 5; 86 + return MHZ_TO_KHZ(2407 + chan * 5); 87 87 break; 88 88 case NL80211_BAND_5GHZ: 89 89 if (chan >= 182 && chan <= 196) 90 - return 4000 + chan * 5; 90 + return MHZ_TO_KHZ(4000 + chan * 5); 91 91 else 92 - return 5000 + chan * 5; 92 + return MHZ_TO_KHZ(5000 + chan * 5); 93 93 break; 94 94 case NL80211_BAND_6GHZ: 95 95 /* see 802.11ax D4.1 27.3.22.2 */ ··· 98 98 break; 99 99 case NL80211_BAND_60GHZ: 100 100 if (chan < 7) 101 - return 56160 + chan * 2160; 101 + return MHZ_TO_KHZ(56160 + chan * 2160); 102 102 break; 103 103 default: 104 104 ; 105 105 } 106 106 return 0; /* not supported */ 107 107 } 108 - EXPORT_SYMBOL(ieee80211_channel_to_frequency); 108 + EXPORT_SYMBOL(ieee80211_channel_to_freq_khz); 109 109 110 - int ieee80211_frequency_to_channel(int freq) 110 + int ieee80211_freq_khz_to_channel(u32 freq) 111 111 { 112 + /* TODO: just handle MHz for now */ 113 + freq = KHZ_TO_MHZ(freq); 114 + 112 115 /* see 802.11 17.3.8.3.2 and Annex J */ 113 116 if (freq == 2484) 114 117 return 14; ··· 129 126 else 130 127 return 0; 131 128 } 132 - EXPORT_SYMBOL(ieee80211_frequency_to_channel); 129 + EXPORT_SYMBOL(ieee80211_freq_khz_to_channel); 133 130 134 - struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq) 131 + struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy, 132 + u32 freq) 135 133 { 136 134 enum nl80211_band band; 137 135 struct ieee80211_supported_band *sband; ··· 145 141 continue; 146 142 147 143 for (i = 0; i < sband->n_channels; i++) { 148 - if (sband->channels[i].center_freq == freq) 149 - return &sband->channels[i]; 144 + struct ieee80211_channel *chan = &sband->channels[i]; 145 + 146 + if (ieee80211_channel_to_khz(chan) == freq) 147 + return chan; 150 148 } 151 149 } 152 150 153 151 return NULL; 154 152 } 155 - EXPORT_SYMBOL(ieee80211_get_channel); 153 + EXPORT_SYMBOL(ieee80211_get_channel_khz); 156 154 157 155 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) 158 156 { ··· 2036 2030 2037 2031 int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap, 2038 2032 enum ieee80211_vht_chanwidth bw, 2039 - int mcs, bool ext_nss_bw_capable) 2033 + int mcs, bool ext_nss_bw_capable, 2034 + unsigned int max_vht_nss) 2040 2035 { 2041 2036 u16 map = le16_to_cpu(cap->supp_mcs.rx_mcs_map); 2042 - int max_vht_nss = 0; 2043 2037 int ext_nss_bw; 2044 2038 int supp_width; 2045 2039 int i, mcs_encoding; ··· 2047 2041 if (map == 0xffff) 2048 2042 return 0; 2049 2043 2050 - if (WARN_ON(mcs > 9)) 2044 + if (WARN_ON(mcs > 9 || max_vht_nss > 8)) 2051 2045 return 0; 2052 2046 if (mcs <= 7) 2053 2047 mcs_encoding = 0; ··· 2056 2050 else 2057 2051 mcs_encoding = 2; 2058 2052 2059 - /* find max_vht_nss for the given MCS */ 2060 - for (i = 7; i >= 0; i--) { 2061 - int supp = (map >> (2 * i)) & 3; 2053 + if (!max_vht_nss) { 2054 + /* find max_vht_nss for the given MCS */ 2055 + for (i = 7; i >= 0; i--) { 2056 + int supp = (map >> (2 * i)) & 3; 2062 2057 2063 - if (supp == 3) 2064 - continue; 2058 + if (supp == 3) 2059 + continue; 2065 2060 2066 - if (supp >= mcs_encoding) { 2067 - max_vht_nss = i + 1; 2068 - break; 2061 + if (supp >= mcs_encoding) { 2062 + max_vht_nss = i + 1; 2063 + break; 2064 + } 2069 2065 } 2070 2066 } 2071 2067