From nobody Sun Dec 14 11:14:57 2025 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAE0C335086 for ; Wed, 5 Nov 2025 17:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762363354; cv=none; b=qPtASyIH8VfmCYFuGDqnLWK83bD0nLYvEjMpo77IkB9tMCO+z1uo+9pnAlIN6CKR/j0jIYipNdHADzNAaq7803SNtymCxfGu8EbJ7s5pqDo5bFMoCq4WyZitLvf3iATj8iq/RBCglcDmKGHsDKqvLXN3YaCRT99S1i5sq5OIUiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762363354; c=relaxed/simple; bh=5KQqtMoLixSs1ft+qPtIztREZGWdfQkFybMN6GvgnbQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KXXsv2ErNQpPxQA4GYywojKP89SUE1eaPC82h6q9k5Iu8GwYdJcIRYqGDRFjjhj0NiDrGShWcFi574Wgf6c7I6F0qpQSGwyyJ2y0C5MUxHU/BJMJSqYBuzDTHiss8/FqXOk85kKzcw39AuvfaV6kiyrKZGCJrc7wUJzXFtu85Is= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=kOfttD1z; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=YidjOKqW; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="kOfttD1z"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="YidjOKqW" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5A5D5pOG4056238 for ; Wed, 5 Nov 2025 17:22:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=KeVshtHCZ35 30glQM5ntY9XB0frGjHklSQGuyQPrwt4=; b=kOfttD1zkm8Ev963yoRjYpGiYt3 R6rM5KnMY9Cajzp1MllrziV9MwpsaP2jOjsGVxFBfQkoHV5Q8piejBG31Qyxncbf Y2kn5UUlUXbOb9g1k5rv3m+V+YTcBFwJxf2ILkzpuT4Rg4nGEWBIB09UPIn9kNLK RJxEUWUpesYrXFXSNOcr4wBWhfW/iKH4D3TrRziFdMSCOTF5iTQbJpdMQVY95SZH c/jBgP5lCB3iz1mlgi/VWW3OPnsd672VmOTMbqQTqOsuAa18/fHlrL/vmEtYjsv3 MkO9EYutYeeMFwhJwEwvWyq69gzI6bLl1dWIFis47BRx/uxfkQSXdKz2Krw== Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4a7yp622qq-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 05 Nov 2025 17:22:31 +0000 (GMT) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-77f610f7325so93904b3a.1 for ; Wed, 05 Nov 2025 09:22:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1762363351; x=1762968151; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KeVshtHCZ3530glQM5ntY9XB0frGjHklSQGuyQPrwt4=; b=YidjOKqWc0FgKwGed4cFZm3WCU129nYh4oQdeUFWDALNpnz/1IrOC/w+rXKvKHPMx6 SLYr5jxWKSzFJjdF7Ztg7XAnErCYTKCl7+d1Ucy//iM9pRGdgrF2k8QZTabD73EZ/bVk RUl0VCcllgD5msIKBhTRyV2OBOBNUsLBpODx59rmbBG7LF3jwZUAgPfsQnwqMG9XPhkd SiqLLYLvFXdSC4aZ6uR3fy3ieRN1Sei/pZUcjpD0QlImdbWpmOtjvzozUHLsNNh1k2Xb tcrF6PevuPjDd6MIg1A3MBU22f0yf1wdrLZVIQ5/4rKkrie/yCc/HjiINLOfDNfIkgJR aPbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762363351; x=1762968151; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KeVshtHCZ3530glQM5ntY9XB0frGjHklSQGuyQPrwt4=; b=av/+qt/YoQzG6errTGFzCLbHqZr/tbBfhMkUvBGnBcxD/x6ONh96l/I1K/2055c8MG O1eLHEYxaETjQNyXOnkugUYN8QsHMKsOhEkTXIcj8pYZfZGhdis0hWrUW/P42iAYDpEn m+X+BL8FaLXP7z2Z9O4llzaXq8ScUo9KhOxXVFkkUxlNZ4pLLe8v0uVlpIf1ncoSGqK5 ctUOmO8S8MtIAQSYxTycZUU38mSFrOucJiEHQhinpz6kSMPlrYqbGzaMsFR7iPnSMjsX dE/+jUNoiMBiHY4I5OmxvljhSmpKQy2ZrCNrLIzVOPnDpZjtDmsocB32Kf6pBW/N3WKO HrWA== X-Forwarded-Encrypted: i=1; AJvYcCU9+aNGl9U/TcZIeNmxa8+7iqmWby6AVTgJxVkOFxiSpfKPmUz/IONLwHBZZvmqlCYrJ9InEHx0myg+VBY=@vger.kernel.org X-Gm-Message-State: AOJu0Yyrjc4IIy4UgA0F/yDjoed8NJ0q25nyhUN0904Eyiy7Q5Hynubp n0pHItftR1a/oyqPykba1Tq0H+sRms9td9O8NXtv9yakx5WD0YqKU5ELKddoy9n2qDvO1UH9FIS 4s2Ux3s8pBuLxox9Ce6CdW3UDOl63exZETwMPxLnsx4AS9MJfWox/nOoQOAqjKT1XCqk= X-Gm-Gg: ASbGncsrNgvgZEiZPds7Y4/BEKen6sSRQoLkicoiA2Ke9yuz3Gjk9DrCwl3UcZGb0rJ yG+O6AW+E4d9r/3vf/YOVQZlDPJ6Id+FZ7HocBiFJBK8eWk+Dku0jpMzySgxeFNHV/MDu4tI+1D vbCjlH+/N2xcsTKxeQJFoBbVZWZH6sKlDSBYw7C5pCXILTdK5RqnE21RkJt6xjHXPLt+s+Udu13 zY6IJQLOienqwkY2Xo4fw5YRirzqb9FREu4M5itzUXc36nAtm9FWob9bSOF/wn0NuvQ1j8dOt/b TKhweS8xtSjg/f9Bk4GByiu5tm7K5JujfNGS0glQ9hOcKNsdc0BHDJ/ljJ3NGp/RvuhgTwtNz4v TRwPkAPIQb78fAh4xGwpqvEBV4vd0E2YDTfqywL0b2Th5 X-Received: by 2002:a05:6a00:c93:b0:780:fff4:f7db with SMTP id d2e1a72fcca58-7ae1ef998cfmr4995604b3a.15.1762363350269; Wed, 05 Nov 2025 09:22:30 -0800 (PST) X-Google-Smtp-Source: AGHT+IEFRrgFLPe3pW+2d0sEVrNGAKtbS4pj4oNIhdOGG8J99aitMheEbN0HxSSBTQEUVmRT8qNGAQ== X-Received: by 2002:a05:6a00:c93:b0:780:fff4:f7db with SMTP id d2e1a72fcca58-7ae1ef998cfmr4995550b3a.15.1762363349636; Wed, 05 Nov 2025 09:22:29 -0800 (PST) Received: from hu-yuzha-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7af48d83c20sm518014b3a.62.2025.11.05.09.22.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:22:28 -0800 (PST) From: "Yu Zhang(Yuriy)" To: jjohnson@kernel.org Cc: baochen.qiang@oss.qualcomm.com, linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, Yu Zhang , Vasanthakumar Thiagarajan Subject: [PATCH ath-next v3 1/6] wifi: ath11k: Add initialization and deinitialization sequence for CFR module Date: Wed, 5 Nov 2025 09:22:21 -0800 Message-Id: <20251105172226.3182968-2-yu.zhang@oss.qualcomm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251105172226.3182968-1-yu.zhang@oss.qualcomm.com> References: <20251105172226.3182968-1-yu.zhang@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: VGqFMPLyxSAlY8EpTseGlzpgv2YJ2v14 X-Proofpoint-ORIG-GUID: VGqFMPLyxSAlY8EpTseGlzpgv2YJ2v14 X-Authority-Analysis: v=2.4 cv=TsrrRTXh c=1 sm=1 tr=0 ts=690b87d7 cx=c_pps a=mDZGXZTwRPZaeRUbqKGCBw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=6UeiqGixMTsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=COk6AnOGAAAA:8 a=EUspDBNiAAAA:8 a=sTJiG90S0w3vqaoQ0_0A:9 a=zc0IvFSfCIW2DFIPzwfm:22 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTA1MDEzNSBTYWx0ZWRfX7zPbF0ctLfhI v0M+N2u0sDkOSIAP0degn7tLv6VSwOleEfR65DU0OfUGaUzGcoL8JXeb9VrMofLJFVtODHGa3EO g6yvyTuhLKsFaLrSyPNlDGGfm3kZW1JJZYYjcqhVa6DdHzPysknqoFe75pCaCluKN+rTWdUTYvj j0zJ6i/M4fe1JZqhSMmOX1ZI7X71OkKX42kdhuxaSly1PyW9JxTllyMHDhzSUCQ/maoLBMKVnuz pB5utGs1sBlrP5cehCyaA7PkNtGQ7/AF2iKJBUIiPJB8OI8pdIpZMnchDtC16ZFPZxOf4FPGWBy 1nVBO7H9FD6hQtsKUh0L4La0KKIp2CYZU0oDa7k2nGAi2wk9tjgMVJprTnCwAQwgN5cegghisi0 xhHGunU+1b+SDzbsRkkVP6tRTAs3gg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-05_06,2025-11-03_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 impostorscore=0 adultscore=0 clxscore=1015 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511050135 Content-Type: text/plain; charset="utf-8" From: Venkateswara Naralasetty Channel Frequency Response (CFR) module will be initialized only when the following criteria passes: * Enabled CFR support for the hardware through the hardware param 'cfr_support' * WMI service enabled for the CFR support 'WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT' Also, provide a configuration option CONFIG_ATH11K_CFR to enable CFR feature support during the compilation time. CFR module initialization includes Direct Buffer(DB) ring initialization where hardware uses the DB ring buffers to copy CFR data to host. Number of buffers and buffer size of the ring is based on the DB ring capabilities advertised by the firmware through WMI service ready. Also ring configurations are sent to firmware through ath11k_dbring_wmi_cfg_setup(). Predefine ath11k_cfr_dma_hdr, ath11k_look_up_table, and ath11k_cfr structs and fields for subsequent patches. Tested-on: IPQ8074 hw2.0 PCI IPQ8074 WLAN.HK.2.5.0.1-00991-QCAHKSWPL_SILICO= NZ-1 Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04685-QCAHSPSWPL_V1_V2_SILICONZ_I= OE-1 Signed-off-by: Venkateswara Naralasetty Co-developed-by: Yu Zhang (Yuriy) Signed-off-by: Yu Zhang (Yuriy) Reviewed-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath11k/Kconfig | 11 ++ drivers/net/wireless/ath/ath11k/Makefile | 1 + drivers/net/wireless/ath/ath11k/cfr.c | 170 +++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 85 ++++++++++++ drivers/net/wireless/ath/ath11k/core.c | 41 +++++- drivers/net/wireless/ath/ath11k/core.h | 8 +- drivers/net/wireless/ath/ath11k/dbring.c | 40 ++++-- drivers/net/wireless/ath/ath11k/dbring.h | 6 +- drivers/net/wireless/ath/ath11k/hal.c | 3 +- drivers/net/wireless/ath/ath11k/hw.h | 5 +- drivers/net/wireless/ath/ath11k/wmi.h | 1 + 11 files changed, 354 insertions(+), 17 deletions(-) create mode 100644 drivers/net/wireless/ath/ath11k/cfr.c create mode 100644 drivers/net/wireless/ath/ath11k/cfr.h diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless= /ath/ath11k/Kconfig index 659ef134ef16..47dfd39caa89 100644 --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -58,3 +58,14 @@ config ATH11K_SPECTRAL Enable ath11k spectral scan support =20 Say Y to enable access to the FFT/spectral data via debugfs. + +config ATH11K_CFR + bool "ath11k channel frequency response support" + depends on ATH11K_DEBUGFS + depends on RELAY + help + Enable ath11k channel frequency response dump support. + This option exposes debugfs nodes that will allow the user + to enable, disable, and dump data. + + Say Y to enable CFR data dump collection via debugfs. diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireles= s/ath/ath11k/Makefile index d9092414b362..b1435fcf3e1b 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -28,6 +28,7 @@ ath11k-$(CONFIG_THERMAL) +=3D thermal.o ath11k-$(CONFIG_ATH11K_SPECTRAL) +=3D spectral.o ath11k-$(CONFIG_PM) +=3D wow.o ath11k-$(CONFIG_DEV_COREDUMP) +=3D coredump.o +ath11k-$(CONFIG_ATH11K_CFR) +=3D cfr.o =20 obj-$(CONFIG_ATH11K_AHB) +=3D ath11k_ahb.o ath11k_ahb-y +=3D ahb.o diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/a= th/ath11k/cfr.c new file mode 100644 index 000000000000..78e356672eba --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include "core.h" +#include "debug.h" + +static int ath11k_cfr_process_data(struct ath11k *ar, + struct ath11k_dbring_data *param) +{ + return 0; +} + +void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, + u32 buf_id) +{ + struct ath11k_cfr *cfr =3D &ar->cfr; + + if (cfr->lut) + cfr->lut[buf_id].dbr_address =3D paddr; +} + +static void ath11k_cfr_ring_free(struct ath11k *ar) +{ + struct ath11k_cfr *cfr =3D &ar->cfr; + + ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring); + ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring); +} + +static int ath11k_cfr_ring_alloc(struct ath11k *ar, + struct ath11k_dbring_cap *db_cap) +{ + struct ath11k_cfr *cfr =3D &ar->cfr; + int ret; + + ret =3D ath11k_dbring_srng_setup(ar, &cfr->rx_ring, + ATH11K_CFR_NUM_RING_ENTRIES, + db_cap->min_elem); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring: %d\n", ret); + return ret; + } + + ath11k_dbring_set_cfg(ar, &cfr->rx_ring, + ATH11K_CFR_NUM_RESP_PER_EVENT, + ATH11K_CFR_EVENT_TIMEOUT_MS, + ath11k_cfr_process_data); + + ret =3D ath11k_dbring_buf_setup(ar, &cfr->rx_ring, db_cap); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring buffer: %d\n", ret); + goto srng_cleanup; + } + + ret =3D ath11k_dbring_wmi_cfg_setup(ar, &cfr->rx_ring, WMI_DIRECT_BUF_CFR= ); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg: %d\n", ret); + goto buffer_cleanup; + } + + return 0; + +buffer_cleanup: + ath11k_dbring_buf_cleanup(ar, &cfr->rx_ring); +srng_cleanup: + ath11k_dbring_srng_cleanup(ar, &cfr->rx_ring); + return ret; +} + +void ath11k_cfr_deinit(struct ath11k_base *ab) +{ + struct ath11k_cfr *cfr; + struct ath11k *ar; + int i; + + if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) || + !ab->hw_params.cfr_support) + return; + + for (i =3D 0; i < ab->num_radios; i++) { + ar =3D ab->pdevs[i].ar; + cfr =3D &ar->cfr; + + if (!cfr->enabled) + continue; + + ath11k_cfr_ring_free(ar); + + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut =3D NULL; + cfr->enabled =3D false; + spin_unlock_bh(&cfr->lut_lock); + } +} + +int ath11k_cfr_init(struct ath11k_base *ab) +{ + struct ath11k_dbring_cap db_cap; + struct ath11k_cfr *cfr; + u32 num_lut_entries; + struct ath11k *ar; + int i, ret; + + if (!test_bit(WMI_TLV_SERVICE_CFR_CAPTURE_SUPPORT, ab->wmi_ab.svc_map) || + !ab->hw_params.cfr_support) + return 0; + + for (i =3D 0; i < ab->num_radios; i++) { + ar =3D ab->pdevs[i].ar; + cfr =3D &ar->cfr; + + ret =3D ath11k_dbring_get_cap(ar->ab, ar->pdev_idx, + WMI_DIRECT_BUF_CFR, &db_cap); + if (ret) + continue; + + idr_init(&cfr->rx_ring.bufs_idr); + spin_lock_init(&cfr->rx_ring.idr_lock); + spin_lock_init(&cfr->lock); + spin_lock_init(&cfr->lut_lock); + + num_lut_entries =3D min_t(u32, CFR_MAX_LUT_ENTRIES, db_cap.min_elem); + cfr->lut =3D kcalloc(num_lut_entries, sizeof(*cfr->lut), + GFP_KERNEL); + if (!cfr->lut) { + ret =3D -ENOMEM; + goto err; + } + + ret =3D ath11k_cfr_ring_alloc(ar, &db_cap); + if (ret) { + ath11k_warn(ab, "failed to init cfr ring for pdev %d: %d\n", + i, ret); + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut =3D NULL; + cfr->enabled =3D false; + spin_unlock_bh(&cfr->lut_lock); + goto err; + } + + cfr->lut_num =3D num_lut_entries; + cfr->enabled =3D true; + } + + return 0; + +err: + for (i =3D i - 1; i >=3D 0; i--) { + ar =3D ab->pdevs[i].ar; + cfr =3D &ar->cfr; + + if (!cfr->enabled) + continue; + + ath11k_cfr_ring_free(ar); + + spin_lock_bh(&cfr->lut_lock); + kfree(cfr->lut); + cfr->lut =3D NULL; + cfr->enabled =3D false; + spin_unlock_bh(&cfr->lut_lock); + } + return ret; +} diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/a= th/ath11k/cfr.h new file mode 100644 index 000000000000..3534176c3e01 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH11K_CFR_H +#define ATH11K_CFR_H + +#include "dbring.h" +#include "wmi.h" + +#define ATH11K_CFR_NUM_RESP_PER_EVENT 1 +#define ATH11K_CFR_EVENT_TIMEOUT_MS 1 +#define ATH11K_CFR_NUM_RING_ENTRIES 1 + +#define CFR_MAX_LUT_ENTRIES 136 + +#define HOST_MAX_CHAINS 8 + +struct ath11k_cfr_dma_hdr { + u16 info0; + u16 info1; + u16 sw_peer_id; + u16 phy_ppdu_id; +}; + +struct ath11k_look_up_table { + bool dbr_recv; + bool tx_recv; + u8 *data; + u32 data_len; + u16 dbr_ppdu_id; + u16 tx_ppdu_id; + dma_addr_t dbr_address; + struct ath11k_cfr_dma_hdr hdr; + u64 txrx_tstamp; + u64 dbr_tstamp; + u32 header_length; + u32 payload_length; + struct ath11k_dbring_element *buff; +}; + +struct ath11k_cfr { + struct ath11k_dbring rx_ring; + /* Protects cfr data */ + spinlock_t lock; + /* Protect for lut entries */ + spinlock_t lut_lock; + struct ath11k_look_up_table *lut; + u32 lut_num; + u64 tx_evt_cnt; + u64 dbr_evt_cnt; + u64 release_cnt; + u64 tx_peer_status_cfr_fail; + u64 tx_evt_status_cfr_fail; + u64 tx_dbr_lookup_fail; + u64 last_success_tstamp; + u64 flush_dbr_cnt; + u64 clear_txrx_event; + u64 cfr_dma_aborts; + bool enabled; +}; + +#ifdef CONFIG_ATH11K_CFR +int ath11k_cfr_init(struct ath11k_base *ab); +void ath11k_cfr_deinit(struct ath11k_base *ab); +void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, + u32 buf_id); +#else +static inline int ath11k_cfr_init(struct ath11k_base *ab) +{ + return 0; +} + +static inline void ath11k_cfr_deinit(struct ath11k_base *ab) +{ +} + +static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar, + dma_addr_t paddr, u32 buf_id) +{ +} +#endif /* CONFIG_ATH11K_CFR */ +#endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/= ath/ath11k/core.c index 2810752260f2..71926a774f57 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights res= erved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ =20 @@ -126,6 +125,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .smp2p_wow_exit =3D false, .support_dual_stations =3D false, .pdev_suspend =3D false, + .cfr_support =3D true, + .cfr_num_stream_bufs =3D 255, + .cfr_stream_buf_size =3D 8200, }, { .hw_rev =3D ATH11K_HW_IPQ6018_HW10, @@ -211,6 +213,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D false, .support_dual_stations =3D false, .pdev_suspend =3D false, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "qca6390 hw2.0", @@ -301,6 +306,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D true, .support_dual_stations =3D true, .pdev_suspend =3D false, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "qcn9074 hw1.0", @@ -385,6 +393,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D false, .support_dual_stations =3D false, .pdev_suspend =3D false, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "wcn6855 hw2.0", @@ -475,6 +486,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D true, .support_dual_stations =3D true, .pdev_suspend =3D false, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "wcn6855 hw2.1", @@ -563,6 +577,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D true, .support_dual_stations =3D true, .pdev_suspend =3D false, + .cfr_support =3D true, + .cfr_num_stream_bufs =3D 255, + .cfr_stream_buf_size =3D 8200, }, { .name =3D "wcn6750 hw1.0", @@ -646,6 +663,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D true, .support_dual_stations =3D false, .pdev_suspend =3D true, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .hw_rev =3D ATH11K_HW_IPQ5018_HW10, @@ -729,6 +749,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D false, .support_dual_stations =3D false, .pdev_suspend =3D false, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "qca2066 hw2.1", @@ -818,6 +841,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .smp2p_wow_exit =3D false, .support_fw_mac_sequence =3D true, .support_dual_stations =3D true, + .cfr_support =3D false, + .cfr_num_stream_bufs =3D 0, + .cfr_stream_buf_size =3D 0, }, { .name =3D "qca6698aq hw2.1", @@ -906,6 +932,9 @@ static const struct ath11k_hw_params ath11k_hw_params[]= =3D { .support_fw_mac_sequence =3D true, .support_dual_stations =3D true, .pdev_suspend =3D false, + .cfr_support =3D true, + .cfr_num_stream_bufs =3D 255, + .cfr_stream_buf_size =3D 8200, }, }; =20 @@ -1945,8 +1974,16 @@ static int ath11k_core_pdev_create(struct ath11k_bas= e *ab) goto err_thermal_unregister; } =20 + ret =3D ath11k_cfr_init(ab); + if (ret) { + ath11k_err(ab, "failed to init cfr %d\n", ret); + goto err_spectral_unregister; + } + return 0; =20 +err_spectral_unregister: + ath11k_spectral_deinit(ab); err_thermal_unregister: ath11k_thermal_unregister(ab); err_mac_unregister: @@ -1996,6 +2033,7 @@ static void ath11k_core_pdev_suspend_target(struct at= h11k_base *ab) =20 static void ath11k_core_pdev_destroy(struct ath11k_base *ab) { + ath11k_cfr_deinit(ab); ath11k_spectral_deinit(ab); ath11k_thermal_unregister(ab); ath11k_mac_unregister(ab); @@ -2208,6 +2246,7 @@ static int ath11k_core_reconfigure_on_crash(struct at= h11k_base *ab) mutex_lock(&ab->core_lock); ath11k_thermal_unregister(ab); ath11k_dp_pdev_free(ab); + ath11k_cfr_deinit(ab); ath11k_spectral_deinit(ab); ath11k_ce_cleanup_pipes(ab); ath11k_wmi_detach(ab); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/= ath/ath11k/core.h index e8780b05ce11..40fb7cee3e43 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights res= erved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ =20 #ifndef ATH11K_CORE_H @@ -35,6 +35,7 @@ #include "wow.h" #include "fw.h" #include "coredump.h" +#include "cfr.h" =20 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) =20 @@ -795,6 +796,11 @@ struct ath11k { bool ps_state_enable; bool ps_timekeeper_enable; s8 max_allowed_tx_power; + +#ifdef CONFIG_ATH11K_CFR + struct ath11k_cfr cfr; +#endif + bool cfr_enabled; }; =20 struct ath11k_band_cap { diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireles= s/ath/ath11k/dbring.c index 520d8b8662a2..ed2b781a6bab 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights res= erved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ =20 @@ -37,10 +36,10 @@ static void ath11k_dbring_fill_magic_value(struct ath11= k *ar, memset32(buffer, ATH11K_DB_MAGIC_VALUE, size); } =20 -static int ath11k_dbring_bufs_replenish(struct ath11k *ar, - struct ath11k_dbring *ring, - struct ath11k_dbring_element *buff, - enum wmi_direct_buffer_module id) +int ath11k_dbring_bufs_replenish(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_element *buff, + enum wmi_direct_buffer_module id) { struct ath11k_base *ab =3D ar->ab; struct hal_srng *srng; @@ -80,6 +79,9 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, goto err_idr_remove; } =20 + if (id =3D=3D WMI_DIRECT_BUF_CFR) + ath11k_cfr_lut_update_paddr(ar, paddr, buf_id); + buff->paddr =3D paddr; =20 cookie =3D FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, ar->pdev_idx) | @@ -155,12 +157,11 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, enum wmi_direct_buffer_module id) { struct ath11k_wmi_pdev_dma_ring_cfg_req_cmd param =3D {}; - int ret; + int ret, i; =20 if (id >=3D WMI_DIRECT_BUF_MAX) return -EINVAL; =20 - param.pdev_id =3D DP_SW2HW_MACID(ring->pdev_id); param.module_id =3D id; param.base_paddr_lo =3D lower_32_bits(ring->refill_srng.paddr); param.base_paddr_hi =3D upper_32_bits(ring->refill_srng.paddr); @@ -173,10 +174,23 @@ int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, param.num_resp_per_event =3D ring->num_resp_per_event; param.event_timeout_ms =3D ring->event_timeout_ms; =20 - ret =3D ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); - if (ret) { - ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); - return ret; + /* For single pdev, 2GHz and 5GHz use one DBR. */ + if (ar->ab->hw_params.single_pdev_only) { + for (i =3D 0; i < ar->ab->target_pdev_count; i++) { + param.pdev_id =3D ar->ab->target_pdev_ids[i].pdev_id; + ret =3D ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + return ret; + } + } + } else { + param.pdev_id =3D DP_SW2HW_MACID(ring->pdev_id); + ret =3D ath11k_wmi_pdev_dma_ring_cfg(ar, ¶m); + if (ret) { + ath11k_warn(ar->ab, "failed to setup db ring cfg\n"); + return ret; + } } =20 return 0; @@ -285,6 +299,10 @@ int ath11k_dbring_buffer_release_event(struct ath11k_b= ase *ab, pdev_idx =3D ev->fixed.pdev_id; module_id =3D ev->fixed.module_id; =20 + if (ab->hw_params.single_pdev_only && + pdev_idx < ab->target_pdev_count) + pdev_idx =3D 0; + if (pdev_idx >=3D ab->num_radios) { ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx); return -EINVAL; diff --git a/drivers/net/wireless/ath/ath11k/dbring.h b/drivers/net/wireles= s/ath/ath11k/dbring.h index 2f93b78a50df..0a380120f7a0 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.h +++ b/drivers/net/wireless/ath/ath11k/dbring.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ =20 #ifndef ATH11K_DBRING_H @@ -61,6 +61,10 @@ int ath11k_dbring_set_cfg(struct ath11k *ar, u32 event_timeout_ms, int (*handler)(struct ath11k *, struct ath11k_dbring_data *)); +int ath11k_dbring_bufs_replenish(struct ath11k *ar, + struct ath11k_dbring *ring, + struct ath11k_dbring_element *buff, + enum wmi_direct_buffer_module id); int ath11k_dbring_wmi_cfg_setup(struct ath11k *ar, struct ath11k_dbring *ring, enum wmi_direct_buffer_module id); diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/a= th/ath11k/hal.c index 0c797b8d0a27..e821e5a62c1c 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights res= erved. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #include @@ -184,7 +183,7 @@ static const struct hal_srng_config hw_srng_config_temp= late[] =3D { }, { /* RXDMA DIR BUF */ .start_ring_id =3D HAL_SRNG_RING_ID_RXDMA_DIR_BUF, - .max_rings =3D 1, + .max_rings =3D 2, .entry_size =3D 8 >> 2, /* TODO: Define the struct */ .lmac_ring =3D true, .ring_dir =3D HAL_SRNG_DIR_SRC, diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/at= h/ath11k/hw.h index 52d9f4c13b13..e13ca02a9d05 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights res= erved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ =20 #ifndef ATH11K_HW_H @@ -228,6 +228,9 @@ struct ath11k_hw_params { bool support_fw_mac_sequence; bool support_dual_stations; bool pdev_suspend; + bool cfr_support; + u32 cfr_num_stream_bufs; + u32 cfr_stream_buf_size; }; =20 struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/a= th/ath11k/wmi.h index 0f0de24a3840..7a55fe0879c0 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -981,6 +981,7 @@ enum wmi_tlv_pdev_param { WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE, WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE, WMI_PDEV_PARAM_MESH_MCAST_ENABLE, + WMI_PDEV_PARAM_PER_PEER_CFR_ENABLE =3D 0xa8, WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD =3D 0xbc, WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC =3D 0xbe, WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT =3D 0xc6, --=20 2.34.1