[PATCH ath-current 6/8] wifi: ath12k: do not advertise MLD peer ID for firmware-allocate devices
Baochen Qiang
baochen.qiang at oss.qualcomm.com
Mon Jul 13 00:33:21 PDT 2026
ath12k_peer_assoc_h_mlo() unconditionally sets ml->peer_id_valid and copies
ahsta->ml_peer_id (with the ATH12K_PEER_ML_ID_VALID bookkeeping bit masked
off) into the WMI_PEER_ASSOC_CMDID ML params, which causes
ath12k_wmi_send_peer_assoc_cmd() to set ATH12K_WMI_FLAG_MLO_PEER_ID_VALID.
This needs to be gated on chips where the firmware allocates the MLD peer
ID:
- WCN7850/QCC2072 firmware always picks the ID itself and does not honor
a host-supplied one, so the value would be silently ignored anyway;
- QCC2072 firmware additionally crashes during MLO disconnect when
ATH12K_WMI_FLAG_MLO_PEER_ID_VALID was set in the preceding peer assoc,
so the bit must not be sent at all.
Branch on ah->host_alloc_ml_id:
- When true (QCN9274 etc.), behavior is unchanged: peer_id_valid is set
and the raw ahsta->ml_peer_id (without the VALID bit) is sent down.
- When false (WCN7850, QCC2072), peer_id_valid stays unset and
ml_peer_id is sent as 0. The firmware ignores both fields and reports
the ID it allocated through HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP.
The early-return on ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID only
applies on the host-alloc path, since on the firmware-alloc path the value
is ATH12K_MLO_PEER_ID_PENDING here, not INVALID.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Signed-off-by: Baochen Qiang <baochen.qiang at oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/mac.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 9e5fcbf8c730..8cd5e9b15db5 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -3529,11 +3529,16 @@ static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
struct ath12k_sta *ahsta = arsta->ahsta;
struct ath12k_link_sta *arsta_p;
struct ath12k_link_vif *arvif;
+ struct ath12k_hw *ah = arsta->arvif->ar->ah;
unsigned long links;
u8 link_id;
int i;
- if (!sta->mlo || ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID)
+ if (!sta->mlo)
+ return;
+
+ if (ah->host_alloc_ml_id &&
+ ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID)
return;
ml->enabled = true;
@@ -3541,16 +3546,25 @@ static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
/* For now considering the primary umac based on assoc link */
ml->primary_umac = arsta->is_assoc_link;
- ml->peer_id_valid = true;
+ /*
+ * Only chips that allocate the MLD peer ID on the host send a valid
+ * ml_peer_id in WMI_PEER_ASSOC_CMDID. For chips where the firmware
+ * picks the ID, leave peer_id_valid false to avoid unexpected issues.
+ */
+ ml->peer_id_valid = ah->host_alloc_ml_id;
ml->logical_link_idx_valid = true;
ether_addr_copy(ml->mld_addr, sta->addr);
ml->logical_link_idx = arsta->link_idx;
/*
* WMI_MLO_PEER_ASSOC_PARAMS expects the raw ML peer ID without
- * the host-side ATH12K_PEER_ML_ID_VALID bookkeeping bit.
+ * the host-side ATH12K_PEER_ML_ID_VALID bookkeeping bit. For chips
+ * where the firmware allocates the ID, the field is unused (the
+ * firmware always allocates regardless of the value here); send 0
+ * to make that intent explicit.
*/
- ml->ml_peer_id = ahsta->ml_peer_id & ~ATH12K_PEER_ML_ID_VALID;
+ ml->ml_peer_id = ah->host_alloc_ml_id ?
+ (ahsta->ml_peer_id & ~ATH12K_PEER_ML_ID_VALID) : 0;
ml->ieee_link_id = arsta->link_id;
ml->num_partner_links = 0;
ml->eml_cap = sta->eml_cap;
--
2.25.1
More information about the ath12k
mailing list