Commit 3bc374cb authored by Aaradhana Sahu's avatar Aaradhana Sahu Committed by Jeff Johnson
Browse files

wifi: ath12k: add factory test mode support



Add support to process factory test mode commands(FTM) for calibration.
By default firmware start with MISSION mode and to process the FTM commands
firmware needs to be restarted in FTM mode using module parameter ftm_mode.
The pre-request is all the radios should be down before starting the test.

All ath12k test mode interface related commands specified in enum
ath_tm_cmd.

When start command ATH_TM_CMD_TESTMODE_START is received, ar state
is set to test Mode and FTM daemon sends test mode command to wifi
driver via cfg80211. Wifi driver sends these command to firmware as
wmi events. If it is segmented commands it will be broken down into
multiple segments and encoded with TLV header else it is sent to
firmware as it is.

Firmware response via UTF events, wifi driver creates skb and send
to cfg80211, cfg80211 sends firmware response to FTM daemon via
netlink message.

Command to boot in ftm mode
insmod ath12k ftm_mode=1

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1

Signed-off-by: default avatarAaradhana Sahu <quic_aarasahu@quicinc.com>
Reviewed-by: default avatarAditya Kumar Singh <quic_adisi@quicinc.com>
Link: https://patch.msgid.link/20250119083657.1937557-4-quic_aarasahu@quicinc.com


Signed-off-by: default avatarJeff Johnson <jeff.johnson@oss.qualcomm.com>
parent 786d5258
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ ath12k-$(CONFIG_ACPI) += acpi.o
ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
ath12k-$(CONFIG_PM) += wow.o
ath12k-$(CONFIG_ATH12K_COREDUMP) += coredump.o
ath12k-$(CONFIG_NL80211_TESTMODE) += testmode.o

# for tracing framework to find trace.h
CFLAGS_trace.o := -I$(src)
+17 −5
Original line number Diff line number Diff line
@@ -23,6 +23,10 @@ unsigned int ath12k_debug_mask;
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");

bool ath12k_ftm_mode;
module_param_named(ftm_mode, ath12k_ftm_mode, bool, 0444);
MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");

/* protected with ath12k_hw_group_mutex */
static struct list_head ath12k_hw_group_list = LIST_HEAD_INIT(ath12k_hw_group_list);

@@ -693,6 +697,11 @@ static int ath12k_core_soc_create(struct ath12k_base *ab)
{
	int ret;

	if (ath12k_ftm_mode) {
		ab->fw_mode = ATH12K_FIRMWARE_MODE_FTM;
		ath12k_info(ab, "Booting in ftm mode\n");
	}

	ret = ath12k_qmi_init_service(ab);
	if (ret) {
		ath12k_err(ab, "failed to initialize qmi :%d\n", ret);
@@ -741,8 +750,7 @@ static void ath12k_core_pdev_destroy(struct ath12k_base *ab)
	ath12k_dp_pdev_free(ab);
}

static int ath12k_core_start(struct ath12k_base *ab,
			     enum ath12k_firmware_mode mode)
static int ath12k_core_start(struct ath12k_base *ab)
{
	int ret;

@@ -1068,7 +1076,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
	struct ath12k_hw_group *ag = ath12k_ab_to_ag(ab);
	int ret, i;

	ret = ath12k_core_start_firmware(ab, ATH12K_FIRMWARE_MODE_NORMAL);
	ret = ath12k_core_start_firmware(ab, ab->fw_mode);
	if (ret) {
		ath12k_err(ab, "failed to start firmware: %d\n", ret);
		return ret;
@@ -1089,7 +1097,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
	mutex_lock(&ag->mutex);
	mutex_lock(&ab->core_lock);

	ret = ath12k_core_start(ab, ATH12K_FIRMWARE_MODE_NORMAL);
	ret = ath12k_core_start(ab);
	if (ret) {
		ath12k_err(ab, "failed to start core: %d\n", ret);
		goto err_dp_free;
@@ -1239,7 +1247,8 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)

	for (i = 0; i < ag->num_hw; i++) {
		ah = ath12k_ag_to_ah(ag, i);
		if (!ah || ah->state == ATH12K_HW_STATE_OFF)
		if (!ah || ah->state == ATH12K_HW_STATE_OFF ||
		    ah->state == ATH12K_HW_STATE_TM)
			continue;

		ieee80211_stop_queues(ah->hw);
@@ -1309,6 +1318,9 @@ static void ath12k_core_post_reconfigure_recovery(struct ath12k_base *ab)
			ath12k_warn(ab,
				    "device is wedged, will not restart hw %d\n", i);
			break;
		case ATH12K_HW_STATE_TM:
			ath12k_warn(ab, "fw mode reset done radio %d\n", i);
			break;
		}

		mutex_unlock(&ah->hw_mutex);
+11 −0
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ enum ath12k_dev_flags {
	ATH12K_FLAG_CE_IRQ_ENABLED,
	ATH12K_FLAG_EXT_IRQ_ENABLED,
	ATH12K_FLAG_QMI_FW_READY_COMPLETE,
	ATH12K_FLAG_FTM_SEGMENTED,
};

struct ath12k_tx_conf {
@@ -534,12 +535,19 @@ enum ath12k_hw_state {
	ATH12K_HW_STATE_RESTARTING,
	ATH12K_HW_STATE_RESTARTED,
	ATH12K_HW_STATE_WEDGED,
	ATH12K_HW_STATE_TM,
	/* Add other states as required */
};

/* Antenna noise floor */
#define ATH12K_DEFAULT_NOISE_FLOOR -95

struct ath12k_ftm_event_obj {
	u32 data_pos;
	u32 expected_seq;
	u8 *eventdata;
};

struct ath12k_fw_stats {
	u32 pdev_id;
	u32 stats_id;
@@ -714,6 +722,7 @@ struct ath12k {

	struct completion mlo_setup_done;
	u32 mlo_setup_status;
	u8 ftm_msgref;
};

struct ath12k_hw {
@@ -1052,6 +1061,8 @@ struct ath12k_base {

	struct ath12k_hw_group *ag;
	struct ath12k_wsi_info wsi_info;
	enum ath12k_firmware_mode fw_mode;
	struct ath12k_ftm_event_obj ftm_event_obj;

	/* must be last */
	u8 drv_priv[] __aligned(sizeof(void *));
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
 * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2021-2022, 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef _ATH12K_DEBUG_H_
@@ -37,6 +37,7 @@ __printf(2, 3) void __ath12k_warn(struct device *dev, const char *fmt, ...);
#define ath12k_hw_warn(ah, fmt, ...) __ath12k_warn((ah)->dev, fmt, ##__VA_ARGS__)

extern unsigned int ath12k_debug_mask;
extern bool ath12k_ftm_mode;

#ifdef CONFIG_ATH12K_DEBUG
__printf(3, 4) void __ath12k_dbg(struct ath12k_base *ab,
+4 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <crypto/hash.h>
@@ -1315,6 +1315,9 @@ void ath12k_dp_cc_config(struct ath12k_base *ab)
	u32 wbm_base = HAL_SEQ_WCSS_UMAC_WBM_REG;
	u32 val = 0;

	if (ath12k_ftm_mode)
		return;

	ath12k_hif_write32(ab, reo_base + HAL_REO1_SW_COOKIE_CFG0(ab), cmem_base);

	val |= u32_encode_bits(ATH12K_CMEM_ADDR_MSB,
Loading