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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'wireless-2025-11-12' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
Couple more fixes:
- mwl8k: work around FW expecting a DSSS element in beacons
- ath11k: report correct TX status
- iwlwifi: avoid toggling links due to wrong element use
- iwlwifi: fix beacon template rate on older devices
- iwlwifi: fix loop iterator being used after loop
- mac80211: disallow address changes while using the address
- mac80211: avoid bad rate warning in monitor/sniffer mode
- hwsim: fix potential NULL deref (on monitor injection)

* tag 'wireless-2025-11-12' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
wifi: iwlwifi: mld: always take beacon ies in link grading
wifi: iwlwifi: mvm: fix beacon template/fixed rate
wifi: iwlwifi: fix aux ROC time event iterator usage
wifi: mwl8k: inject DSSS Parameter Set element into beacons if missing
wifi: mac80211_hwsim: Fix possible NULL dereference
wifi: mac80211: skip rate verification for not captured PSDUs
wifi: mac80211: reject address change while connecting
wifi: ath11k: zero init info->status in wmi_process_mgmt_tx_comp()
====================

Link: https://patch.msgid.link/20251112114621.15716-5-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+117 -41
+3
drivers/net/wireless/ath/ath11k/wmi.c
··· 5961 5961 dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); 5962 5962 5963 5963 info = IEEE80211_SKB_CB(msdu); 5964 + memset(&info->status, 0, sizeof(info->status)); 5965 + info->status.rates[0].idx = -1; 5966 + 5964 5967 if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && 5965 5968 !tx_compl_param->status) { 5966 5969 info->flags |= IEEE80211_TX_STAT_ACK;
+1 -6
drivers/net/wireless/intel/iwlwifi/mld/link.c
··· 708 708 iwl_mld_get_chan_load_from_element(struct iwl_mld *mld, 709 709 struct ieee80211_bss_conf *link_conf) 710 710 { 711 - struct ieee80211_vif *vif = link_conf->vif; 712 711 const struct cfg80211_bss_ies *ies; 713 712 const struct element *bss_load_elem = NULL; 714 713 const struct ieee80211_bss_load_elem *bss_load; 715 714 716 715 guard(rcu)(); 717 716 718 - if (ieee80211_vif_link_active(vif, link_conf->link_id)) 719 - ies = rcu_dereference(link_conf->bss->beacon_ies); 720 - else 721 - ies = rcu_dereference(link_conf->bss->ies); 722 - 717 + ies = rcu_dereference(link_conf->bss->beacon_ies); 723 718 if (ies) 724 719 bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD, 725 720 ies->data, ies->len);
+3 -10
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
··· 938 938 939 939 u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) 940 940 { 941 + u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); 941 942 bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10; 942 - u16 flags, cck_flag; 943 - 944 - if (is_new_rate) { 945 - flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); 946 - cck_flag = IWL_MAC_BEACON_CCK; 947 - } else { 948 - cck_flag = IWL_MAC_BEACON_CCK_V1; 949 - flags = iwl_fw_rate_idx_to_plcp(rate_idx); 950 - } 951 943 952 944 if (rate_idx <= IWL_LAST_CCK_RATE) 953 - flags |= cck_flag; 945 + flags |= is_new_rate ? IWL_MAC_BEACON_CCK 946 + : IWL_MAC_BEACON_CCK_V1; 954 947 955 948 return flags; 956 949 }
+7 -7
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
··· 463 463 if (!aux_roc_te) /* Not a Aux ROC time event */ 464 464 return -EINVAL; 465 465 466 - iwl_mvm_te_check_trigger(mvm, notif, te_data); 466 + iwl_mvm_te_check_trigger(mvm, notif, aux_roc_te); 467 467 468 468 IWL_DEBUG_TE(mvm, 469 469 "Aux ROC time event notification - UID = 0x%x action %d (error = %d)\n", ··· 475 475 /* End TE, notify mac80211 */ 476 476 ieee80211_remain_on_channel_expired(mvm->hw); 477 477 iwl_mvm_roc_finished(mvm); /* flush aux queue */ 478 - list_del(&te_data->list); /* remove from list */ 479 - te_data->running = false; 480 - te_data->vif = NULL; 481 - te_data->uid = 0; 482 - te_data->id = TE_MAX; 478 + list_del(&aux_roc_te->list); /* remove from list */ 479 + aux_roc_te->running = false; 480 + aux_roc_te->vif = NULL; 481 + aux_roc_te->uid = 0; 482 + aux_roc_te->id = TE_MAX; 483 483 } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) { 484 484 set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); 485 - te_data->running = true; 485 + aux_roc_te->running = true; 486 486 ieee80211_ready_on_channel(mvm->hw); /* Start TE */ 487 487 } else { 488 488 IWL_DEBUG_TE(mvm,
+9 -3
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
··· 159 159 160 160 u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx) 161 161 { 162 - return (rate_idx >= IWL_FIRST_OFDM_RATE ? 163 - rate_idx - IWL_FIRST_OFDM_RATE : 164 - rate_idx); 162 + if (iwl_fw_lookup_cmd_ver(fw, TX_CMD, 0) > 8) 163 + /* In the new rate legacy rates are indexed: 164 + * 0 - 3 for CCK and 0 - 7 for OFDM. 165 + */ 166 + return (rate_idx >= IWL_FIRST_OFDM_RATE ? 167 + rate_idx - IWL_FIRST_OFDM_RATE : 168 + rate_idx); 169 + 170 + return iwl_fw_rate_idx_to_plcp(rate_idx); 165 171 } 166 172 167 173 u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac)
+66 -5
drivers/net/wireless/marvell/mwl8k.c
··· 2966 2966 /* 2967 2967 * CMD_SET_BEACON. 2968 2968 */ 2969 + 2970 + static bool mwl8k_beacon_has_ds_params(const u8 *buf, int len) 2971 + { 2972 + const struct ieee80211_mgmt *mgmt = (const void *)buf; 2973 + int ies_len; 2974 + 2975 + if (len <= offsetof(struct ieee80211_mgmt, u.beacon.variable)) 2976 + return false; 2977 + 2978 + ies_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); 2979 + 2980 + return cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable, 2981 + ies_len) != NULL; 2982 + } 2983 + 2984 + static void mwl8k_beacon_copy_inject_ds_params(struct ieee80211_hw *hw, 2985 + u8 *buf_dst, const u8 *buf_src, 2986 + int src_len) 2987 + { 2988 + const struct ieee80211_mgmt *mgmt = (const void *)buf_src; 2989 + static const u8 before_ds_params[] = { 2990 + WLAN_EID_SSID, 2991 + WLAN_EID_SUPP_RATES, 2992 + }; 2993 + const u8 *ies; 2994 + int hdr_len, left, offs, pos; 2995 + 2996 + ies = mgmt->u.beacon.variable; 2997 + hdr_len = offsetof(struct ieee80211_mgmt, u.beacon.variable); 2998 + 2999 + offs = ieee80211_ie_split(ies, src_len - hdr_len, before_ds_params, 3000 + ARRAY_SIZE(before_ds_params), 0); 3001 + 3002 + pos = hdr_len + offs; 3003 + left = src_len - pos; 3004 + 3005 + memcpy(buf_dst, buf_src, pos); 3006 + 3007 + /* Inject a DSSS Parameter Set after SSID + Supp Rates */ 3008 + buf_dst[pos + 0] = WLAN_EID_DS_PARAMS; 3009 + buf_dst[pos + 1] = 1; 3010 + buf_dst[pos + 2] = hw->conf.chandef.chan->hw_value; 3011 + 3012 + memcpy(buf_dst + pos + 3, buf_src + pos, left); 3013 + } 2969 3014 struct mwl8k_cmd_set_beacon { 2970 3015 struct mwl8k_cmd_pkt_hdr header; 2971 3016 __le16 beacon_len; ··· 3020 2975 static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, 3021 2976 struct ieee80211_vif *vif, u8 *beacon, int len) 3022 2977 { 2978 + bool ds_params_present = mwl8k_beacon_has_ds_params(beacon, len); 3023 2979 struct mwl8k_cmd_set_beacon *cmd; 3024 - int rc; 2980 + int rc, final_len = len; 3025 2981 3026 - cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL); 2982 + if (!ds_params_present) { 2983 + /* 2984 + * mwl8k firmware requires a DS Params IE with the current 2985 + * channel in AP beacons. If mac80211/hostapd does not 2986 + * include it, inject one here. IE ID + length + channel 2987 + * number = 3 bytes. 2988 + */ 2989 + final_len += 3; 2990 + } 2991 + 2992 + cmd = kzalloc(sizeof(*cmd) + final_len, GFP_KERNEL); 3027 2993 if (cmd == NULL) 3028 2994 return -ENOMEM; 3029 2995 3030 2996 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON); 3031 - cmd->header.length = cpu_to_le16(sizeof(*cmd) + len); 3032 - cmd->beacon_len = cpu_to_le16(len); 3033 - memcpy(cmd->beacon, beacon, len); 2997 + cmd->header.length = cpu_to_le16(sizeof(*cmd) + final_len); 2998 + cmd->beacon_len = cpu_to_le16(final_len); 2999 + 3000 + if (ds_params_present) 3001 + memcpy(cmd->beacon, beacon, len); 3002 + else 3003 + mwl8k_beacon_copy_inject_ds_params(hw, cmd->beacon, beacon, 3004 + len); 3034 3005 3035 3006 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); 3036 3007 kfree(cmd);
+10 -4
drivers/net/wireless/virtual/mac80211_hwsim.c
··· 2003 2003 struct ieee80211_sta *sta = control->sta; 2004 2004 struct ieee80211_bss_conf *bss_conf; 2005 2005 2006 + /* This can happen in case of monitor injection */ 2007 + if (!vif) { 2008 + ieee80211_free_txskb(hw, skb); 2009 + return; 2010 + } 2011 + 2006 2012 if (link != IEEE80211_LINK_UNSPECIFIED) { 2007 - bss_conf = rcu_dereference(txi->control.vif->link_conf[link]); 2013 + bss_conf = rcu_dereference(vif->link_conf[link]); 2008 2014 if (sta) 2009 2015 link_sta = rcu_dereference(sta->link[link]); 2010 2016 } else { ··· 2071 2065 return; 2072 2066 } 2073 2067 2074 - if (txi->control.vif) 2075 - hwsim_check_magic(txi->control.vif); 2068 + if (vif) 2069 + hwsim_check_magic(vif); 2076 2070 if (control->sta) 2077 2071 hwsim_check_sta_magic(control->sta); 2078 2072 2079 2073 if (ieee80211_hw_check(hw, SUPPORTS_RC_TABLE)) 2080 - ieee80211_get_tx_rates(txi->control.vif, control->sta, skb, 2074 + ieee80211_get_tx_rates(vif, control->sta, skb, 2081 2075 txi->control.rates, 2082 2076 ARRAY_SIZE(txi->control.rates)); 2083 2077
+11 -3
net/mac80211/iface.c
··· 223 223 if (netif_carrier_ok(sdata->dev)) 224 224 return -EBUSY; 225 225 226 + /* if any stations are set known (so they know this vif too), reject */ 227 + if (sta_info_get_by_idx(sdata, 0)) 228 + return -EBUSY; 229 + 226 230 /* First check no ROC work is happening on this iface */ 227 231 list_for_each_entry(roc, &local->roc_list, list) { 228 232 if (roc->sdata != sdata) ··· 246 242 ret = -EBUSY; 247 243 } 248 244 245 + /* 246 + * More interface types could be added here but changing the 247 + * address while powered makes the most sense in client modes. 248 + */ 249 249 switch (sdata->vif.type) { 250 250 case NL80211_IFTYPE_STATION: 251 251 case NL80211_IFTYPE_P2P_CLIENT: 252 - /* More interface types could be added here but changing the 253 - * address while powered makes the most sense in client modes. 254 - */ 252 + /* refuse while connecting */ 253 + if (sdata->u.mgd.auth_data || sdata->u.mgd.assoc_data) 254 + return -EBUSY; 255 255 break; 256 256 default: 257 257 ret = -EOPNOTSUPP;
+7 -3
net/mac80211/rx.c
··· 5360 5360 if (WARN_ON(!local->started)) 5361 5361 goto drop; 5362 5362 5363 - if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { 5363 + if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC) && 5364 + !(status->flag & RX_FLAG_NO_PSDU && 5365 + status->zero_length_psdu_type == 5366 + IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED))) { 5364 5367 /* 5365 - * Validate the rate, unless a PLCP error means that 5366 - * we probably can't have a valid rate here anyway. 5368 + * Validate the rate, unless there was a PLCP error which may 5369 + * have an invalid rate or the PSDU was not capture and may be 5370 + * missing rate information. 5367 5371 */ 5368 5372 5369 5373 switch (status->encoding) {