Commit 614c23e2 authored by Ripan Deuri's avatar Ripan Deuri Committed by Jeff Johnson
Browse files

wifi: ath12k: Support arch-specific DP device allocation



Add arch_init() and arch_deinit() ops to the PCI and AHB family ops to
support allocation and cleanup of architecture-specific fields in
ath12k_base. Define shared ath12k_wifi7_arch_init() and
ath12k_wifi7_arch_deinit() functions to handle DP device allocation and
cleanup for Wi-Fi 7 across both PCI and AHB. Introduce a new header file
wifi7/core.h to declare functions defined in wifi7/core.c.

Currently, DP device allocation and cleanup are handled via arch_init()
and arch_deinit(), which can be extended to support additional
architecture-specific initialization in the future.

Define common ath12k_wifi7_arch_init() and
ath12k_wifi7_arch_deinit() functions to handle allocation and cleanup
for Wi-Fi 7. Add a new header file wifi7/core.h to declare common Wi-Fi 7
functions.

Add ath12k_wifi7_dp_device_alloc() and ath12k_wifi7_dp_device_free() to
handle allocation and deallocation of the DP device object for Wi-Fi 7.

Add ath12k_dp_cmn_device_init() and ath12k_dp_cmn_device_deinit() to
initialize and deinitialize common DP device fields. Introduce a new header
file dp_cmn.h to declare these functions, which can also be used to expose
new common DP functions that need to be invoked from non-DP code.

Rename existing DP allocation and cleanup functions to ath12k_dp_setup()
and ath12k_dp_cleanup() to better reflect their purpose in the updated
design.

Replicate device-related fields such as device and hw_params in the DP
device object to align with the new design, which limits per packet data
path object usage to DP specific objects.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: default avatarRipan Deuri <quic_rdeuri@quicinc.com>
Reviewed-by: default avatarVasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Reviewed-by: default avatarBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20250930131005.2884253-3-quic_rdeuri@quicinc.com


Signed-off-by: default avatarJeff Johnson <jeff.johnson@oss.qualcomm.com>
parent 3a52762b
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -1088,14 +1088,26 @@ static int ath12k_ahb_probe(struct platform_device *pdev)
		goto err_rproc_deconfigure;
	}

	/* Invoke arch_init here so that arch-specific init operations
	 * can utilize already initialized ab fields, such as HAL SRNGs.
	 */
	ret = ab_ahb->device_family_ops->arch_init(ab);
	if (ret) {
		ath12k_err(ab, "AHB arch_init failed %d\n", ret);
		goto err_rproc_deconfigure;
	}

	ret = ath12k_core_init(ab);
	if (ret) {
		ath12k_err(ab, "failed to init core: %d\n", ret);
		goto err_rproc_deconfigure;
		goto err_deinit_arch;
	}

	return 0;

err_deinit_arch:
	ab_ahb->device_family_ops->arch_deinit(ab);

err_rproc_deconfigure:
	ath12k_ahb_deconfigure_rproc(ab);

@@ -1134,11 +1146,13 @@ static void ath12k_ahb_remove_prepare(struct ath12k_base *ab)
static void ath12k_ahb_free_resources(struct ath12k_base *ab)
{
	struct platform_device *pdev = ab->pdev;
	struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);

	ath12k_hal_srng_deinit(ab);
	ath12k_ce_free_pipes(ab);
	ath12k_ahb_resource_deinit(ab);
	ath12k_ahb_deconfigure_rproc(ab);
	ab_ahb->device_family_ops->arch_deinit(ab);
	ath12k_core_free(ab);
	platform_set_drvdata(pdev, NULL);
}
@@ -1167,7 +1181,8 @@ int ath12k_ahb_register_driver(const enum ath12k_device_family device_id,
	if (device_id >= ATH12K_DEVICE_FAMILY_MAX)
		return -EINVAL;

	if (!driver || !driver->ops.probe)
	if (!driver || !driver->ops.probe ||
	    !driver->ops.arch_init || !driver->ops.arch_deinit)
		return -EINVAL;

	if (ath12k_ahb_family_drivers[device_id]) {
+3 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
 */
#ifndef ATH12K_AHB_H
#define ATH12K_AHB_H
@@ -46,6 +46,8 @@ struct ath12k_base;

struct ath12k_ahb_device_family_ops {
	int (*probe)(struct platform_device *pdev);
	int (*arch_init)(struct ath12k_base *ab);
	void (*arch_deinit)(struct ath12k_base *ab);
};

struct ath12k_ahb {
+7 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "hif.h"
#include "pci.h"
#include "wow.h"
#include "dp_cmn.h"

unsigned int ath12k_debug_mask;
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
@@ -711,7 +712,7 @@ static void ath12k_core_stop(struct ath12k_base *ab)
	ath12k_dp_rx_pdev_reo_cleanup(ab);
	ath12k_hif_stop(ab);
	ath12k_wmi_detach(ab);
	ath12k_dp_free(ab);
	ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));

	/* De-Init of components as needed */
}
@@ -1290,7 +1291,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
		goto err_firmware_stop;
	}

	ret = ath12k_dp_alloc(ab);
	ret = ath12k_dp_cmn_device_init(ath12k_ab_to_dp(ab));
	if (ret) {
		ath12k_err(ab, "failed to init DP: %d\n", ret);
		goto err_firmware_stop;
@@ -1302,7 +1303,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
	ret = ath12k_core_start(ab);
	if (ret) {
		ath12k_err(ab, "failed to start core: %d\n", ret);
		goto err_dp_free;
		goto err_deinit;
	}

	mutex_unlock(&ab->core_lock);
@@ -1335,8 +1336,8 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
	mutex_unlock(&ag->mutex);
	goto exit;

err_dp_free:
	ath12k_dp_free(ab);
err_deinit:
	ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));
	mutex_unlock(&ab->core_lock);
	mutex_unlock(&ag->mutex);

