1: 3fdbe876f648 ! 1: ce5d358e2d9c wifi: ath12k: allocate the AFC memory region requested by firmware @@ Metadata Author: Goran Sustek   ## Commit message ## - wifi: ath12k: allocate the AFC memory region requested by firmware + wifi: ath12k: report no AFC memory region to firmware  QCN9274 firmware WLAN.WBE.1.6-01243 requests a target memory segment of type 0xa at every boot. The driver does not know this type, so it logs @@ Commit message and answers the request with a NULL address but the requested size.  Type 0xa is the AFC region: QMI_WLFW_AFC_MEM_V01 = 10 in Qualcomm's - wlan_firmware_service_v01.h. The firmware asks for 8 KiB, one 4 KiB - slot per radio, where the host places the answer of an Automated - Frequency Coordination server for 6 GHz Standard Power operation. + wlan_firmware_service_v01.h. The firmware asks for 8 KiB, where the + host places the response of an Automated Frequency Coordination server + for 6 GHz Standard Power operation. ath12k does not support AFC.  - The firmware's handler of the memory response records the reported - address and marks the region as provided whenever the size is - non-zero; it does not check for a zero address. With the current - NULL answer the firmware therefore holds a region at bus address 0. - This driver never enables AFC and no misbehaviour has been observed, - but the firmware state is wrong. + The firmware treats a region as provided whenever its size is non-zero; + it does not check the address. With the current answer it therefore + takes bus address 0 as its AFC region and maps it for its own use.  - Name the type and allocate it like the other host regions, bounded to - two 4 KiB slots. This removes the warning and gives the firmware a - valid region. An oversized request keeps today's behaviour with a - warning. + Name the type and answer it with size 0, so that the firmware sees no + AFC region, and log this at debug level instead of warning. No memory + is allocated. With this answer the firmware sends the memory ready + indication, reaches firmware ready and brings up all radios.  Tested as part of the series.  @@ drivers/net/wireless/ath/ath12k/qmi.c: static int ath12k_qmi_alloc_target_mem_ch goto err; break;  + case AFC_REGION_TYPE: -+ /* Firmware requests the AFC region at every boot, even -+ * when the 6 GHz radio does not use Standard Power. It -+ * treats a non-zero size as a provided region, so hand -+ * it real memory instead of a NULL address. ++ /* The host does not support AFC. Firmware treats a ++ * region with a non-zero size as provided, so report ++ * size 0 instead of address 0 with the requested size.  + */ -+ if (chunk->size > ATH12K_QMI_AFC_MEM_SIZE) { -+ ath12k_warn(ab, "AFC memory request of %u B exceeds %u B, not allocated\n", -+ chunk->size, ATH12K_QMI_AFC_MEM_SIZE); -+ chunk->paddr = 0; -+ chunk->v.addr = NULL; -+ break; -+ } -+ ret = ath12k_qmi_alloc_chunk(ab, chunk); -+ if (ret) -+ goto err; ++ ath12k_dbg(ab, ATH12K_DBG_QMI, ++ "qmi AFC memory region of %u B not provided\n", ++ chunk->size); ++ chunk->paddr = 0; ++ chunk->v.addr = NULL; ++ chunk->size = 0;  + break; case MLO_GLOBAL_MEM_REGION_TYPE: mlo_size += chunk->size; if (ag->mlo_mem.mlo_mem_size &&  ## drivers/net/wireless/ath/ath12k/qmi.h ## -@@ - #define ATH12K_QMI_BDF_EXT_STR_LENGTH 0x20 - #define ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01 4 - #define ATH12K_QMI_DEVMEM_CMEM_INDEX 0 -+/* AFC region: one 4 KiB slot per radio, at most two radios */ -+#define ATH12K_QMI_AFC_MEM_SIZE (2 * 0x1000) -  - #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 - #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037  @@ drivers/net/wireless/ath/ath12k/qmi.h: enum ath12k_qmi_target_mem { CALDB_MEM_REGION_TYPE = 0x4, MLO_GLOBAL_MEM_REGION_TYPE = 0x8, 2: 81d05e889338 ! 2: 6389719dee9c wifi: ath12k: skip unknown direct buffer ring module IDs @@ Metadata ## Commit message ## wifi: ath12k: skip unknown direct buffer ring module IDs  - Newer firmware may advertise direct buffer rings for modules the - driver does not know. QCN9274 firmware WLAN.WBE.1.6-01243 lists - module 2, and ath12k_wmi_dma_ring_caps() treats it as fatal: + QCN9274 firmware WLAN.WBE.1.6-01243 advertises direct buffer rings for + module IDs 2 (CV upload) and 3 (Wi-Fi radar), one entry per radio. + ath12k_wmi_dma_ring_caps() treats any ID at or above + WMI_DIRECT_BUF_MAX as fatal:  ath12k_wifi7_pci 0000:06:00.0: Invalid module id 2 ath12k_wifi7_pci 0000:06:00.0: failed to parse tlv -22 @@ Commit message rest of the service ready ext event. Initialisation continues only because the service ready ext2 event completes it.  - Skip unknown module IDs with a debug message instead; the driver only - sets up rings for the modules it implements. Store the accepted - entries contiguously and set num_db_cap to the number actually stored: - ath12k_wmi_alloc_dbring_caps() zero-fills the array, so a hole left at - the index of a skipped entry would read as a spectral ring with zero - sizes. + An unknown ID is not an error. The firmware uses a direct buffer ring + only after the host configures it with WMI_PDEV_DMA_RING_CFG_REQ_CMDID, + and the host does that only for a feature it implements. Skip unknown + module IDs with a debug message instead.  - Tested as part of the series. + Store the accepted entries contiguously and set num_db_cap to the + number actually stored. ath12k_wmi_alloc_dbring_caps() zero-fills the + array, so a skipped entry left in place would read as a spectral ring + with zero sizes. No code reads db_caps today, but a future spectral + user would.  + This follows Nazar Mokrynskyi's earlier version, with the separate + count of stored entries that Jeff Johnson suggested in its review. + + Link: https://lore.kernel.org/linux-wireless/20260505172415.566328-3-nazar@mokrynskyi.com/ + Suggested-by: Jeff Johnson  Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1 Signed-off-by: Goran Sustek   @@ drivers/net/wireless/ath/ath12k/wmi.c: static int ath12k_wmi_dma_ring_caps(struc  - goto free_dir_buff;  + module_id = le32_to_cpu(dma_caps[i].module_id);  + -+ /* Newer firmware may advertise rings for modules this driver -+ * does not know yet. Skip them; the driver only sets up rings -+ * for the modules it implements. ++ /* Firmware may advertise rings for modules this driver ++ * does not implement. It uses a ring only after the host ++ * configures it, so skipping the entry is safe.  + */  + if (module_id >= WMI_DIRECT_BUF_MAX) {  + ath12k_dbg(ab, ATH12K_DBG_WMI, 3: a80f93b81f35 < -: ------------ wifi: ath12k: name direct buffer ring modules 2 and 3