summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-01-22 18:54:30 +0300
committerJakub Kicinski <kuba@kernel.org>2026-01-22 18:54:31 +0300
commit9146fe2829907a73464210db1a117103941d94f1 (patch)
tree3582d9b9d65b65eb4230b55e35da26773900e3b8
parent5778d65d4b85d4929d30998863e08e20af4b6113 (diff)
parent50b359896fe55d0443ed550e1fabba71d242031a (diff)
downloadlinux-9146fe2829907a73464210db1a117103941d94f1.tar.xz
Merge tag 'wireless-2026-11-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless
Johannes Berg says: ==================== Another set of updates: - various small fixes for ath10k/ath12k/mwifiex/rsi - cfg80211 fix for HE bitrate overflow - mac80211 fixes - S1G beacon handling in scan - skb tailroom handling for HW encryption - CSA fix for multi-link - handling of disabled links during association * tag 'wireless-2026-11-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: cfg80211: ignore link disabled flag from userspace wifi: mac80211: apply advertised TTLM from association response wifi: mac80211: parse all TTLM entries wifi: mac80211: don't increment crypto_tx_tailroom_needed_cnt twice wifi: mac80211: don't perform DA check on S1G beacon wifi: ath12k: Fix wrong P2P device link id issue wifi: ath12k: fix dead lock while flushing management frames wifi: ath12k: Fix scan state stuck in ABORTING after cancel_remain_on_channel wifi: ath12k: cancel scan only on active scan vdev wifi: mwifiex: Fix a loop in mwifiex_update_ampdu_rxwinsize() wifi: mac80211: correctly check if CSA is active wifi: cfg80211: Fix bitrate calculation overflow for HE rates wifi: rsi: Fix memory corruption due to not set vif driver data size wifi: ath12k: don't force radio frequency check in freq_to_idx() wifi: ath12k: fix dma_free_coherent() pointer wifi: ath10k: fix dma_free_coherent() pointer ==================== Link: https://patch.msgid.link/20260122110248.15450-3-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c16
-rw-r--r--drivers/net/wireless/ath/ath12k/ce.c12
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath12k/wmi.c9
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c6
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c1
-rw-r--r--include/net/cfg80211.h3
-rw-r--r--include/uapi/linux/nl80211.h5
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c8
-rw-r--r--net/mac80211/key.c3
-rw-r--r--net/mac80211/mlme.c213
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/wireless/nl80211.c10
-rw-r--r--net/wireless/util.c8
15 files changed, 171 insertions, 150 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 7bbda46cfd93..82f120ee1c66 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -1727,8 +1727,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
(ce_state->src_ring->nentries *
sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- ce_state->src_ring->base_addr_owner_space,
- ce_state->src_ring->base_addr_ce_space);
+ ce_state->src_ring->base_addr_owner_space_unaligned,
+ ce_state->src_ring->base_addr_ce_space_unaligned);
kfree(ce_state->src_ring);
}
@@ -1737,8 +1737,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
(ce_state->dest_ring->nentries *
sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- ce_state->dest_ring->base_addr_owner_space,
- ce_state->dest_ring->base_addr_ce_space);
+ ce_state->dest_ring->base_addr_owner_space_unaligned,
+ ce_state->dest_ring->base_addr_ce_space_unaligned);
kfree(ce_state->dest_ring);
}
@@ -1758,8 +1758,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id)
(ce_state->src_ring->nentries *
sizeof(struct ce_desc_64) +
CE_DESC_RING_ALIGN),
- ce_state->src_ring->base_addr_owner_space,
- ce_state->src_ring->base_addr_ce_space);
+ ce_state->src_ring->base_addr_owner_space_unaligned,
+ ce_state->src_ring->base_addr_ce_space_unaligned);
kfree(ce_state->src_ring);
}
@@ -1768,8 +1768,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id)
(ce_state->dest_ring->nentries *
sizeof(struct ce_desc_64) +
CE_DESC_RING_ALIGN),
- ce_state->dest_ring->base_addr_owner_space,
- ce_state->dest_ring->base_addr_ce_space);
+ ce_state->dest_ring->base_addr_owner_space_unaligned,
+ ce_state->dest_ring->base_addr_ce_space_unaligned);
kfree(ce_state->dest_ring);
}
diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c
index 9a63608838ac..4aea58446838 100644
--- a/drivers/net/wireless/ath/ath12k/ce.c
+++ b/drivers/net/wireless/ath/ath12k/ce.c
@@ -984,8 +984,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->src_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->src_ring->base_addr_owner_space,
- pipe->src_ring->base_addr_ce_space);
+ pipe->src_ring->base_addr_owner_space_unaligned,
+ pipe->src_ring->base_addr_ce_space_unaligned);
kfree(pipe->src_ring);
pipe->src_ring = NULL;
}
@@ -995,8 +995,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->dest_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->dest_ring->base_addr_owner_space,
- pipe->dest_ring->base_addr_ce_space);
+ pipe->dest_ring->base_addr_owner_space_unaligned,
+ pipe->dest_ring->base_addr_ce_space_unaligned);
kfree(pipe->dest_ring);
pipe->dest_ring = NULL;
}
@@ -1007,8 +1007,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->status_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->status_ring->base_addr_owner_space,
- pipe->status_ring->base_addr_ce_space);
+ pipe->status_ring->base_addr_owner_space_unaligned,
+ pipe->status_ring->base_addr_ce_space_unaligned);
kfree(pipe->status_ring);
pipe->status_ring = NULL;
}
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index f7a2a544bef2..e0e49f782bf8 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -5495,7 +5495,8 @@ static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw,
for_each_set_bit(link_id, &links_map, ATH12K_NUM_MAX_LINKS) {
arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
- if (!arvif || arvif->is_started)
+ if (!arvif || !arvif->is_created ||
+ arvif->ar->scan.arvif != arvif)
continue;
ar = arvif->ar;
@@ -9172,7 +9173,10 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
return;
}
} else {
- link_id = 0;
+ if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
+ link_id = ATH12K_FIRST_SCAN_LINK;
+ else
+ link_id = 0;
}
arvif = rcu_dereference(ahvif->link[link_id]);
@@ -12142,6 +12146,9 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
if (drop)
return;
+ for_each_ar(ah, ar, i)
+ wiphy_work_flush(hw->wiphy, &ar->wmi_mgmt_tx_work);
+
/* vif can be NULL when flush() is considered for hw */
if (!vif) {
for_each_ar(ah, ar, i)
@@ -12149,9 +12156,6 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
return;
}
- for_each_ar(ah, ar, i)
- wiphy_work_flush(hw->wiphy, &ar->wmi_mgmt_tx_work);
-
ahvif = ath12k_vif_to_ahvif(vif);
links = ahvif->links_map;
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
@@ -13343,7 +13347,7 @@ static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
ath12k_scan_abort(ar);
cancel_delayed_work_sync(&ar->scan.timeout);
- wiphy_work_cancel(hw->wiphy, &ar->scan.vdev_clean_wk);
+ wiphy_work_flush(hw->wiphy, &ar->scan.vdev_clean_wk);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index be8b2943094f..3ce5fcb0e460 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -6575,16 +6575,9 @@ static int freq_to_idx(struct ath12k *ar, int freq)
if (!sband)
continue;
- for (ch = 0; ch < sband->n_channels; ch++, idx++) {
- if (sband->channels[ch].center_freq <
- KHZ_TO_MHZ(ar->freq_range.start_freq) ||
- sband->channels[ch].center_freq >
- KHZ_TO_MHZ(ar->freq_range.end_freq))
- continue;
-
+ for (ch = 0; ch < sband->n_channels; ch++, idx++)
if (sband->channels[ch].center_freq == freq)
goto exit;
- }
}
exit:
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index 354c5ce66045..f3397dc6c422 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -825,7 +825,7 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
bool coex_flag)
{
- u8 i;
+ u8 i, j;
u32 rx_win_size;
struct mwifiex_private *priv;
@@ -863,8 +863,8 @@ static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
if (rx_win_size != priv->add_ba_param.rx_win_size) {
if (!priv->media_connected)
continue;
- for (i = 0; i < MAX_NUM_TID; i++)
- mwifiex_11n_delba(priv, i);
+ for (j = 0; j < MAX_NUM_TID; j++)
+ mwifiex_11n_delba(priv, j);
}
}
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index f3a853edfc11..8c8e074a3a70 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -2035,6 +2035,7 @@ int rsi_mac80211_attach(struct rsi_common *common)
hw->queues = MAX_HW_QUEUES;
hw->extra_tx_headroom = RSI_NEEDED_HEADROOM;
+ hw->vif_data_size = sizeof(struct vif_priv);
hw->max_rates = 1;
hw->max_rate_tries = MAX_RETRIES;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 899f267b7cf9..2900202588a5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3221,8 +3221,6 @@ struct cfg80211_auth_request {
* if this is %NULL for a link, that link is not requested
* @elems: extra elements for the per-STA profile for this link
* @elems_len: length of the elements
- * @disabled: If set this link should be included during association etc. but it
- * should not be used until enabled by the AP MLD.
* @error: per-link error code, must be <= 0. If there is an error, then the
* operation as a whole must fail.
*/
@@ -3230,7 +3228,6 @@ struct cfg80211_assoc_link {
struct cfg80211_bss *bss;
const u8 *elems;
size_t elems_len;
- bool disabled;
int error;
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8134f10e4e6c..8433bac48112 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2880,8 +2880,9 @@ enum nl80211_commands {
* index. If the userspace includes more RNR elements than number of
* MBSSID elements then these will be added in every EMA beacon.
*
- * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is
- * disabled.
+ * @NL80211_ATTR_MLO_LINK_DISABLED: Unused. It was used to indicate that a link
+ * is disabled during association. However, the AP will send the
+ * information by including a TTLM in the association response.
*
* @NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA: Include BSS usage data, i.e.
* include BSSes that can only be used in restricted scenarios and/or
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9d9313eee59f..bd573f8e61fb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -451,8 +451,6 @@ struct ieee80211_mgd_assoc_data {
struct ieee80211_conn_settings conn;
u16 status;
-
- bool disabled;
} link[IEEE80211_MLD_MAX_NUM_LINKS];
u8 ap_addr[ETH_ALEN] __aligned(2);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7b0aa24c1f97..515384ca2f8f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -350,6 +350,8 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
/* we hold the RTNL here so can safely walk the list */
list_for_each_entry(nsdata, &local->interfaces, list) {
if (nsdata != sdata && ieee80211_sdata_running(nsdata)) {
+ struct ieee80211_link_data *link;
+
/*
* Only OCB and monitor mode may coexist
*/
@@ -376,8 +378,10 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
* will not add another interface while any channel
* switch is active.
*/
- if (nsdata->vif.bss_conf.csa_active)
- return -EBUSY;
+ for_each_link_data(nsdata, link) {
+ if (link->conf->csa_active)
+ return -EBUSY;
+ }
/*
* The remaining checks are only performed for interfaces
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index d5da7ccea66e..04c8809173d7 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -987,7 +987,8 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
if (ieee80211_sdata_running(sdata)) {
list_for_each_entry(key, &sdata->key_list, list) {
- increment_tailroom_need_count(sdata);
+ if (!(key->flags & KEY_FLAG_TAINTED))
+ increment_tailroom_need_count(sdata);
ieee80211_key_enable_hw_accel(key);
}
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ad53dedd929c..b72345c779c0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -6161,6 +6161,98 @@ static bool ieee80211_get_dtim(const struct cfg80211_bss_ies *ies,
return true;
}
+static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data)
+{
+ if (bm_size == 1)
+ return *data;
+
+ return get_unaligned_le16(data);
+}
+
+static int
+ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_ttlm_elem *ttlm,
+ struct ieee80211_adv_ttlm_info *ttlm_info)
+{
+ /* The element size was already validated in
+ * ieee80211_tid_to_link_map_size_ok()
+ */
+ u8 control, link_map_presence, map_size, tid;
+ u8 *pos;
+
+ memset(ttlm_info, 0, sizeof(*ttlm_info));
+ pos = (void *)ttlm->optional;
+ control = ttlm->control;
+
+ if ((control & IEEE80211_TTLM_CONTROL_DIRECTION) !=
+ IEEE80211_TTLM_DIRECTION_BOTH) {
+ sdata_info(sdata, "Invalid advertised T2L map direction\n");
+ return -EINVAL;
+ }
+
+ link_map_presence = *pos;
+ pos++;
+
+ if (control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT) {
+ ttlm_info->switch_time = get_unaligned_le16(pos);
+
+ /* Since ttlm_info->switch_time == 0 means no switch time, bump
+ * it by 1.
+ */
+ if (!ttlm_info->switch_time)
+ ttlm_info->switch_time = 1;
+
+ pos += 2;
+ }
+
+ if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) {
+ ttlm_info->duration = pos[0] | pos[1] << 8 | pos[2] << 16;
+ pos += 3;
+ }
+
+ if (control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP) {
+ ttlm_info->map = 0xffff;
+ return 0;
+ }
+
+ if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE)
+ map_size = 1;
+ else
+ map_size = 2;
+
+ /* According to Draft P802.11be_D3.0 clause 35.3.7.1.7, an AP MLD shall
+ * not advertise a TID-to-link mapping that does not map all TIDs to the
+ * same link set, reject frame if not all links have mapping
+ */
+ if (link_map_presence != 0xff) {
+ sdata_info(sdata,
+ "Invalid advertised T2L mapping presence indicator\n");
+ return -EINVAL;
+ }
+
+ ttlm_info->map = ieee80211_get_ttlm(map_size, pos);
+ if (!ttlm_info->map) {
+ sdata_info(sdata,
+ "Invalid advertised T2L map for TID 0\n");
+ return -EINVAL;
+ }
+
+ pos += map_size;
+
+ for (tid = 1; tid < 8; tid++) {
+ u16 map = ieee80211_get_ttlm(map_size, pos);
+
+ if (map != ttlm_info->map) {
+ sdata_info(sdata, "Invalid advertised T2L map for tid %d\n",
+ tid);
+ return -EINVAL;
+ }
+
+ pos += map_size;
+ }
+ return 0;
+}
+
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
struct ieee802_11_elems *elems,
@@ -6192,8 +6284,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
continue;
valid_links |= BIT(link_id);
- if (assoc_data->link[link_id].disabled)
- dormant_links |= BIT(link_id);
if (link_id != assoc_data->assoc_link_id) {
err = ieee80211_sta_allocate_link(sta, link_id);
@@ -6202,6 +6292,33 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
}
}
+ /*
+ * We do not support setting a negotiated TTLM during
+ * association. As such, we can assume that if there is a TTLM,
+ * then it is the currently active advertised TTLM.
+ * In that case, there must be exactly one TTLM that does not
+ * have a switch time set. This mapping should also leave us
+ * with at least one usable link.
+ */
+ if (elems->ttlm_num > 1) {
+ sdata_info(sdata,
+ "More than one advertised TTLM in association response\n");
+ goto out_err;
+ } else if (elems->ttlm_num == 1) {
+ if (ieee80211_parse_adv_t2l(sdata, elems->ttlm[0],
+ &sdata->u.mgd.ttlm_info) ||
+ sdata->u.mgd.ttlm_info.switch_time != 0 ||
+ !(valid_links & sdata->u.mgd.ttlm_info.map)) {
+ sdata_info(sdata,
+ "Invalid advertised TTLM in association response\n");
+ goto out_err;
+ }
+
+ sdata->u.mgd.ttlm_info.active = true;
+ dormant_links =
+ valid_links & ~sdata->u.mgd.ttlm_info.map;
+ }
+
ieee80211_vif_set_links(sdata, valid_links, dormant_links);
}
@@ -6992,95 +7109,6 @@ static void ieee80211_tid_to_link_map_work(struct wiphy *wiphy,
sdata->u.mgd.ttlm_info.switch_time = 0;
}
-static u16 ieee80211_get_ttlm(u8 bm_size, u8 *data)
-{
- if (bm_size == 1)
- return *data;
- else
- return get_unaligned_le16(data);
-}
-
-static int
-ieee80211_parse_adv_t2l(struct ieee80211_sub_if_data *sdata,
- const struct ieee80211_ttlm_elem *ttlm,
- struct ieee80211_adv_ttlm_info *ttlm_info)
-{
- /* The element size was already validated in
- * ieee80211_tid_to_link_map_size_ok()
- */
- u8 control, link_map_presence, map_size, tid;
- u8 *pos;
-
- memset(ttlm_info, 0, sizeof(*ttlm_info));
- pos = (void *)ttlm->optional;
- control = ttlm->control;
-
- if ((control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP) ||
- !(control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT))
- return 0;
-
- if ((control & IEEE80211_TTLM_CONTROL_DIRECTION) !=
- IEEE80211_TTLM_DIRECTION_BOTH) {
- sdata_info(sdata, "Invalid advertised T2L map direction\n");
- return -EINVAL;
- }
-
- link_map_presence = *pos;
- pos++;
-
- ttlm_info->switch_time = get_unaligned_le16(pos);
-
- /* Since ttlm_info->switch_time == 0 means no switch time, bump it
- * by 1.
- */
- if (!ttlm_info->switch_time)
- ttlm_info->switch_time = 1;
-
- pos += 2;
-
- if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) {
- ttlm_info->duration = pos[0] | pos[1] << 8 | pos[2] << 16;
- pos += 3;
- }
-
- if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE)
- map_size = 1;
- else
- map_size = 2;
-
- /* According to Draft P802.11be_D3.0 clause 35.3.7.1.7, an AP MLD shall
- * not advertise a TID-to-link mapping that does not map all TIDs to the
- * same link set, reject frame if not all links have mapping
- */
- if (link_map_presence != 0xff) {
- sdata_info(sdata,
- "Invalid advertised T2L mapping presence indicator\n");
- return -EINVAL;
- }
-
- ttlm_info->map = ieee80211_get_ttlm(map_size, pos);
- if (!ttlm_info->map) {
- sdata_info(sdata,
- "Invalid advertised T2L map for TID 0\n");
- return -EINVAL;
- }
-
- pos += map_size;
-
- for (tid = 1; tid < 8; tid++) {
- u16 map = ieee80211_get_ttlm(map_size, pos);
-
- if (map != ttlm_info->map) {
- sdata_info(sdata, "Invalid advertised T2L map for tid %d\n",
- tid);
- return -EINVAL;
- }
-
- pos += map_size;
- }
- return 0;
-}
-
static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems,
u64 beacon_ts)
@@ -9737,7 +9765,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
req, true, i,
&assoc_data->link[i].conn);
assoc_data->link[i].bss = link_cbss;
- assoc_data->link[i].disabled = req->links[i].disabled;
if (!bss->uapsd_supported)
uapsd_supported = false;
@@ -10719,8 +10746,6 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata,
&data->link[link_id].conn);
data->link[link_id].bss = link_cbss;
- data->link[link_id].disabled =
- req->add_links[link_id].disabled;
data->link[link_id].elems =
(u8 *)req->add_links[link_id].elems;
data->link[link_id].elems_len =
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5ef315ed3b0f..4823c8d45639 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -347,8 +347,13 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
mgmt->da))
return;
} else {
- /* Beacons are expected only with broadcast address */
- if (!is_broadcast_ether_addr(mgmt->da))
+ /*
+ * Non-S1G beacons are expected only with broadcast address.
+ * S1G beacons only carry the SA so no DA check is required
+ * nor possible.
+ */
+ if (!ieee80211_is_s1g_beacon(mgmt->frame_control) &&
+ !is_broadcast_ether_addr(mgmt->da))
return;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c961cd42a832..03efd45c007f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12241,9 +12241,6 @@ static int nl80211_process_links(struct cfg80211_registered_device *rdev,
return -EINVAL;
}
}
-
- links[link_id].disabled =
- nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]);
}
return 0;
@@ -12423,13 +12420,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
goto free;
}
- if (req.links[req.link_id].disabled) {
- GENL_SET_ERR_MSG(info,
- "cannot have assoc link disabled");
- err = -EINVAL;
- goto free;
- }
-
if (info->attrs[NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS])
req.ext_mld_capa_ops =
nla_get_u16(info->attrs[NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS]);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 27e8a2f52f04..4f581aed45b7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1561,12 +1561,14 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
tmp = result;
tmp *= SCALE;
do_div(tmp, mcs_divisors[rate->mcs]);
- result = tmp;
/* and take NSS, DCM into account */
- result = (result * rate->nss) / 8;
+ tmp *= rate->nss;
+ do_div(tmp, 8);
if (rate->he_dcm)
- result /= 2;
+ do_div(tmp, 2);
+
+ result = tmp;
return result / 10000;
}