@@ -1358,7 +1359,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab)
	ath12k_dp_rx_pdev_reo_cleanup(ab);
	mutex_unlock(&ab->core_lock);

	ath12k_dp_free(ab);
	ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));
	ath12k_hal_srng_deinit(ab);
	total_vdev = ab->num_radios * TARGET_NUM_VDEVS(ab);
	ab->free_vdev_map = (1LL << total_vdev) - 1;
+22 −16
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "wifi7/dp_rx.h"
#include "peer.h"
#include "dp_mon.h"
#include "dp_cmn.h"

enum ath12k_dp_desc_type {
	ATH12K_DP_TX_DESC,
@@ -1130,7 +1131,7 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
	}
}

void ath12k_dp_free(struct ath12k_base *ab)
static void ath12k_dp_cleanup(struct ath12k_base *ab)
{
	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
	int i;
@@ -1155,8 +1156,6 @@ void ath12k_dp_free(struct ath12k_base *ab)

	ath12k_dp_rx_free(ab);
	/* Deinit any SOC level resource */
	kfree(ab->dp);
	ab->dp = NULL;
}

void ath12k_dp_cc_config(struct ath12k_base *ab)
@@ -1564,7 +1563,7 @@ ath12k_dp_get_idle_link_rbm(struct ath12k_base *ab)
	}
}

int ath12k_dp_alloc(struct ath12k_base *ab)
static int ath12k_dp_setup(struct ath12k_base *ab)
{
	struct ath12k_dp *dp;
	struct hal_srng *srng = NULL;
@@ -1573,12 +1572,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab)
	int ret;
	int i;

	/* TODO: align dp later if cache alignment becomes a bottleneck */
	dp = kzalloc(sizeof(*dp), GFP_KERNEL);
	if (!dp)
		return -ENOMEM;

	ab->dp = dp;
	dp = ath12k_ab_to_dp(ab);
	dp->ab = ab;

	INIT_LIST_HEAD(&dp->reo_cmd_list);
@@ -1591,7 +1585,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab)
	ret = ath12k_wbm_idle_ring_setup(ab, &n_link_desc);
	if (ret) {
		ath12k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret);
		goto fail_dp_free;
		return ret;
	}

	srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id];
@@ -1600,7 +1594,7 @@ int ath12k_dp_alloc(struct ath12k_base *ab)
					HAL_WBM_IDLE_LINK, srng, n_link_desc);
	if (ret) {
		ath12k_warn(ab, "failed to setup link desc: %d\n", ret);
		goto fail_dp_free;
		return ret;
	}

	ret = ath12k_dp_cc_init(ab);
@@ -1673,9 +1667,21 @@ int ath12k_dp_alloc(struct ath12k_base *ab)
	ath12k_dp_link_desc_cleanup(ab, dp->link_desc_banks,
				    HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring);

fail_dp_free:
	kfree(ab->dp);
	ab->dp = NULL;
	return ret;
}

void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp)
{
	ath12k_dp_cleanup(dp->ab);
}

int ath12k_dp_cmn_device_init(struct ath12k_dp *dp)
{
	int ret;

	ret = ath12k_dp_setup(dp->ab);
	if (ret)
		return ret;

	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -424,6 +424,8 @@ struct ath12k_dp {
	struct dp_rxdma_mon_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV];
	struct ath12k_reo_q_addr_lut reoq_lut;
	struct ath12k_reo_q_addr_lut ml_reoq_lut;
	const struct ath12k_hw_params *hw_params;
	struct device *dev;
};

static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr)
@@ -433,8 +435,6 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr)
}

void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);
void ath12k_dp_free(struct ath12k_base *ab);
int ath12k_dp_alloc(struct ath12k_base *ab);
void ath12k_dp_cc_config(struct ath12k_base *ab);
void ath12k_dp_partner_cc_init(struct ath12k_base *ab);
int ath12k_dp_pdev_alloc(struct ath12k_base *ab);
Loading