wifi: ath12k: do not advertise MLD peer ID for firmware-allocate devices

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@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260720-ath12k-fw-allocated-ml-peer-id-v2-6-630632758a80@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Baochen Qiang 2026-07-20 14:43:27 +08:00 committed by Jeff Johnson
parent 378e659029
commit 1726a7a10c

View File

@ -3533,11 +3533,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;
@ -3545,16 +3550,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;