From nobody Tue Feb 10 05:27:21 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.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 939E533C51A for ; Wed, 5 Nov 2025 17:22:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762363361; cv=none; b=W+rzjK+Re8YNhU98aLXEngZTpiRChwJVwytSKJGuqAtyoUBJTXPvwNqtQbq9TYoCUk51zxyHvcKYuxrZ6XZZRdp6IqDP2x//5cvRDpkoiwH/Z7ZdZCCKHH7DCY8YIX2zeNB94wKMCITGWL+h7v7m0fUz1K6rD0zOaxiJ9P/kVDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762363361; c=relaxed/simple; bh=HOqt9BuedG5uKv1yKxuShwimEq1mdstx+e5yGAecMMU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GT3OVc5HdAopxg8yL+Nr3pS4ywXK0X9JajL+8AKgcSG+3OvyVf2ZQucXOrOVDcqf9WUkw7otQ6AJfYaonAxJz6gnJhyxADtqlBKVU523LCwSh4yPrGbh3OwfThEY21NUA6gLI7bEalNVYINhPXMIAI5bZ43MFgeGoAfbxLkezk4= 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=cU+phUa1; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=GfMaUepO; arc=none smtp.client-ip=205.220.168.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="cU+phUa1"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="GfMaUepO" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5A5H2uor1379703 for ; Wed, 5 Nov 2025 17:22:38 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=zDYaxendOKg BXNHSEYqdstxwAT0j4LcK+vc404gFmq4=; b=cU+phUa1nSd2vrpn7DV7LYO5cGF OHSrBv99yDi6KVRGpGLjHS5s7ykNhBKe8uwXDIWzTpkxOaiz347rkkd83S1zzf4L vGs9bQ9kTvmhpuFbrNhEOxZWNsKYDDNuDvah8RdKLuq8/smjWaoY+LqX4edjvh/x V1nphjiQ7k8uBAn259cRdHpkBtQsxzOdo3522+kum/cOsUYzs6pGg/HkIP9ExICc zvVTZltiUBhANxiDcG1pHBb0EmJhwLlHq4bPcPqRcz4MrLuEI9U2jhQF9/sglVbp zabXolZl5BN0Q8lD/kcZZ3vgpIPmsmuvSA0HGjfkGnX6Uc8tO91ni+wl5CQ== Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4a8amx82j0-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 05 Nov 2025 17:22:37 +0000 (GMT) Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-7ae220b9d18so82692b3a.2 for ; Wed, 05 Nov 2025 09:22:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1762363357; x=1762968157; 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=zDYaxendOKgBXNHSEYqdstxwAT0j4LcK+vc404gFmq4=; b=GfMaUepOcs4s4o5vh8oDWBLwnRSsfvg1nfjJMBlUHU19kw6/MJoj/lonnGnFY7PS/V 7hXIb8mx5CN9/73uTr/k8WPDIpMFzee7oF4Hc6zZXga0FxjTQvRr3mIyEvxzn5uTXTRJ gxz1i/SkXjyUog8DjSFGCv+f+J4ioD0BiI8hLxmyocxdnBuzJGhBPhDrxhEq9SMfnYOd oo9OY2eIDCKwAtB/iVxdiCL/npN/CHU8cSbxo3CdHx1BEl4AYbpxpeXB4SLfvOv+ybAQ jc8U/zpU4AfqfMeOmJAHMMz9omU9yUAxyFoybkz4Mnpab66T5EH45h8lDDWJnPDYyTbs +p0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762363357; x=1762968157; 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=zDYaxendOKgBXNHSEYqdstxwAT0j4LcK+vc404gFmq4=; b=DbdLhTTd1Gbc8w4vQfBCzquU4qP8Nvcvj0dYV0orBdY74Z+cx8c1bGfPGfgiOobJOQ HPeXtyVT127QIzp3KFd7bhvoRMr4rc9lxPsJqMY8w1wMFp+pSzrmMWeSMKtUnyDTi4ro XzSrdzDQSpoorP49gl3FG3SWxe5BhMfsh+hYpQOfHKUAUoE+FhhTuz30t4XoWFXSB1Ua Z/UMe1jslt5EbdEBBvgbqrfMPV+E44OHzF2/GfE81EggRHUSlbo2qb486mI2WGqHVSYu 6M5460PBBpEH+X6d14cKYkbA7lfud7stzPrg0bd93yE0Zkl5sl7Pp5psctQjKzlYT0wn Evmg== X-Forwarded-Encrypted: i=1; AJvYcCW6xTW0Iqq/KQhl7i7iQd+sdj1wkctcPIFz04mEXJJNzRlcUoRz9M5ntTFVqN0Sf3ziwO++I9oU6iWqo8s=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+9aXd4wAib+UuidkuftLtlrMNXtTbu439ecoOHOsB9wFC3nVf TsUVQ8meTxuY77Hm9/mcho2nTyUmRShlLroeB6opffbzUJ9EbvvgpYK8XHwp3rMGj+bPKrf16dK 42nRfyOkRdUynGIhD/Skoure0l9jNNhr2/5OPSgXVDEJJw6EGPwh5FjNhNXdwCGMVkIA= X-Gm-Gg: ASbGncvCfkrmIEkk9r6LPcqtEfdnzmKOk4pnGmPOoHMNusd46dqW4YsrjgoDa05vplC racjl1znhDkH3sdnBxVcYyVbVMggWa6z+biFqnV44abJ0Ofi0Feghnp1K+HTtmK/qbZQstze8MF 8RmQhoWPWB3kAPneV/Gb2I3VORsdOyVotfgvyjhUiWWXKiiQvMt7xncQQXmL/5L5yAUc1XFLx/y 9yAM0bdRoCNIj7UsxEpD8QUoW/VkR53yzyJd1E9iWuHRlGeTIE69bo4N+8nGpCrUGOAL3DRIvQt JqUdPSmz+w0HF55LSyRjsstZZaZnAJQUDV5Szl1s4bi263CJXvkwbqfwTdMDbrhE/4DU5QYrdY8 rPftKrLoaohs6C4hch1Sghqv4lzHBvs6kpZs2eolv3bWF X-Received: by 2002:a05:6a00:1ac6:b0:7ad:df61:e67a with SMTP id d2e1a72fcca58-7ae1f48d17cmr4215975b3a.22.1762363356874; Wed, 05 Nov 2025 09:22:36 -0800 (PST) X-Google-Smtp-Source: AGHT+IGuHkiMFhW7PI2amrhRkIUX0V7Y9Yv0M9IU6zLbW3SZkFglf8nG7gtIKmKWmIk9hfTfSV6R1A== X-Received: by 2002:a05:6a00:1ac6:b0:7ad:df61:e67a with SMTP id d2e1a72fcca58-7ae1f48d17cmr4215933b3a.22.1762363356264; Wed, 05 Nov 2025 09:22:36 -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.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:22:35 -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 6/6] wifi: ath11k: Register handler for CFR capture event Date: Wed, 5 Nov 2025 09:22:26 -0800 Message-Id: <20251105172226.3182968-7-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: kgz-YxvgcG_daGJ7nrT31Rv30HaVk7jP X-Authority-Analysis: v=2.4 cv=P443RyAu c=1 sm=1 tr=0 ts=690b87dd cx=c_pps a=rEQLjTOiSrHUhVqRoksmgQ==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=6UeiqGixMTsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=COk6AnOGAAAA:8 a=EUspDBNiAAAA:8 a=RXpQw9b9vDifZkLeuRoA:9 a=2VI0MkxyNR6bbpdq8BZq:22 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTA1MDEzNSBTYWx0ZWRfXxVF+zey5657U U8k94YbB29pycTqh8Fyf6TLCM3udwsD6Edvo27cWN5P44wnfVlQfsiqnLjWwTbVIaexDwbZAGuv 2vaogEt4rA1FSlwxRvkkSClKWH+evzdXFuOeoRf1pY5g94SCbwf9rN2TVlmR/q72xNzuky5ZNi4 B9zPmE6LMeiNkh0FsAZRrVj1nvEHQ6k31tY+kJtH6y4GNmijNmN3lMY1iC4qzob/mL04LlGrNO/ OaJlBJ7eJyaTeGVMS4ADjk+HavmfDGPmov9EHB+7aj3ccHSoc8fhg6D3ORUtHA6uwRtocSohlaw XZgAFLN+SvtcVwrY2EvWLd9i6nwPAlyxn/R91xlv+O0d6IepVbLs/9fsFQ7oG651JFd4ohKyBBx SfjLzgIYRSZ6P8nvkIlzqQTeBaInaw== X-Proofpoint-ORIG-GUID: kgz-YxvgcG_daGJ7nrT31Rv30HaVk7jP 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 clxscore=1015 adultscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 phishscore=0 malwarescore=0 bulkscore=0 lowpriorityscore=0 spamscore=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 Firmware sends CFR meta data through the WMI event WMI_PEER_CFR_CAPTURE_EVENT. Parse the meta data coming from the firmware and invoke correlate_and_relay function to correlate the CFR meta data with the CFR payload coming from the other WMI event WMI_PDEV_DMA_RING_BUF_RELEASE_EVENT. Release the buffer to user space once correlate and relay return success. 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/cfr.c | 145 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/cfr.h | 62 ++++++++++- drivers/net/wireless/ath/ath11k/wmi.c | 90 ++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 44 ++++++++ 4 files changed, 340 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/a= th/ath11k/cfr.c index ee7626bd4b1a..3a42e54ddf80 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -252,6 +252,151 @@ static int ath11k_cfr_process_data(struct ath11k *ar, return status; } =20 +static void ath11k_cfr_fill_hdr_info(struct ath11k *ar, + struct ath11k_csi_cfr_header *header, + struct ath11k_cfr_peer_tx_param *params) +{ + header->cfr_metadata_version =3D ATH11K_CFR_META_VERSION_4; + header->cfr_data_version =3D ATH11K_CFR_DATA_VERSION_1; + header->cfr_metadata_len =3D sizeof(struct cfr_metadata); + header->chip_type =3D ar->ab->hw_rev; + header->meta_data.status =3D FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, + params->status); + header->meta_data.capture_bw =3D params->bandwidth; + header->meta_data.phy_mode =3D params->phy_mode; + header->meta_data.prim20_chan =3D params->primary_20mhz_chan; + header->meta_data.center_freq1 =3D params->band_center_freq1; + header->meta_data.center_freq2 =3D params->band_center_freq2; + + /* + * CFR capture is triggered by the ACK of a QoS Null frame: + * - 20 MHz: Legacy ACK + * - 40/80/160 MHz: DUP Legacy ACK + */ + header->meta_data.capture_mode =3D params->bandwidth ? + ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK : ATH11K_CFR_CAPTURE_LEGACY_ACK; + header->meta_data.capture_type =3D params->capture_method; + header->meta_data.num_rx_chain =3D ar->num_rx_chains; + header->meta_data.sts_count =3D params->spatial_streams; + header->meta_data.timestamp =3D params->timestamp_us; + ether_addr_copy(header->meta_data.peer_addr, params->peer_mac_addr); + memcpy(header->meta_data.chain_rssi, params->chain_rssi, + sizeof(params->chain_rssi)); + memcpy(header->meta_data.chain_phase, params->chain_phase, + sizeof(params->chain_phase)); + memcpy(header->meta_data.agc_gain, params->agc_gain, + sizeof(params->agc_gain)); +} + +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params) +{ + struct ath11k_look_up_table *lut =3D NULL; + u32 end_magic =3D ATH11K_CFR_END_MAGIC; + struct ath11k_csi_cfr_header *header; + struct ath11k_dbring_element *buff; + struct ath11k_cfr *cfr; + dma_addr_t buf_addr; + struct ath11k *ar; + u8 tx_status; + int status; + int i; + + rcu_read_lock(); + ar =3D ath11k_mac_get_ar_by_vdev_id(ab, params->vdev_id); + if (!ar) { + rcu_read_unlock(); + ath11k_warn(ab, "Failed to get ar for vdev id %d\n", + params->vdev_id); + return -ENOENT; + } + + cfr =3D &ar->cfr; + rcu_read_unlock(); + + if (WMI_CFR_CAPTURE_STATUS_PEER_PS & params->status) { + ath11k_warn(ab, "CFR capture failed as peer %pM is in powersave", + params->peer_mac_addr); + return -EINVAL; + } + + if (!(WMI_CFR_PEER_CAPTURE_STATUS & params->status)) { + ath11k_warn(ab, "CFR capture failed for the peer : %pM", + params->peer_mac_addr); + cfr->tx_peer_status_cfr_fail++; + return -EINVAL; + } + + tx_status =3D FIELD_GET(WMI_CFR_FRAME_TX_STATUS, params->status); + if (tx_status !=3D WMI_FRAME_TX_STATUS_OK) { + ath11k_warn(ab, "WMI tx status %d for the peer %pM", + tx_status, params->peer_mac_addr); + cfr->tx_evt_status_cfr_fail++; + return -EINVAL; + } + + buf_addr =3D (((u64)FIELD_GET(WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH, + params->correlation_info_2)) << 32) | + params->correlation_info_1; + + spin_lock_bh(&cfr->lut_lock); + + if (!cfr->lut) { + spin_unlock_bh(&cfr->lut_lock); + return -EINVAL; + } + + for (i =3D 0; i < cfr->lut_num; i++) { + struct ath11k_look_up_table *temp =3D &cfr->lut[i]; + + if (temp->dbr_address =3D=3D buf_addr) { + lut =3D &cfr->lut[i]; + break; + } + } + + if (!lut) { + spin_unlock_bh(&cfr->lut_lock); + ath11k_warn(ab, "lut failure to process tx event\n"); + cfr->tx_dbr_lookup_fail++; + return -EINVAL; + } + + lut->tx_ppdu_id =3D FIELD_GET(WMI_CFR_CORRELATION_INFO2_PPDU_ID, + params->correlation_info_2); + lut->txrx_tstamp =3D jiffies; + + header =3D &lut->header; + header->start_magic_num =3D ATH11K_CFR_START_MAGIC; + header->vendorid =3D VENDOR_QCA; + header->platform_type =3D PLATFORM_TYPE_ARM; + + ath11k_cfr_fill_hdr_info(ar, header, params); + + status =3D ath11k_cfr_correlate_and_relay(ar, lut, + ATH11K_CORRELATE_TX_EVENT); + if (status =3D=3D ATH11K_CORRELATE_STATUS_RELEASE) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "Releasing CFR data to user space"); + ath11k_cfr_rfs_write(ar, &lut->header, + sizeof(struct ath11k_csi_cfr_header), + lut->data, lut->data_len, + &end_magic, sizeof(u32)); + buff =3D lut->buff; + ath11k_cfr_release_lut_entry(lut); + + ath11k_dbring_bufs_replenish(ar, &cfr->rx_ring, buff, + WMI_DIRECT_BUF_CFR); + } else if (status =3D=3D ATH11K_CORRELATE_STATUS_HOLD) { + ath11k_dbg(ab, ATH11K_DBG_CFR, + "dbr event is not yet received holding buf\n"); + } + + spin_unlock_bh(&cfr->lut_lock); + + return 0; +} + /* Helper function to check whether the given peer mac address * is in unassociated peer pool or not. */ diff --git a/drivers/net/wireless/ath/ath11k/cfr.h b/drivers/net/wireless/a= th/ath11k/cfr.h index c8e5086674d2..b17a8ca16b69 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -27,8 +27,37 @@ enum ath11k_cfr_correlate_event_type { struct ath11k_sta; struct ath11k_per_peer_cfr_capture; =20 +#define ATH11K_CFR_START_MAGIC 0xDEADBEAF #define ATH11K_CFR_END_MAGIC 0xBEAFDEAD =20 +#define VENDOR_QCA 0x8cfdf0 +#define PLATFORM_TYPE_ARM 2 + +enum ath11k_cfr_meta_version { + ATH11K_CFR_META_VERSION_NONE, + ATH11K_CFR_META_VERSION_1, + ATH11K_CFR_META_VERSION_2, + ATH11K_CFR_META_VERSION_3, + ATH11K_CFR_META_VERSION_4, + ATH11K_CFR_META_VERSION_MAX =3D 0xFF, +}; + +enum ath11k_cfr_data_version { + ATH11K_CFR_DATA_VERSION_NONE, + ATH11K_CFR_DATA_VERSION_1, + ATH11K_CFR_DATA_VERSION_MAX =3D 0xFF, +}; + +enum ath11k_cfr_capture_ack_mode { + ATH11K_CFR_CAPTURE_LEGACY_ACK, + ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK, + ATH11K_CFR_CAPTURE_HT_ACK, + ATH11K_CFR_CAPTURE_VHT_ACK, + + /*Always keep this at last*/ + ATH11K_CFR_CAPTURE_INVALID_ACK +}; + enum ath11k_cfr_correlate_status { ATH11K_CORRELATE_STATUS_RELEASE, ATH11K_CORRELATE_STATUS_HOLD, @@ -41,6 +70,28 @@ enum ath11k_cfr_preamble_type { ATH11K_CFR_PREAMBLE_TYPE_VHT, }; =20 +struct ath11k_cfr_peer_tx_param { + u32 capture_method; + u32 vdev_id; + u8 peer_mac_addr[ETH_ALEN]; + u32 primary_20mhz_chan; + u32 bandwidth; + u32 phy_mode; + u32 band_center_freq1; + u32 band_center_freq2; + u32 spatial_streams; + u32 correlation_info_1; + u32 correlation_info_2; + u32 status; + u32 timestamp_us; + u32 counter; + u32 chain_rssi[WMI_MAX_CHAINS]; + u16 chain_phase[WMI_MAX_CHAINS]; + u32 cfo_measurement; + u8 agc_gain[HOST_MAX_CHAINS]; + u32 rx_start_ts; +}; + struct cfr_metadata { u8 peer_addr[ETH_ALEN]; u8 status; @@ -70,7 +121,7 @@ struct ath11k_csi_cfr_header { u8 cfr_data_version; u8 chip_type; u8 platform_type; - u32 reserved; + u32 cfr_metadata_len; struct cfr_metadata meta_data; } __packed; =20 @@ -181,6 +232,8 @@ int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k = *ar, const u8 *peer_mac); struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar); void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut); +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params); =20 #else static inline int ath11k_cfr_init(struct ath11k_base *ab) @@ -238,5 +291,12 @@ struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath= 11k *ar) { return NULL; } + +static inline +int ath11k_process_cfr_capture_event(struct ath11k_base *ab, + struct ath11k_cfr_peer_tx_param *params) +{ + return 0; +} #endif /* CONFIG_ATH11K_CFR */ #endif /* ATH11K_CFR_H */ diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/a= th/ath11k/wmi.c index 0b4cc943c290..65f084524855 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -8802,6 +8802,93 @@ static void ath11k_wmi_p2p_noa_event(struct ath11k_b= ase *ab, kfree(tb); } =20 +static void ath11k_wmi_tlv_cfr_capture_event_fixed_param(const void *ptr, + void *data) +{ + struct ath11k_cfr_peer_tx_param *tx_params =3D data; + const struct ath11k_wmi_cfr_peer_tx_event_param *params =3D ptr; + + tx_params->capture_method =3D params->capture_method; + tx_params->vdev_id =3D params->vdev_id; + ether_addr_copy(tx_params->peer_mac_addr, params->mac_addr.addr); + tx_params->primary_20mhz_chan =3D params->chan_mhz; + tx_params->bandwidth =3D params->bandwidth; + tx_params->phy_mode =3D params->phy_mode; + tx_params->band_center_freq1 =3D params->band_center_freq1; + tx_params->band_center_freq2 =3D params->band_center_freq2; + tx_params->spatial_streams =3D params->sts_count; + tx_params->correlation_info_1 =3D params->correlation_info_1; + tx_params->correlation_info_2 =3D params->correlation_info_2; + tx_params->status =3D params->status; + tx_params->timestamp_us =3D params->timestamp_us; + tx_params->counter =3D params->counter; + tx_params->rx_start_ts =3D params->rx_start_ts; + + memcpy(tx_params->chain_rssi, params->chain_rssi, + sizeof(tx_params->chain_rssi)); + + if (WMI_CFR_CFO_MEASUREMENT_VALID & params->cfo_measurement) + tx_params->cfo_measurement =3D FIELD_GET(WMI_CFR_CFO_MEASUREMENT_RAW_DAT= A, + params->cfo_measurement); +} + +static void ath11k_wmi_tlv_cfr_capture_phase_fixed_param(const void *ptr, + void *data) +{ + struct ath11k_cfr_peer_tx_param *tx_params =3D data; + const struct ath11k_wmi_cfr_peer_tx_event_phase_param *params =3D ptr; + int i; + + for (i =3D 0; i < WMI_MAX_CHAINS; i++) { + tx_params->chain_phase[i] =3D params->chain_phase[i]; + tx_params->agc_gain[i] =3D params->agc_gain[i]; + } +} + +static int ath11k_wmi_tlv_cfr_capture_evt_parse(struct ath11k_base *ab, + u16 tag, u16 len, + const void *ptr, void *data) +{ + switch (tag) { + case WMI_TAG_PEER_CFR_CAPTURE_EVENT: + ath11k_wmi_tlv_cfr_capture_event_fixed_param(ptr, data); + break; + case WMI_TAG_CFR_CAPTURE_PHASE_PARAM: + ath11k_wmi_tlv_cfr_capture_phase_fixed_param(ptr, data); + break; + default: + ath11k_warn(ab, "Invalid tag received tag %d len %d\n", + tag, len); + return -EINVAL; + } + + return 0; +} + +static void ath11k_wmi_parse_cfr_capture_event(struct ath11k_base *ab, + struct sk_buff *skb) +{ + struct ath11k_cfr_peer_tx_param params =3D {}; + int ret; + + ath11k_dbg_dump(ab, ATH11K_DBG_CFR_DUMP, "cfr_dump:", "", + skb->data, skb->len); + + ret =3D ath11k_wmi_tlv_iter(ab, skb->data, skb->len, + ath11k_wmi_tlv_cfr_capture_evt_parse, + ¶ms); + if (ret) { + ath11k_warn(ab, "failed to parse cfr capture event tlv %d\n", + ret); + return; + } + + ret =3D ath11k_process_cfr_capture_event(ab, ¶ms); + if (ret) + ath11k_dbg(ab, ATH11K_DBG_CFR, + "failed to process cfr capture ret =3D %d\n", ret); +} + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *s= kb) { struct wmi_cmd_hdr *cmd_hdr; @@ -8932,6 +9019,9 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *= ab, struct sk_buff *skb) case WMI_P2P_NOA_EVENTID: ath11k_wmi_p2p_noa_event(ab, skb); break; + case WMI_PEER_CFR_CAPTURE_EVENTID: + ath11k_wmi_parse_cfr_capture_event(ab, skb); + break; default: ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id); break; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/a= th/ath11k/wmi.h index afc78fa4389b..baed501b640b 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -1889,6 +1889,8 @@ enum wmi_tlv_tag { WMI_TAG_NDP_EVENT, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD =3D 0x301, WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO, + WMI_TAG_PEER_CFR_CAPTURE_EVENT =3D 0x317, + WMI_TAG_CFR_CAPTURE_PHASE_PARAM =3D 0x33b, WMI_TAG_FILS_DISCOVERY_TMPL_CMD =3D 0x344, WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD =3D 0x37b, WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, @@ -4237,6 +4239,48 @@ enum ath11k_wmi_cfr_capture_method { WMI_CFR_CAPTURE_METHOD_MAX, }; =20 +#define WMI_CFR_FRAME_TX_STATUS GENMASK(1, 0) +#define WMI_CFR_CAPTURE_STATUS_PEER_PS BIT(30) +#define WMI_CFR_PEER_CAPTURE_STATUS BIT(31) + +#define WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH GENMASK(3, 0) +#define WMI_CFR_CORRELATION_INFO2_PPDU_ID GENMASK(31, 16) + +#define WMI_CFR_CFO_MEASUREMENT_VALID BIT(0) +#define WMI_CFR_CFO_MEASUREMENT_RAW_DATA GENMASK(14, 1) + +struct ath11k_wmi_cfr_peer_tx_event_param { + u32 capture_method; + u32 vdev_id; + struct wmi_mac_addr mac_addr; + u32 chan_mhz; + u32 bandwidth; + u32 phy_mode; + u32 band_center_freq1; + u32 band_center_freq2; + u32 sts_count; + u32 correlation_info_1; + u32 correlation_info_2; + u32 status; + u32 timestamp_us; + u32 counter; + u32 chain_rssi[WMI_MAX_CHAINS]; + u32 cfo_measurement; + u32 rx_start_ts; +} __packed; + +struct ath11k_wmi_cfr_peer_tx_event_phase_param { + u32 chain_phase[WMI_MAX_CHAINS]; + u8 agc_gain[WMI_MAX_CHAINS]; +} __packed; + +enum ath11k_wmi_frame_tx_status { + WMI_FRAME_TX_STATUS_OK, + WMI_FRAME_TX_STATUS_XRETRY, + WMI_FRAME_TX_STATUS_DROP, + WMI_FRAME_TX_STATUS_FILTERED, +}; + struct wmi_peer_cfr_capture_conf_arg { enum ath11k_wmi_cfr_capture_bw bw; enum ath11k_wmi_cfr_capture_method method; --=20 2.34.1