]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: ath12k: do not advertise MLD peer ID for firmware-allocate devices
authorBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Mon, 20 Jul 2026 06:43:27 +0000 (14:43 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 27 Jul 2026 15:00:43 +0000 (08:00 -0700)
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>
drivers/net/wireless/ath/ath12k/mac.c

index 51641c5ff265a344c97d6e58386a0e3fce24d0c9..1004c290e5d0e015bbfa3e63d38ef9a91a04546e 100644 (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;