xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/be/dp_be.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #include <wlan_utility.h>
21*5113495bSYour Name #include <dp_internal.h>
22*5113495bSYour Name #include "dp_rings.h"
23*5113495bSYour Name #include <dp_htt.h>
24*5113495bSYour Name #include "dp_be.h"
25*5113495bSYour Name #include "dp_be_tx.h"
26*5113495bSYour Name #include "dp_be_rx.h"
27*5113495bSYour Name #ifdef WIFI_MONITOR_SUPPORT
28*5113495bSYour Name #if !defined(DISABLE_MON_CONFIG) && (defined(WLAN_PKT_CAPTURE_TX_2_0) || \
29*5113495bSYour Name 	defined(WLAN_PKT_CAPTURE_RX_2_0))
30*5113495bSYour Name #include "dp_mon_2.0.h"
31*5113495bSYour Name #endif
32*5113495bSYour Name #include "dp_mon.h"
33*5113495bSYour Name #endif
34*5113495bSYour Name #include <hal_be_api.h>
35*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
36*5113495bSYour Name #include "be/dp_ppeds.h"
37*5113495bSYour Name #include <ppe_vp_public.h>
38*5113495bSYour Name #include <ppe_drv_sc.h>
39*5113495bSYour Name #endif
40*5113495bSYour Name 
41*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
42*5113495bSYour Name static const char *ring_usage_dump[RING_USAGE_MAX] = {
43*5113495bSYour Name 	"100%",
44*5113495bSYour Name 	"Greater than 90%",
45*5113495bSYour Name 	"70 to 90%",
46*5113495bSYour Name 	"50 to 70%",
47*5113495bSYour Name 	"Less than 50%"
48*5113495bSYour Name };
49*5113495bSYour Name #endif
50*5113495bSYour Name 
51*5113495bSYour Name /* Generic AST entry aging timer value */
52*5113495bSYour Name #define DP_AST_AGING_TIMER_DEFAULT_MS	5000
53*5113495bSYour Name 
54*5113495bSYour Name #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
55*5113495bSYour Name #define DP_TX_VDEV_ID_CHECK_ENABLE 0
56*5113495bSYour Name 
57*5113495bSYour Name static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = {
58*5113495bSYour Name 	{.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_BE_WBM_SW0_BM_ID, .for_ipa = 0},
59*5113495bSYour Name 	{1, 4, HAL_BE_WBM_SW4_BM_ID, 0},
60*5113495bSYour Name 	{2, 2, HAL_BE_WBM_SW2_BM_ID, 0},
61*5113495bSYour Name #ifdef QCA_WIFI_KIWI_V2
62*5113495bSYour Name 	{3, 5, HAL_BE_WBM_SW5_BM_ID, 0},
63*5113495bSYour Name 	{4, 6, HAL_BE_WBM_SW6_BM_ID, 0}
64*5113495bSYour Name #else
65*5113495bSYour Name 	{3, 6, HAL_BE_WBM_SW5_BM_ID, 0},
66*5113495bSYour Name 	{4, 7, HAL_BE_WBM_SW6_BM_ID, 0}
67*5113495bSYour Name #endif
68*5113495bSYour Name };
69*5113495bSYour Name #else
70*5113495bSYour Name #define DP_TX_VDEV_ID_CHECK_ENABLE 1
71*5113495bSYour Name 
72*5113495bSYour Name static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RINGS] = {
73*5113495bSYour Name 	{.tcl_ring_num = 0, .wbm_ring_num = 0, .wbm_rbm_id = HAL_BE_WBM_SW0_BM_ID, .for_ipa = 0},
74*5113495bSYour Name 	{1, 1, HAL_BE_WBM_SW1_BM_ID, 0},
75*5113495bSYour Name 	{2, 2, HAL_BE_WBM_SW2_BM_ID, 0},
76*5113495bSYour Name 	{3, 3, HAL_BE_WBM_SW3_BM_ID, 0},
77*5113495bSYour Name 	{4, 4, HAL_BE_WBM_SW4_BM_ID, 0}
78*5113495bSYour Name };
79*5113495bSYour Name #endif
80*5113495bSYour Name 
81*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
82*5113495bSYour Name static struct cdp_ppeds_txrx_ops dp_ops_ppeds_be = {
83*5113495bSYour Name 	.ppeds_entry_attach = dp_ppeds_attach_vdev_be,
84*5113495bSYour Name 	.ppeds_entry_detach = dp_ppeds_detach_vdev_be,
85*5113495bSYour Name 	.ppeds_set_int_pri2tid = dp_ppeds_set_int_pri2tid_be,
86*5113495bSYour Name 	.ppeds_update_int_pri2tid = dp_ppeds_update_int_pri2tid_be,
87*5113495bSYour Name 	.ppeds_entry_dump = dp_ppeds_dump_ppe_vp_tbl_be,
88*5113495bSYour Name 	.ppeds_enable_pri2tid = dp_ppeds_vdev_enable_pri2tid_be,
89*5113495bSYour Name 	.ppeds_vp_setup_recovery = dp_ppeds_vp_setup_on_fw_recovery,
90*5113495bSYour Name 	.ppeds_stats_sync = dp_ppeds_stats_sync_be,
91*5113495bSYour Name };
92*5113495bSYour Name 
dp_ppeds_rings_status(struct dp_soc * soc)93*5113495bSYour Name static void dp_ppeds_rings_status(struct dp_soc *soc)
94*5113495bSYour Name {
95*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
96*5113495bSYour Name 
97*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &be_soc->reo2ppe_ring, REO2PPE);
98*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &be_soc->ppe2tcl_ring, PPE2TCL);
99*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &be_soc->ppeds_wbm_release_ring,
100*5113495bSYour Name 				    WBM2SW_RELEASE);
101*5113495bSYour Name }
102*5113495bSYour Name 
103*5113495bSYour Name #ifdef GLOBAL_ASSERT_AVOIDANCE
dp_ppeds_print_assert_war_stats(struct dp_soc_be * be_soc)104*5113495bSYour Name void dp_ppeds_print_assert_war_stats(struct dp_soc_be *be_soc)
105*5113495bSYour Name {
106*5113495bSYour Name 	DP_PRINT_STATS("PPE-DS Tx WAR stats: [%u] [%u] [%u]",
107*5113495bSYour Name 		       be_soc->ppeds_stats.tx.tx_comp_buf_src,
108*5113495bSYour Name 		       be_soc->ppeds_stats.tx.tx_comp_desc_null,
109*5113495bSYour Name 		       be_soc->ppeds_stats.tx.tx_comp_invalid_flag);
110*5113495bSYour Name }
111*5113495bSYour Name 
dp_ppeds_clear_assert_war_stats(struct dp_soc_be * be_soc)112*5113495bSYour Name static void dp_ppeds_clear_assert_war_stats(struct dp_soc_be *be_soc)
113*5113495bSYour Name {
114*5113495bSYour Name 	be_soc->ppeds_stats.tx.tx_comp_buf_src = 0;
115*5113495bSYour Name 	be_soc->ppeds_stats.tx.tx_comp_desc_null = 0;
116*5113495bSYour Name 	be_soc->ppeds_stats.tx.tx_comp_invalid_flag = 0;
117*5113495bSYour Name }
118*5113495bSYour Name #else
dp_ppeds_print_assert_war_stats(struct dp_soc_be * be_soc)119*5113495bSYour Name static void dp_ppeds_print_assert_war_stats(struct dp_soc_be *be_soc)
120*5113495bSYour Name {
121*5113495bSYour Name }
122*5113495bSYour Name 
dp_ppeds_clear_assert_war_stats(struct dp_soc_be * be_soc)123*5113495bSYour Name static void dp_ppeds_clear_assert_war_stats(struct dp_soc_be *be_soc)
124*5113495bSYour Name {
125*5113495bSYour Name }
126*5113495bSYour Name #endif
127*5113495bSYour Name 
dp_ppeds_inuse_desc(struct dp_soc * soc)128*5113495bSYour Name static void dp_ppeds_inuse_desc(struct dp_soc *soc)
129*5113495bSYour Name {
130*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
131*5113495bSYour Name 
132*5113495bSYour Name 	DP_PRINT_STATS("PPE-DS Tx Descriptors in Use = %u num_free %u",
133*5113495bSYour Name 		       be_soc->ppeds_tx_desc.num_allocated,
134*5113495bSYour Name 		       be_soc->ppeds_tx_desc.num_free);
135*5113495bSYour Name 
136*5113495bSYour Name 	DP_PRINT_STATS("PPE-DS Tx desc alloc failed %u",
137*5113495bSYour Name 		       be_soc->ppeds_stats.tx.desc_alloc_failed);
138*5113495bSYour Name 
139*5113495bSYour Name 	dp_ppeds_print_assert_war_stats(be_soc);
140*5113495bSYour Name }
141*5113495bSYour Name 
dp_ppeds_clear_stats(struct dp_soc * soc)142*5113495bSYour Name static void dp_ppeds_clear_stats(struct dp_soc *soc)
143*5113495bSYour Name {
144*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
145*5113495bSYour Name 
146*5113495bSYour Name 	be_soc->ppeds_stats.tx.desc_alloc_failed = 0;
147*5113495bSYour Name 	dp_ppeds_clear_assert_war_stats(be_soc);
148*5113495bSYour Name }
149*5113495bSYour Name 
dp_ppeds_rings_stats(struct dp_soc * soc)150*5113495bSYour Name static void dp_ppeds_rings_stats(struct dp_soc *soc)
151*5113495bSYour Name {
152*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
153*5113495bSYour Name 	int i = 0;
154*5113495bSYour Name 
155*5113495bSYour Name 	DP_PRINT_STATS("Ring utilization statistics");
156*5113495bSYour Name 	DP_PRINT_STATS("WBM2SW_RELEASE");
157*5113495bSYour Name 
158*5113495bSYour Name 	for (i = 0; i < RING_USAGE_MAX; i++)
159*5113495bSYour Name 		DP_PRINT_STATS("\t %s utilized %d instances",
160*5113495bSYour Name 			       ring_usage_dump[i],
161*5113495bSYour Name 			       be_soc->ppeds_wbm_release_ring.stats.util[i]);
162*5113495bSYour Name 
163*5113495bSYour Name 	DP_PRINT_STATS("PPE2TCL");
164*5113495bSYour Name 
165*5113495bSYour Name 	for (i = 0; i < RING_USAGE_MAX; i++)
166*5113495bSYour Name 		DP_PRINT_STATS("\t %s utilized %d instances",
167*5113495bSYour Name 			       ring_usage_dump[i],
168*5113495bSYour Name 			       be_soc->ppe2tcl_ring.stats.util[i]);
169*5113495bSYour Name }
170*5113495bSYour Name 
dp_ppeds_clear_rings_stats(struct dp_soc * soc)171*5113495bSYour Name static void dp_ppeds_clear_rings_stats(struct dp_soc *soc)
172*5113495bSYour Name {
173*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
174*5113495bSYour Name 
175*5113495bSYour Name 	memset(&be_soc->ppeds_wbm_release_ring.stats, 0,
176*5113495bSYour Name 	       sizeof(struct ring_util_stats));
177*5113495bSYour Name 	memset(&be_soc->ppe2tcl_ring.stats, 0, sizeof(struct ring_util_stats));
178*5113495bSYour Name }
179*5113495bSYour Name #endif
180*5113495bSYour Name 
dp_soc_cfg_attach_be(struct dp_soc * soc)181*5113495bSYour Name static void dp_soc_cfg_attach_be(struct dp_soc *soc)
182*5113495bSYour Name {
183*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
184*5113495bSYour Name 	dp_soc_cfg_attach(soc);
185*5113495bSYour Name 
186*5113495bSYour Name 	wlan_cfg_set_rx_rel_ring_id(soc_cfg_ctx, WBM2SW_REL_ERR_RING_NUM);
187*5113495bSYour Name 
188*5113495bSYour Name 	soc->wlan_cfg_ctx->tcl_wbm_map_array = g_tcl_wbm_map_array;
189*5113495bSYour Name 
190*5113495bSYour Name 	/* this is used only when dmac mode is enabled */
191*5113495bSYour Name 	soc->num_rx_refill_buf_rings = 1;
192*5113495bSYour Name 
193*5113495bSYour Name 	/*
194*5113495bSYour Name 	 * do not allocate TCL credit ring for BE as we already have
195*5113495bSYour Name 	 * 4 TCL_DATA rings
196*5113495bSYour Name 	 */
197*5113495bSYour Name 	soc->init_tcl_cmd_cred_ring = false;
198*5113495bSYour Name 	soc->wlan_cfg_ctx->notify_frame_support =
199*5113495bSYour Name 				DP_MARK_NOTIFY_FRAME_SUPPORT;
200*5113495bSYour Name }
201*5113495bSYour Name 
dp_get_context_size_be(enum dp_context_type context_type)202*5113495bSYour Name qdf_size_t dp_get_context_size_be(enum dp_context_type context_type)
203*5113495bSYour Name {
204*5113495bSYour Name 	switch (context_type) {
205*5113495bSYour Name 	case DP_CONTEXT_TYPE_SOC:
206*5113495bSYour Name 		return sizeof(struct dp_soc_be);
207*5113495bSYour Name 	case DP_CONTEXT_TYPE_PDEV:
208*5113495bSYour Name 		return sizeof(struct dp_pdev_be);
209*5113495bSYour Name 	case DP_CONTEXT_TYPE_VDEV:
210*5113495bSYour Name 		return sizeof(struct dp_vdev_be);
211*5113495bSYour Name 	case DP_CONTEXT_TYPE_PEER:
212*5113495bSYour Name 		return sizeof(struct dp_peer_be);
213*5113495bSYour Name 	default:
214*5113495bSYour Name 		return 0;
215*5113495bSYour Name 	}
216*5113495bSYour Name }
217*5113495bSYour Name 
218*5113495bSYour Name #if defined(DP_FEATURE_HW_COOKIE_CONVERSION) || defined(WLAN_SUPPORT_RX_FISA)
dp_get_cmem_chunk(struct dp_soc * soc,uint64_t size,enum CMEM_MEM_CLIENTS client)219*5113495bSYour Name static uint64_t dp_get_cmem_chunk(struct dp_soc *soc, uint64_t size,
220*5113495bSYour Name 				  enum CMEM_MEM_CLIENTS client)
221*5113495bSYour Name {
222*5113495bSYour Name 	uint64_t cmem_chunk;
223*5113495bSYour Name 
224*5113495bSYour Name 	dp_info("cmem base 0x%llx, total size 0x%llx avail_size 0x%llx",
225*5113495bSYour Name 		soc->cmem_base, soc->cmem_total_size, soc->cmem_avail_size);
226*5113495bSYour Name 
227*5113495bSYour Name 	/* Check if requested cmem space is available */
228*5113495bSYour Name 	if (soc->cmem_avail_size < size) {
229*5113495bSYour Name 		dp_err("cmem_size 0x%llx bytes < requested size 0x%llx bytes",
230*5113495bSYour Name 		       soc->cmem_avail_size, size);
231*5113495bSYour Name 		return 0;
232*5113495bSYour Name 	}
233*5113495bSYour Name 
234*5113495bSYour Name 	cmem_chunk = soc->cmem_base +
235*5113495bSYour Name 		     (soc->cmem_total_size - soc->cmem_avail_size);
236*5113495bSYour Name 	soc->cmem_avail_size -= size;
237*5113495bSYour Name 	dp_info("Reserved cmem space 0x%llx, size 0x%llx for client %d",
238*5113495bSYour Name 		cmem_chunk, size, client);
239*5113495bSYour Name 
240*5113495bSYour Name 	return cmem_chunk;
241*5113495bSYour Name }
242*5113495bSYour Name #endif
243*5113495bSYour Name 
244*5113495bSYour Name #ifdef WLAN_SUPPORT_RX_FISA
dp_get_fst_cmem_base_be(struct dp_soc * soc,uint64_t size)245*5113495bSYour Name static uint64_t dp_get_fst_cmem_base_be(struct dp_soc *soc, uint64_t size)
246*5113495bSYour Name {
247*5113495bSYour Name 	return dp_get_cmem_chunk(soc, size, FISA_FST);
248*5113495bSYour Name }
249*5113495bSYour Name 
dp_initialize_arch_ops_be_fisa(struct dp_arch_ops * arch_ops)250*5113495bSYour Name static void dp_initialize_arch_ops_be_fisa(struct dp_arch_ops *arch_ops)
251*5113495bSYour Name {
252*5113495bSYour Name 	arch_ops->dp_get_fst_cmem_base = dp_get_fst_cmem_base_be;
253*5113495bSYour Name }
254*5113495bSYour Name #else
dp_initialize_arch_ops_be_fisa(struct dp_arch_ops * arch_ops)255*5113495bSYour Name static void dp_initialize_arch_ops_be_fisa(struct dp_arch_ops *arch_ops)
256*5113495bSYour Name {
257*5113495bSYour Name }
258*5113495bSYour Name #endif
259*5113495bSYour Name 
260*5113495bSYour Name #ifdef DP_FEATURE_HW_COOKIE_CONVERSION
261*5113495bSYour Name #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
262*5113495bSYour Name /**
263*5113495bSYour Name  * dp_cc_wbm_sw_en_cfg() - configure HW cookie conversion enablement
264*5113495bSYour Name  *			   per wbm2sw ring
265*5113495bSYour Name  *
266*5113495bSYour Name  * @cc_cfg: HAL HW cookie conversion configuration structure pointer
267*5113495bSYour Name  *
268*5113495bSYour Name  * Return: None
269*5113495bSYour Name  */
270*5113495bSYour Name #ifdef IPA_OPT_WIFI_DP
271*5113495bSYour Name static inline
dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config * cc_cfg)272*5113495bSYour Name void dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config *cc_cfg)
273*5113495bSYour Name {
274*5113495bSYour Name 	cc_cfg->wbm2sw6_cc_en = 1;
275*5113495bSYour Name 	cc_cfg->wbm2sw5_cc_en = 0;
276*5113495bSYour Name 	cc_cfg->wbm2sw4_cc_en = 1;
277*5113495bSYour Name 	cc_cfg->wbm2sw3_cc_en = 1;
278*5113495bSYour Name 	cc_cfg->wbm2sw2_cc_en = 1;
279*5113495bSYour Name 	/* disable wbm2sw1 hw cc as it's for FW */
280*5113495bSYour Name 	cc_cfg->wbm2sw1_cc_en = 0;
281*5113495bSYour Name 	cc_cfg->wbm2sw0_cc_en = 1;
282*5113495bSYour Name 	cc_cfg->wbm2fw_cc_en = 0;
283*5113495bSYour Name }
284*5113495bSYour Name #else
285*5113495bSYour Name static inline
dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config * cc_cfg)286*5113495bSYour Name void dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config *cc_cfg)
287*5113495bSYour Name {
288*5113495bSYour Name 	cc_cfg->wbm2sw6_cc_en = 1;
289*5113495bSYour Name 	cc_cfg->wbm2sw5_cc_en = 1;
290*5113495bSYour Name 	cc_cfg->wbm2sw4_cc_en = 1;
291*5113495bSYour Name 	cc_cfg->wbm2sw3_cc_en = 1;
292*5113495bSYour Name 	cc_cfg->wbm2sw2_cc_en = 1;
293*5113495bSYour Name 	/* disable wbm2sw1 hw cc as it's for FW */
294*5113495bSYour Name 	cc_cfg->wbm2sw1_cc_en = 0;
295*5113495bSYour Name 	cc_cfg->wbm2sw0_cc_en = 1;
296*5113495bSYour Name 	cc_cfg->wbm2fw_cc_en = 0;
297*5113495bSYour Name }
298*5113495bSYour Name #endif
299*5113495bSYour Name #else
300*5113495bSYour Name static inline
dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config * cc_cfg)301*5113495bSYour Name void dp_cc_wbm_sw_en_cfg(struct hal_hw_cc_config *cc_cfg)
302*5113495bSYour Name {
303*5113495bSYour Name 	cc_cfg->wbm2sw6_cc_en = 1;
304*5113495bSYour Name 	cc_cfg->wbm2sw5_cc_en = 1;
305*5113495bSYour Name 	cc_cfg->wbm2sw4_cc_en = 1;
306*5113495bSYour Name 	cc_cfg->wbm2sw3_cc_en = 1;
307*5113495bSYour Name 	cc_cfg->wbm2sw2_cc_en = 1;
308*5113495bSYour Name 	cc_cfg->wbm2sw1_cc_en = 1;
309*5113495bSYour Name 	cc_cfg->wbm2sw0_cc_en = 1;
310*5113495bSYour Name 	cc_cfg->wbm2fw_cc_en = 0;
311*5113495bSYour Name }
312*5113495bSYour Name #endif
313*5113495bSYour Name 
314*5113495bSYour Name /**
315*5113495bSYour Name  * dp_cc_reg_cfg_init() - initialize and configure HW cookie
316*5113495bSYour Name  *			  conversion register
317*5113495bSYour Name  *
318*5113495bSYour Name  * @soc: SOC handle
319*5113495bSYour Name  * @is_4k_align: page address 4k aligned
320*5113495bSYour Name  *
321*5113495bSYour Name  * Return: None
322*5113495bSYour Name  */
dp_cc_reg_cfg_init(struct dp_soc * soc,bool is_4k_align)323*5113495bSYour Name static void dp_cc_reg_cfg_init(struct dp_soc *soc,
324*5113495bSYour Name 			       bool is_4k_align)
325*5113495bSYour Name {
326*5113495bSYour Name 	struct hal_hw_cc_config cc_cfg = { 0 };
327*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
328*5113495bSYour Name 
329*5113495bSYour Name 	if (soc->cdp_soc.ol_ops->get_con_mode &&
330*5113495bSYour Name 	    soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_FTM_MODE)
331*5113495bSYour Name 		return;
332*5113495bSYour Name 
333*5113495bSYour Name 	if (!soc->wlan_cfg_ctx->hw_cc_enabled) {
334*5113495bSYour Name 		dp_info("INI skip HW CC register setting");
335*5113495bSYour Name 		return;
336*5113495bSYour Name 	}
337*5113495bSYour Name 
338*5113495bSYour Name 	cc_cfg.lut_base_addr_31_0 = be_soc->cc_cmem_base;
339*5113495bSYour Name 	cc_cfg.cc_global_en = true;
340*5113495bSYour Name 	cc_cfg.page_4k_align = is_4k_align;
341*5113495bSYour Name 	cc_cfg.cookie_offset_msb = DP_CC_DESC_ID_SPT_VA_OS_MSB;
342*5113495bSYour Name 	cc_cfg.cookie_page_msb = DP_CC_DESC_ID_PPT_PAGE_OS_MSB;
343*5113495bSYour Name 	/* 36th bit should be 1 then HW know this is CMEM address */
344*5113495bSYour Name 	cc_cfg.lut_base_addr_39_32 = 0x10;
345*5113495bSYour Name 
346*5113495bSYour Name 	cc_cfg.error_path_cookie_conv_en = true;
347*5113495bSYour Name 	cc_cfg.release_path_cookie_conv_en = true;
348*5113495bSYour Name 	dp_cc_wbm_sw_en_cfg(&cc_cfg);
349*5113495bSYour Name 
350*5113495bSYour Name 	hal_cookie_conversion_reg_cfg_be(soc->hal_soc, &cc_cfg);
351*5113495bSYour Name }
352*5113495bSYour Name 
353*5113495bSYour Name /**
354*5113495bSYour Name  * dp_hw_cc_cmem_write() - DP wrapper function for CMEM buffer writing
355*5113495bSYour Name  * @hal_soc_hdl: HAL SOC handle
356*5113495bSYour Name  * @offset: CMEM address
357*5113495bSYour Name  * @value: value to write
358*5113495bSYour Name  *
359*5113495bSYour Name  * Return: None.
360*5113495bSYour Name  */
dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl,uint32_t offset,uint32_t value)361*5113495bSYour Name static inline void dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl,
362*5113495bSYour Name 				       uint32_t offset,
363*5113495bSYour Name 				       uint32_t value)
364*5113495bSYour Name {
365*5113495bSYour Name 	hal_cmem_write(hal_soc_hdl, offset, value);
366*5113495bSYour Name }
367*5113495bSYour Name 
368*5113495bSYour Name /**
369*5113495bSYour Name  * dp_hw_cc_cmem_addr_init() - Check and initialize CMEM base address for
370*5113495bSYour Name  *			       HW cookie conversion
371*5113495bSYour Name  *
372*5113495bSYour Name  * @soc: SOC handle
373*5113495bSYour Name  *
374*5113495bSYour Name  * Return: 0 in case of success, else error value
375*5113495bSYour Name  */
dp_hw_cc_cmem_addr_init(struct dp_soc * soc)376*5113495bSYour Name static inline QDF_STATUS dp_hw_cc_cmem_addr_init(struct dp_soc *soc)
377*5113495bSYour Name {
378*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
379*5113495bSYour Name 
380*5113495bSYour Name 	be_soc->cc_cmem_base = dp_get_cmem_chunk(soc, DP_CC_PPT_MEM_SIZE,
381*5113495bSYour Name 					      COOKIE_CONVERSION);
382*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
383*5113495bSYour Name }
384*5113495bSYour Name 
385*5113495bSYour Name #else
386*5113495bSYour Name 
dp_cc_reg_cfg_init(struct dp_soc * soc,bool is_4k_align)387*5113495bSYour Name static inline void dp_cc_reg_cfg_init(struct dp_soc *soc,
388*5113495bSYour Name 				      bool is_4k_align) {}
389*5113495bSYour Name 
dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl,uint32_t offset,uint32_t value)390*5113495bSYour Name static inline void dp_hw_cc_cmem_write(hal_soc_handle_t hal_soc_hdl,
391*5113495bSYour Name 				       uint32_t offset,
392*5113495bSYour Name 				       uint32_t value)
393*5113495bSYour Name { }
394*5113495bSYour Name 
dp_hw_cc_cmem_addr_init(struct dp_soc * soc)395*5113495bSYour Name static inline QDF_STATUS dp_hw_cc_cmem_addr_init(struct dp_soc *soc)
396*5113495bSYour Name {
397*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
398*5113495bSYour Name }
399*5113495bSYour Name #endif
400*5113495bSYour Name 
401*5113495bSYour Name #if defined(DP_FEATURE_HW_COOKIE_CONVERSION) || defined(WLAN_SUPPORT_RX_FISA)
dp_get_cmem_allocation(struct dp_soc * soc,uint8_t for_feature)402*5113495bSYour Name static QDF_STATUS dp_get_cmem_allocation(struct dp_soc *soc,
403*5113495bSYour Name 					 uint8_t for_feature)
404*5113495bSYour Name {
405*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
406*5113495bSYour Name 
407*5113495bSYour Name 	switch (for_feature) {
408*5113495bSYour Name 	case COOKIE_CONVERSION:
409*5113495bSYour Name 		status = dp_hw_cc_cmem_addr_init(soc);
410*5113495bSYour Name 		break;
411*5113495bSYour Name 	default:
412*5113495bSYour Name 		dp_err("Invalid CMEM request");
413*5113495bSYour Name 	}
414*5113495bSYour Name 
415*5113495bSYour Name 	return status;
416*5113495bSYour Name }
417*5113495bSYour Name #else
dp_get_cmem_allocation(struct dp_soc * soc,uint8_t for_feature)418*5113495bSYour Name static QDF_STATUS dp_get_cmem_allocation(struct dp_soc *soc,
419*5113495bSYour Name 					 uint8_t for_feature)
420*5113495bSYour Name {
421*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
422*5113495bSYour Name }
423*5113495bSYour Name #endif
424*5113495bSYour Name 
425*5113495bSYour Name QDF_STATUS
dp_hw_cookie_conversion_attach(struct dp_soc_be * be_soc,struct dp_hw_cookie_conversion_t * cc_ctx,uint32_t num_descs,enum qdf_dp_desc_type desc_type,uint8_t desc_pool_id)426*5113495bSYour Name dp_hw_cookie_conversion_attach(struct dp_soc_be *be_soc,
427*5113495bSYour Name 			       struct dp_hw_cookie_conversion_t *cc_ctx,
428*5113495bSYour Name 			       uint32_t num_descs,
429*5113495bSYour Name 			       enum qdf_dp_desc_type desc_type,
430*5113495bSYour Name 			       uint8_t desc_pool_id)
431*5113495bSYour Name {
432*5113495bSYour Name 	struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc);
433*5113495bSYour Name 	uint32_t num_spt_pages, i = 0;
434*5113495bSYour Name 	struct dp_spt_page_desc *spt_desc;
435*5113495bSYour Name 	struct qdf_mem_dma_page_t *dma_page;
436*5113495bSYour Name 	uint8_t chip_id;
437*5113495bSYour Name 
438*5113495bSYour Name 	/* estimate how many SPT DDR pages needed */
439*5113495bSYour Name 	num_spt_pages = qdf_do_div(
440*5113495bSYour Name 				num_descs + (DP_CC_SPT_PAGE_MAX_ENTRIES - 1),
441*5113495bSYour Name 				DP_CC_SPT_PAGE_MAX_ENTRIES);
442*5113495bSYour Name 	num_spt_pages = num_spt_pages <= DP_CC_PPT_MAX_ENTRIES ?
443*5113495bSYour Name 					num_spt_pages : DP_CC_PPT_MAX_ENTRIES;
444*5113495bSYour Name 	dp_info("num_spt_pages needed %d", num_spt_pages);
445*5113495bSYour Name 
446*5113495bSYour Name 	dp_desc_multi_pages_mem_alloc(soc, QDF_DP_HW_CC_SPT_PAGE_TYPE,
447*5113495bSYour Name 				      &cc_ctx->page_pool, qdf_page_size,
448*5113495bSYour Name 				      num_spt_pages, 0, false);
449*5113495bSYour Name 	if (!cc_ctx->page_pool.dma_pages) {
450*5113495bSYour Name 		dp_err("spt ddr pages allocation failed");
451*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
452*5113495bSYour Name 	}
453*5113495bSYour Name 	cc_ctx->page_desc_base = qdf_mem_malloc(
454*5113495bSYour Name 			num_spt_pages * sizeof(struct dp_spt_page_desc));
455*5113495bSYour Name 	if (!cc_ctx->page_desc_base) {
456*5113495bSYour Name 		dp_err("spt page descs allocation failed");
457*5113495bSYour Name 		goto fail_0;
458*5113495bSYour Name 	}
459*5113495bSYour Name 
460*5113495bSYour Name 	chip_id = dp_mlo_get_chip_id(soc);
461*5113495bSYour Name 	cc_ctx->cmem_offset = dp_desc_pool_get_cmem_base(chip_id, desc_pool_id,
462*5113495bSYour Name 							 desc_type);
463*5113495bSYour Name 
464*5113495bSYour Name 	/* initial page desc */
465*5113495bSYour Name 	spt_desc = cc_ctx->page_desc_base;
466*5113495bSYour Name 	dma_page = cc_ctx->page_pool.dma_pages;
467*5113495bSYour Name 	while (i < num_spt_pages) {
468*5113495bSYour Name 		/* check if page address 4K aligned */
469*5113495bSYour Name 		if (qdf_unlikely(dma_page[i].page_p_addr & 0xFFF)) {
470*5113495bSYour Name 			dp_err("non-4k aligned pages addr %pK",
471*5113495bSYour Name 			       (void *)dma_page[i].page_p_addr);
472*5113495bSYour Name 			goto fail_1;
473*5113495bSYour Name 		}
474*5113495bSYour Name 
475*5113495bSYour Name 		spt_desc[i].page_v_addr =
476*5113495bSYour Name 					dma_page[i].page_v_addr_start;
477*5113495bSYour Name 		spt_desc[i].page_p_addr =
478*5113495bSYour Name 					dma_page[i].page_p_addr;
479*5113495bSYour Name 		i++;
480*5113495bSYour Name 	}
481*5113495bSYour Name 
482*5113495bSYour Name 	cc_ctx->total_page_num = num_spt_pages;
483*5113495bSYour Name 	qdf_spinlock_create(&cc_ctx->cc_lock);
484*5113495bSYour Name 
485*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
486*5113495bSYour Name fail_1:
487*5113495bSYour Name 	qdf_mem_free(cc_ctx->page_desc_base);
488*5113495bSYour Name 	cc_ctx->page_desc_base = NULL;
489*5113495bSYour Name fail_0:
490*5113495bSYour Name 	dp_desc_multi_pages_mem_free(soc, QDF_DP_HW_CC_SPT_PAGE_TYPE,
491*5113495bSYour Name 				     &cc_ctx->page_pool, 0, false);
492*5113495bSYour Name 
493*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
494*5113495bSYour Name }
495*5113495bSYour Name 
496*5113495bSYour Name QDF_STATUS
dp_hw_cookie_conversion_detach(struct dp_soc_be * be_soc,struct dp_hw_cookie_conversion_t * cc_ctx)497*5113495bSYour Name dp_hw_cookie_conversion_detach(struct dp_soc_be *be_soc,
498*5113495bSYour Name 			       struct dp_hw_cookie_conversion_t *cc_ctx)
499*5113495bSYour Name {
500*5113495bSYour Name 	struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc);
501*5113495bSYour Name 
502*5113495bSYour Name 	dp_desc_multi_pages_mem_free(soc, QDF_DP_HW_CC_SPT_PAGE_TYPE,
503*5113495bSYour Name 				     &cc_ctx->page_pool, 0, false);
504*5113495bSYour Name 	if (cc_ctx->page_desc_base)
505*5113495bSYour Name 		qdf_spinlock_destroy(&cc_ctx->cc_lock);
506*5113495bSYour Name 
507*5113495bSYour Name 	qdf_mem_free(cc_ctx->page_desc_base);
508*5113495bSYour Name 	cc_ctx->page_desc_base = NULL;
509*5113495bSYour Name 
510*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
511*5113495bSYour Name }
512*5113495bSYour Name 
513*5113495bSYour Name QDF_STATUS
dp_hw_cookie_conversion_init(struct dp_soc_be * be_soc,struct dp_hw_cookie_conversion_t * cc_ctx)514*5113495bSYour Name dp_hw_cookie_conversion_init(struct dp_soc_be *be_soc,
515*5113495bSYour Name 			     struct dp_hw_cookie_conversion_t *cc_ctx)
516*5113495bSYour Name {
517*5113495bSYour Name 	struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc);
518*5113495bSYour Name 	uint32_t i = 0;
519*5113495bSYour Name 	struct dp_spt_page_desc *spt_desc;
520*5113495bSYour Name 	uint32_t ppt_index;
521*5113495bSYour Name 	uint32_t ppt_id_start;
522*5113495bSYour Name 
523*5113495bSYour Name 	if (!cc_ctx->total_page_num) {
524*5113495bSYour Name 		dp_err("total page num is 0");
525*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
526*5113495bSYour Name 	}
527*5113495bSYour Name 
528*5113495bSYour Name 	ppt_id_start = DP_CMEM_OFFSET_TO_PPT_ID(cc_ctx->cmem_offset);
529*5113495bSYour Name 	spt_desc = cc_ctx->page_desc_base;
530*5113495bSYour Name 	while (i < cc_ctx->total_page_num) {
531*5113495bSYour Name 		/* write page PA to CMEM */
532*5113495bSYour Name 		dp_hw_cc_cmem_write(soc->hal_soc,
533*5113495bSYour Name 				    (cc_ctx->cmem_offset + be_soc->cc_cmem_base
534*5113495bSYour Name 				     + (i * DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)),
535*5113495bSYour Name 				    (spt_desc[i].page_p_addr >>
536*5113495bSYour Name 				     DP_CC_PPT_ENTRY_HW_APEND_BITS_4K_ALIGNED));
537*5113495bSYour Name 
538*5113495bSYour Name 		ppt_index = ppt_id_start + i;
539*5113495bSYour Name 
540*5113495bSYour Name 		if (ppt_index >= DP_CC_PPT_MAX_ENTRIES)
541*5113495bSYour Name 			qdf_assert_always(0);
542*5113495bSYour Name 
543*5113495bSYour Name 		spt_desc[i].ppt_index = ppt_index;
544*5113495bSYour Name 
545*5113495bSYour Name 		be_soc->page_desc_base[ppt_index].page_v_addr =
546*5113495bSYour Name 				spt_desc[i].page_v_addr;
547*5113495bSYour Name 		i++;
548*5113495bSYour Name 	}
549*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
550*5113495bSYour Name }
551*5113495bSYour Name 
552*5113495bSYour Name #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
553*5113495bSYour Name QDF_STATUS
dp_hw_cookie_conversion_deinit(struct dp_soc_be * be_soc,struct dp_hw_cookie_conversion_t * cc_ctx)554*5113495bSYour Name dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc,
555*5113495bSYour Name 			       struct dp_hw_cookie_conversion_t *cc_ctx)
556*5113495bSYour Name {
557*5113495bSYour Name 	uint32_t ppt_index;
558*5113495bSYour Name 	struct dp_spt_page_desc *spt_desc;
559*5113495bSYour Name 	int i = 0;
560*5113495bSYour Name 
561*5113495bSYour Name 	spt_desc = cc_ctx->page_desc_base;
562*5113495bSYour Name 	while (i < cc_ctx->total_page_num) {
563*5113495bSYour Name 		ppt_index = spt_desc[i].ppt_index;
564*5113495bSYour Name 		be_soc->page_desc_base[ppt_index].page_v_addr = NULL;
565*5113495bSYour Name 		i++;
566*5113495bSYour Name 	}
567*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
568*5113495bSYour Name }
569*5113495bSYour Name #else
570*5113495bSYour Name QDF_STATUS
dp_hw_cookie_conversion_deinit(struct dp_soc_be * be_soc,struct dp_hw_cookie_conversion_t * cc_ctx)571*5113495bSYour Name dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc,
572*5113495bSYour Name 			       struct dp_hw_cookie_conversion_t *cc_ctx)
573*5113495bSYour Name {
574*5113495bSYour Name 	struct dp_soc *soc = DP_SOC_BE_GET_SOC(be_soc);
575*5113495bSYour Name 	uint32_t ppt_index;
576*5113495bSYour Name 	struct dp_spt_page_desc *spt_desc;
577*5113495bSYour Name 	int i = 0;
578*5113495bSYour Name 
579*5113495bSYour Name 	spt_desc = cc_ctx->page_desc_base;
580*5113495bSYour Name 	while (i < cc_ctx->total_page_num) {
581*5113495bSYour Name 		/* reset PA in CMEM to NULL */
582*5113495bSYour Name 		dp_hw_cc_cmem_write(soc->hal_soc,
583*5113495bSYour Name 				    (cc_ctx->cmem_offset + be_soc->cc_cmem_base
584*5113495bSYour Name 				     + (i * DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)),
585*5113495bSYour Name 				    0);
586*5113495bSYour Name 
587*5113495bSYour Name 		ppt_index = spt_desc[i].ppt_index;
588*5113495bSYour Name 		be_soc->page_desc_base[ppt_index].page_v_addr = NULL;
589*5113495bSYour Name 		i++;
590*5113495bSYour Name 	}
591*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
592*5113495bSYour Name }
593*5113495bSYour Name #endif
594*5113495bSYour Name 
595*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
dp_soc_ppeds_attach_be(struct dp_soc * soc)596*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_attach_be(struct dp_soc *soc)
597*5113495bSYour Name {
598*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
599*5113495bSYour Name 	int target_type = hal_get_target_type(soc->hal_soc);
600*5113495bSYour Name 	struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
601*5113495bSYour Name 
602*5113495bSYour Name 	/*
603*5113495bSYour Name 	 * Check if PPE DS is enabled and wlan soc supports it.
604*5113495bSYour Name 	 */
605*5113495bSYour Name 	if (!wlan_cfg_get_dp_soc_ppeds_enable(soc->wlan_cfg_ctx) ||
606*5113495bSYour Name 	    !dp_ppeds_target_supported(target_type))
607*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
608*5113495bSYour Name 
609*5113495bSYour Name 	if (dp_ppeds_attach_soc_be(be_soc) != QDF_STATUS_SUCCESS)
610*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
611*5113495bSYour Name 
612*5113495bSYour Name 	cdp_ops->ppeds_ops = &dp_ops_ppeds_be;
613*5113495bSYour Name 
614*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
615*5113495bSYour Name }
616*5113495bSYour Name 
dp_soc_ppeds_detach_be(struct dp_soc * soc)617*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_detach_be(struct dp_soc *soc)
618*5113495bSYour Name {
619*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
620*5113495bSYour Name 	struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
621*5113495bSYour Name 
622*5113495bSYour Name 	if (!be_soc->ppeds_handle)
623*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
624*5113495bSYour Name 
625*5113495bSYour Name 	dp_ppeds_detach_soc_be(be_soc);
626*5113495bSYour Name 
627*5113495bSYour Name 	cdp_ops->ppeds_ops = NULL;
628*5113495bSYour Name 
629*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
630*5113495bSYour Name }
631*5113495bSYour Name 
dp_peer_ppeds_default_route_be(struct dp_soc * soc,struct dp_peer_be * be_peer,uint8_t vdev_id,uint16_t src_info)632*5113495bSYour Name static QDF_STATUS dp_peer_ppeds_default_route_be(struct dp_soc *soc,
633*5113495bSYour Name 						 struct dp_peer_be *be_peer,
634*5113495bSYour Name 						 uint8_t vdev_id,
635*5113495bSYour Name 						 uint16_t src_info)
636*5113495bSYour Name {
637*5113495bSYour Name 	uint16_t service_code;
638*5113495bSYour Name 	uint8_t priority_valid;
639*5113495bSYour Name 	uint8_t use_ppe_ds = PEER_ROUTING_USE_PPE;
640*5113495bSYour Name 	uint8_t peer_routing_enabled = PEER_ROUTING_ENABLED;
641*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
642*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
643*5113495bSYour Name 	struct dp_vdev_be *be_vdev;
644*5113495bSYour Name 
645*5113495bSYour Name 	be_vdev = dp_get_be_vdev_from_dp_vdev(be_peer->peer.vdev);
646*5113495bSYour Name 
647*5113495bSYour Name 	/*
648*5113495bSYour Name 	 * Program service code bypass to avoid L2 new mac address
649*5113495bSYour Name 	 * learning exception when fdb learning is disabled.
650*5113495bSYour Name 	 */
651*5113495bSYour Name 	service_code = PPE_DRV_SC_SPF_BYPASS;
652*5113495bSYour Name 	priority_valid = be_peer->priority_valid;
653*5113495bSYour Name 
654*5113495bSYour Name 	/*
655*5113495bSYour Name 	 * if FST is enabled then let flow rule take the decision of
656*5113495bSYour Name 	 * routing the pkt to DS or host
657*5113495bSYour Name 	 */
658*5113495bSYour Name 	if (wlan_cfg_is_rx_flow_tag_enabled(cfg))
659*5113495bSYour Name 		use_ppe_ds = 0;
660*5113495bSYour Name 
661*5113495bSYour Name 	if (soc->cdp_soc.ol_ops->peer_set_ppeds_default_routing) {
662*5113495bSYour Name 		status =
663*5113495bSYour Name 		soc->cdp_soc.ol_ops->peer_set_ppeds_default_routing
664*5113495bSYour Name 				(soc->ctrl_psoc,
665*5113495bSYour Name 				be_peer->peer.mac_addr.raw,
666*5113495bSYour Name 				service_code, priority_valid,
667*5113495bSYour Name 				src_info, vdev_id, use_ppe_ds,
668*5113495bSYour Name 				peer_routing_enabled);
669*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
670*5113495bSYour Name 			dp_err("vdev_id: %d, PPE peer routing mac:"
671*5113495bSYour Name 			       QDF_MAC_ADDR_FMT, vdev_id,
672*5113495bSYour Name 			       QDF_MAC_ADDR_REF(be_peer->peer.mac_addr.raw));
673*5113495bSYour Name 
674*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
675*5113495bSYour Name 		}
676*5113495bSYour Name 	}
677*5113495bSYour Name 
678*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
679*5113495bSYour Name }
680*5113495bSYour Name 
681*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
dp_peer_setup_ppeds_be(struct dp_soc * soc,struct dp_peer * peer,struct dp_vdev_be * be_vdev,void * args)682*5113495bSYour Name QDF_STATUS dp_peer_setup_ppeds_be(struct dp_soc *soc,
683*5113495bSYour Name 				  struct dp_peer *peer,
684*5113495bSYour Name 				  struct dp_vdev_be *be_vdev,
685*5113495bSYour Name 				  void *args)
686*5113495bSYour Name {
687*5113495bSYour Name 	struct dp_peer *mld_peer;
688*5113495bSYour Name 	struct dp_soc *mld_soc;
689*5113495bSYour Name 	struct dp_soc_be *be_soc;
690*5113495bSYour Name 	struct cdp_soc_t *cdp_soc;
691*5113495bSYour Name 	struct dp_peer_be *be_peer = dp_get_be_peer_from_dp_peer(peer);
692*5113495bSYour Name 	struct cdp_ds_vp_params vp_params = {0};
693*5113495bSYour Name 	struct dp_ppe_vp_profile *ppe_vp_profile = (struct dp_ppe_vp_profile *)args;
694*5113495bSYour Name 	uint16_t src_info = ppe_vp_profile->vp_num;
695*5113495bSYour Name 	uint8_t vdev_id = be_vdev->vdev.vdev_id;
696*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
697*5113495bSYour Name 
698*5113495bSYour Name 	if (!be_peer) {
699*5113495bSYour Name 		dp_err("BE peer is null");
700*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
701*5113495bSYour Name 	}
702*5113495bSYour Name 
703*5113495bSYour Name 	if (IS_DP_LEGACY_PEER(peer)) {
704*5113495bSYour Name 		qdf_status = dp_peer_ppeds_default_route_be(soc, be_peer,
705*5113495bSYour Name 							    vdev_id, src_info);
706*5113495bSYour Name 	} else if (IS_MLO_DP_MLD_PEER(peer)) {
707*5113495bSYour Name 		int i;
708*5113495bSYour Name 		struct dp_peer *link_peer = NULL;
709*5113495bSYour Name 		struct dp_mld_link_peers link_peers_info;
710*5113495bSYour Name 
711*5113495bSYour Name 		/* get link peers with reference */
712*5113495bSYour Name 		dp_get_link_peers_ref_from_mld_peer(soc, peer, &link_peers_info,
713*5113495bSYour Name 						    DP_MOD_ID_DS);
714*5113495bSYour Name 
715*5113495bSYour Name 		for (i = 0; i < link_peers_info.num_links; i++) {
716*5113495bSYour Name 			link_peer = link_peers_info.link_peers[i];
717*5113495bSYour Name 			be_peer = dp_get_be_peer_from_dp_peer(link_peer);
718*5113495bSYour Name 			if (!be_peer) {
719*5113495bSYour Name 				dp_err("BE peer is null");
720*5113495bSYour Name 				continue;
721*5113495bSYour Name 			}
722*5113495bSYour Name 
723*5113495bSYour Name 			be_vdev = dp_get_be_vdev_from_dp_vdev(link_peer->vdev);
724*5113495bSYour Name 			if (!be_vdev) {
725*5113495bSYour Name 				dp_err("BE vap is null for peer id %d ",
726*5113495bSYour Name 				       link_peer->peer_id);
727*5113495bSYour Name 				continue;
728*5113495bSYour Name 			}
729*5113495bSYour Name 
730*5113495bSYour Name 			vdev_id = be_vdev->vdev.vdev_id;
731*5113495bSYour Name 			soc = link_peer->vdev->pdev->soc;
732*5113495bSYour Name 			qdf_status = dp_peer_ppeds_default_route_be(soc,
733*5113495bSYour Name 								    be_peer,
734*5113495bSYour Name 								    vdev_id,
735*5113495bSYour Name 								    src_info);
736*5113495bSYour Name 		}
737*5113495bSYour Name 
738*5113495bSYour Name 		dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_DS);
739*5113495bSYour Name 	} else {
740*5113495bSYour Name 		mld_peer = DP_GET_MLD_PEER_FROM_PEER(peer);
741*5113495bSYour Name 
742*5113495bSYour Name 		if (!mld_peer)
743*5113495bSYour Name 			return qdf_status;
744*5113495bSYour Name 
745*5113495bSYour Name 		/*
746*5113495bSYour Name 		 * In case of MLO link peer,
747*5113495bSYour Name 		 * Fetch the VP profile from the mld vdev.
748*5113495bSYour Name 		 */
749*5113495bSYour Name 		be_vdev = dp_get_be_vdev_from_dp_vdev(mld_peer->vdev);
750*5113495bSYour Name 		if (!be_vdev) {
751*5113495bSYour Name 			dp_err("BE vap is null");
752*5113495bSYour Name 			return QDF_STATUS_E_NULL_VALUE;
753*5113495bSYour Name 		}
754*5113495bSYour Name 
755*5113495bSYour Name 		/*
756*5113495bSYour Name 		 * Extract the VP profile from the vap
757*5113495bSYour Name 		 * in case of MLO peer, we have to get the profile from
758*5113495bSYour Name 		 * the MLD vdev's osif handle and not the link peer.
759*5113495bSYour Name 		 */
760*5113495bSYour Name 		mld_soc = mld_peer->vdev->pdev->soc;
761*5113495bSYour Name 		cdp_soc = &mld_soc->cdp_soc;
762*5113495bSYour Name 		if (!cdp_soc->ol_ops->get_ppeds_profile_info_for_vap) {
763*5113495bSYour Name 			dp_err("%pK: Register PPEDS profile info API before use", cdp_soc);
764*5113495bSYour Name 			return QDF_STATUS_E_NULL_VALUE;
765*5113495bSYour Name 		}
766*5113495bSYour Name 
767*5113495bSYour Name 		qdf_status = cdp_soc->ol_ops->get_ppeds_profile_info_for_vap(mld_soc->ctrl_psoc,
768*5113495bSYour Name 									     mld_peer->vdev->vdev_id,
769*5113495bSYour Name 									     &vp_params);
770*5113495bSYour Name 		if (qdf_status == QDF_STATUS_E_NULL_VALUE) {
771*5113495bSYour Name 			dp_err("%pK: Failed to get ppeds profile for mld soc", mld_soc);
772*5113495bSYour Name 			return qdf_status;
773*5113495bSYour Name 		}
774*5113495bSYour Name 
775*5113495bSYour Name 		/*
776*5113495bSYour Name 		 * Check if PPE DS routing is enabled on
777*5113495bSYour Name 		 * the associated vap.
778*5113495bSYour Name 		 */
779*5113495bSYour Name 		if (vp_params.ppe_vp_type != PPE_VP_USER_TYPE_DS)
780*5113495bSYour Name 			return qdf_status;
781*5113495bSYour Name 
782*5113495bSYour Name 		be_soc = dp_get_be_soc_from_dp_soc(mld_soc);
783*5113495bSYour Name 		ppe_vp_profile = &be_soc->ppe_vp_profile[vp_params.ppe_vp_profile_idx];
784*5113495bSYour Name 		src_info = ppe_vp_profile->vp_num;
785*5113495bSYour Name 
786*5113495bSYour Name 		qdf_status = dp_peer_ppeds_default_route_be(soc, be_peer,
787*5113495bSYour Name 							    vdev_id, src_info);
788*5113495bSYour Name 	}
789*5113495bSYour Name 
790*5113495bSYour Name 	return qdf_status;
791*5113495bSYour Name }
792*5113495bSYour Name #else
dp_peer_setup_ppeds_be(struct dp_soc * soc,struct dp_peer * peer,struct dp_vdev_be * be_vdev void * args)793*5113495bSYour Name static QDF_STATUS dp_peer_setup_ppeds_be(struct dp_soc *soc,
794*5113495bSYour Name 					 struct dp_peer *peer,
795*5113495bSYour Name 					 struct dp_vdev_be *be_vdev
796*5113495bSYour Name 					 void *args)
797*5113495bSYour Name {
798*5113495bSYour Name 	struct dp_ppe_vp_profile *vp_profile = (struct dp_ppe_vp_profile *)args;
799*5113495bSYour Name 	struct dp_peer_be *be_peer = dp_get_be_peer_from_dp_peer(peer);
800*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
801*5113495bSYour Name 
802*5113495bSYour Name 	if (!be_peer) {
803*5113495bSYour Name 		dp_err("BE peer is null");
804*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
805*5113495bSYour Name 	}
806*5113495bSYour Name 
807*5113495bSYour Name 	qdf_status = dp_peer_ppeds_default_route_be(soc, be_peer,
808*5113495bSYour Name 						    be_vdev->vdev.vdev_id,
809*5113495bSYour Name 						    vp_profile->vp_num);
810*5113495bSYour Name 
811*5113495bSYour Name 	return qdf_status;
812*5113495bSYour Name }
813*5113495bSYour Name #endif
814*5113495bSYour Name #else
dp_ppeds_init_soc_be(struct dp_soc * soc)815*5113495bSYour Name static QDF_STATUS dp_ppeds_init_soc_be(struct dp_soc *soc)
816*5113495bSYour Name {
817*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
818*5113495bSYour Name }
819*5113495bSYour Name 
dp_ppeds_deinit_soc_be(struct dp_soc * soc)820*5113495bSYour Name static QDF_STATUS dp_ppeds_deinit_soc_be(struct dp_soc *soc)
821*5113495bSYour Name {
822*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
823*5113495bSYour Name }
824*5113495bSYour Name 
dp_soc_ppeds_attach_be(struct dp_soc * soc)825*5113495bSYour Name static inline QDF_STATUS dp_soc_ppeds_attach_be(struct dp_soc *soc)
826*5113495bSYour Name {
827*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
828*5113495bSYour Name }
829*5113495bSYour Name 
dp_soc_ppeds_detach_be(struct dp_soc * soc)830*5113495bSYour Name static inline QDF_STATUS dp_soc_ppeds_detach_be(struct dp_soc *soc)
831*5113495bSYour Name {
832*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
833*5113495bSYour Name }
834*5113495bSYour Name 
dp_peer_setup_ppeds_be(struct dp_soc * soc,struct dp_peer * peer,struct dp_vdev_be * be_vdev,void * args)835*5113495bSYour Name QDF_STATUS dp_peer_setup_ppeds_be(struct dp_soc *soc, struct dp_peer *peer,
836*5113495bSYour Name 				  struct dp_vdev_be *be_vdev,
837*5113495bSYour Name 				  void *args)
838*5113495bSYour Name {
839*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
840*5113495bSYour Name }
841*5113495bSYour Name 
dp_ppeds_stop_soc_be(struct dp_soc * soc)842*5113495bSYour Name static inline void dp_ppeds_stop_soc_be(struct dp_soc *soc)
843*5113495bSYour Name {
844*5113495bSYour Name }
845*5113495bSYour Name #endif /* WLAN_SUPPORT_PPEDS */
846*5113495bSYour Name 
dp_reo_shared_qaddr_detach(struct dp_soc * soc)847*5113495bSYour Name void dp_reo_shared_qaddr_detach(struct dp_soc *soc)
848*5113495bSYour Name {
849*5113495bSYour Name 	qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
850*5113495bSYour Name 				REO_QUEUE_REF_ML_TABLE_SIZE,
851*5113495bSYour Name 				soc->reo_qref.mlo_reo_qref_table_vaddr,
852*5113495bSYour Name 				soc->reo_qref.mlo_reo_qref_table_paddr, 0);
853*5113495bSYour Name 	qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
854*5113495bSYour Name 				REO_QUEUE_REF_NON_ML_TABLE_SIZE,
855*5113495bSYour Name 				soc->reo_qref.non_mlo_reo_qref_table_vaddr,
856*5113495bSYour Name 				soc->reo_qref.non_mlo_reo_qref_table_paddr, 0);
857*5113495bSYour Name }
858*5113495bSYour Name 
859*5113495bSYour Name #ifdef QCA_SUPPORT_DP_GLOBAL_CTX
dp_soc_tx_cookie_detach_be(struct dp_soc * soc)860*5113495bSYour Name static void dp_soc_tx_cookie_detach_be(struct dp_soc *soc)
861*5113495bSYour Name {
862*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
863*5113495bSYour Name 	int i = 0;
864*5113495bSYour Name 	struct dp_global_context *dp_global;
865*5113495bSYour Name 
866*5113495bSYour Name 	dp_global = wlan_objmgr_get_global_ctx();
867*5113495bSYour Name 
868*5113495bSYour Name 	dp_global->tx_cookie_ctx_alloc_cnt--;
869*5113495bSYour Name 	if (dp_global->tx_cookie_ctx_alloc_cnt == 0) {
870*5113495bSYour Name 		for (i = 0; i < MAX_TXDESC_POOLS; i++) {
871*5113495bSYour Name 			dp_hw_cookie_conversion_detach(be_soc,
872*5113495bSYour Name 						       dp_global->tx_cc_ctx[i]);
873*5113495bSYour Name 			qdf_mem_free(dp_global->tx_cc_ctx[i]);
874*5113495bSYour Name 		}
875*5113495bSYour Name 	}
876*5113495bSYour Name 
877*5113495bSYour Name 	dp_global->spcl_tx_cookie_ctx_alloc_cnt--;
878*5113495bSYour Name 	if (dp_global->spcl_tx_cookie_ctx_alloc_cnt == 0) {
879*5113495bSYour Name 		for (i = 0; i < MAX_TXDESC_POOLS; i++) {
880*5113495bSYour Name 			dp_hw_cookie_conversion_detach(
881*5113495bSYour Name 					be_soc,
882*5113495bSYour Name 					dp_global->spcl_tx_cc_ctx[i]);
883*5113495bSYour Name 			qdf_mem_free(dp_global->spcl_tx_cc_ctx[i]);
884*5113495bSYour Name 		}
885*5113495bSYour Name 	}
886*5113495bSYour Name }
887*5113495bSYour Name 
dp_soc_tx_cookie_attach_be(struct dp_soc * soc)888*5113495bSYour Name static QDF_STATUS dp_soc_tx_cookie_attach_be(struct dp_soc *soc)
889*5113495bSYour Name {
890*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
891*5113495bSYour Name 	struct dp_hw_cookie_conversion_t *cc_ctx;
892*5113495bSYour Name 	struct dp_global_context *dp_global;
893*5113495bSYour Name 	struct dp_hw_cookie_conversion_t *spcl_cc_ctx;
894*5113495bSYour Name 	uint32_t num_entries;
895*5113495bSYour Name 	int i = 0;
896*5113495bSYour Name 	QDF_STATUS qdf_status;
897*5113495bSYour Name 
898*5113495bSYour Name 	dp_global = wlan_objmgr_get_global_ctx();
899*5113495bSYour Name 	if (dp_global->tx_cookie_ctx_alloc_cnt == 0) {
900*5113495bSYour Name 		for (i = 0; i < MAX_TXDESC_POOLS; i++) {
901*5113495bSYour Name 			dp_global->tx_cc_ctx[i] =
902*5113495bSYour Name 				qdf_mem_malloc(
903*5113495bSYour Name 				sizeof(struct dp_hw_cookie_conversion_t));
904*5113495bSYour Name 			cc_ctx = dp_global->tx_cc_ctx[i];
905*5113495bSYour Name 			num_entries =
906*5113495bSYour Name 				wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
907*5113495bSYour Name 			qdf_status =
908*5113495bSYour Name 				dp_hw_cookie_conversion_attach(
909*5113495bSYour Name 						be_soc,
910*5113495bSYour Name 						cc_ctx,
911*5113495bSYour Name 						num_entries,
912*5113495bSYour Name 						QDF_DP_TX_DESC_TYPE, i);
913*5113495bSYour Name 			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
914*5113495bSYour Name 				return QDF_STATUS_E_FAILURE;
915*5113495bSYour Name 		}
916*5113495bSYour Name 	}
917*5113495bSYour Name 	dp_global->tx_cookie_ctx_alloc_cnt++;
918*5113495bSYour Name 
919*5113495bSYour Name 	if (dp_global->spcl_tx_cookie_ctx_alloc_cnt == 0) {
920*5113495bSYour Name 		for (i = 0; i < MAX_TXDESC_POOLS; i++) {
921*5113495bSYour Name 			dp_global->spcl_tx_cc_ctx[i] =
922*5113495bSYour Name 				qdf_mem_malloc(
923*5113495bSYour Name 				sizeof(struct dp_hw_cookie_conversion_t));
924*5113495bSYour Name 			spcl_cc_ctx = dp_global->spcl_tx_cc_ctx[i];
925*5113495bSYour Name 			num_entries =
926*5113495bSYour Name 				wlan_cfg_get_num_tx_spl_desc(soc->wlan_cfg_ctx);
927*5113495bSYour Name 			qdf_status =
928*5113495bSYour Name 				dp_hw_cookie_conversion_attach(
929*5113495bSYour Name 						be_soc,
930*5113495bSYour Name 						spcl_cc_ctx,
931*5113495bSYour Name 						num_entries,
932*5113495bSYour Name 						QDF_DP_TX_SPCL_DESC_TYPE, i);
933*5113495bSYour Name 			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
934*5113495bSYour Name 				return QDF_STATUS_E_FAILURE;
935*5113495bSYour Name 		}
936*5113495bSYour Name 	}
937*5113495bSYour Name 	dp_global->spcl_tx_cookie_ctx_alloc_cnt++;
938*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
939*5113495bSYour Name }
940*5113495bSYour Name 
dp_soc_tx_cookie_deinit_be(struct dp_soc * soc)941*5113495bSYour Name static void dp_soc_tx_cookie_deinit_be(struct dp_soc *soc)
942*5113495bSYour Name {
943*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
944*5113495bSYour Name 	struct dp_global_context *dp_global;
945*5113495bSYour Name 	int i = 0;
946*5113495bSYour Name 
947*5113495bSYour Name 	dp_global = wlan_objmgr_get_global_ctx();
948*5113495bSYour Name 
949*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++)
950*5113495bSYour Name 		dp_hw_cookie_conversion_deinit(
951*5113495bSYour Name 				be_soc,
952*5113495bSYour Name 				dp_global->tx_cc_ctx[i]);
953*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++)
954*5113495bSYour Name 		dp_hw_cookie_conversion_deinit(be_soc,
955*5113495bSYour Name 					       dp_global->spcl_tx_cc_ctx[i]);
956*5113495bSYour Name }
957*5113495bSYour Name 
dp_soc_tx_cookie_init_be(struct dp_soc * soc)958*5113495bSYour Name static QDF_STATUS dp_soc_tx_cookie_init_be(struct dp_soc *soc)
959*5113495bSYour Name {
960*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
961*5113495bSYour Name 	struct dp_global_context *dp_global;
962*5113495bSYour Name 	struct dp_hw_cookie_conversion_t *cc_ctx;
963*5113495bSYour Name 	struct dp_hw_cookie_conversion_t *spcl_cc_ctx;
964*5113495bSYour Name 	QDF_STATUS qdf_status;
965*5113495bSYour Name 	int i = 0;
966*5113495bSYour Name 
967*5113495bSYour Name 	dp_global = wlan_objmgr_get_global_ctx();
968*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
969*5113495bSYour Name 		cc_ctx = dp_global->tx_cc_ctx[i];
970*5113495bSYour Name 		qdf_status =
971*5113495bSYour Name 			dp_hw_cookie_conversion_init(be_soc,
972*5113495bSYour Name 						     cc_ctx);
973*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
974*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
975*5113495bSYour Name 	}
976*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
977*5113495bSYour Name 		spcl_cc_ctx = dp_global->spcl_tx_cc_ctx[i];
978*5113495bSYour Name 		qdf_status =
979*5113495bSYour Name 			dp_hw_cookie_conversion_init(be_soc,
980*5113495bSYour Name 						     spcl_cc_ctx);
981*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
982*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
983*5113495bSYour Name 	}
984*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
985*5113495bSYour Name }
986*5113495bSYour Name #else
dp_soc_tx_cookie_detach_be(struct dp_soc * soc)987*5113495bSYour Name static void dp_soc_tx_cookie_detach_be(struct dp_soc *soc)
988*5113495bSYour Name {
989*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
990*5113495bSYour Name 	int i = 0;
991*5113495bSYour Name 
992*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
993*5113495bSYour Name 		dp_hw_cookie_conversion_detach(
994*5113495bSYour Name 				be_soc,
995*5113495bSYour Name 				&be_soc->tx_cc_ctx[i]);
996*5113495bSYour Name 	}
997*5113495bSYour Name }
998*5113495bSYour Name 
dp_soc_tx_cookie_attach_be(struct dp_soc * soc)999*5113495bSYour Name static QDF_STATUS dp_soc_tx_cookie_attach_be(struct dp_soc *soc)
1000*5113495bSYour Name {
1001*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1002*5113495bSYour Name 	uint32_t num_entries;
1003*5113495bSYour Name 	int i = 0;
1004*5113495bSYour Name 	QDF_STATUS qdf_status;
1005*5113495bSYour Name 
1006*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
1007*5113495bSYour Name 		num_entries = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
1008*5113495bSYour Name 		qdf_status =
1009*5113495bSYour Name 			dp_hw_cookie_conversion_attach(
1010*5113495bSYour Name 					be_soc,
1011*5113495bSYour Name 					&be_soc->tx_cc_ctx[i],
1012*5113495bSYour Name 					num_entries,
1013*5113495bSYour Name 					QDF_DP_TX_DESC_TYPE, i);
1014*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1015*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
1016*5113495bSYour Name 	}
1017*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1018*5113495bSYour Name }
1019*5113495bSYour Name 
dp_soc_tx_cookie_deinit_be(struct dp_soc * soc)1020*5113495bSYour Name static void dp_soc_tx_cookie_deinit_be(struct dp_soc *soc)
1021*5113495bSYour Name {
1022*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1023*5113495bSYour Name 	int i = 0;
1024*5113495bSYour Name 
1025*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++)
1026*5113495bSYour Name 		dp_hw_cookie_conversion_deinit(
1027*5113495bSYour Name 				be_soc,
1028*5113495bSYour Name 				&be_soc->tx_cc_ctx[i]);
1029*5113495bSYour Name }
1030*5113495bSYour Name 
dp_soc_tx_cookie_init_be(struct dp_soc * soc)1031*5113495bSYour Name static QDF_STATUS dp_soc_tx_cookie_init_be(struct dp_soc *soc)
1032*5113495bSYour Name {
1033*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1034*5113495bSYour Name 	int i = 0;
1035*5113495bSYour Name 	QDF_STATUS qdf_status;
1036*5113495bSYour Name 
1037*5113495bSYour Name 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
1038*5113495bSYour Name 		qdf_status =
1039*5113495bSYour Name 			dp_hw_cookie_conversion_init(
1040*5113495bSYour Name 					be_soc,
1041*5113495bSYour Name 					&be_soc->tx_cc_ctx[i]);
1042*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1043*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
1044*5113495bSYour Name 	}
1045*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1046*5113495bSYour Name }
1047*5113495bSYour Name #endif
1048*5113495bSYour Name 
dp_soc_detach_be(struct dp_soc * soc)1049*5113495bSYour Name static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc)
1050*5113495bSYour Name {
1051*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1052*5113495bSYour Name 	dp_mlo_dev_obj_t mlo_dev_obj;
1053*5113495bSYour Name 	int i = 0;
1054*5113495bSYour Name 
1055*5113495bSYour Name 	dp_soc_ppeds_detach_be(soc);
1056*5113495bSYour Name 	dp_reo_shared_qaddr_detach(soc);
1057*5113495bSYour Name 
1058*5113495bSYour Name 	mlo_dev_obj = dp_get_mlo_dev_list_obj(be_soc);
1059*5113495bSYour Name 	dp_mlo_dev_ctxt_list_detach_wrapper(mlo_dev_obj);
1060*5113495bSYour Name 	dp_soc_tx_cookie_detach_be(soc);
1061*5113495bSYour Name 
1062*5113495bSYour Name 	for (i = 0; i < MAX_RXDESC_POOLS; i++)
1063*5113495bSYour Name 		dp_hw_cookie_conversion_detach(be_soc,
1064*5113495bSYour Name 					       &be_soc->rx_cc_ctx[i]);
1065*5113495bSYour Name 
1066*5113495bSYour Name 	qdf_mem_free(be_soc->page_desc_base);
1067*5113495bSYour Name 	be_soc->page_desc_base = NULL;
1068*5113495bSYour Name 
1069*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1070*5113495bSYour Name }
1071*5113495bSYour Name 
1072*5113495bSYour Name #ifdef QCA_SUPPORT_DP_GLOBAL_CTX
dp_set_rx_fst_be(struct dp_rx_fst * fst)1073*5113495bSYour Name static void dp_set_rx_fst_be(struct dp_rx_fst *fst)
1074*5113495bSYour Name {
1075*5113495bSYour Name 	struct dp_global_context *dp_global = wlan_objmgr_get_global_ctx();
1076*5113495bSYour Name 
1077*5113495bSYour Name 	if (dp_global)
1078*5113495bSYour Name 		dp_global->fst_ctx = fst;
1079*5113495bSYour Name }
1080*5113495bSYour Name 
dp_get_rx_fst_be(void)1081*5113495bSYour Name static struct dp_rx_fst *dp_get_rx_fst_be(void)
1082*5113495bSYour Name {
1083*5113495bSYour Name 	struct dp_global_context *dp_global = wlan_objmgr_get_global_ctx();
1084*5113495bSYour Name 
1085*5113495bSYour Name 	if (dp_global)
1086*5113495bSYour Name 		return dp_global->fst_ctx;
1087*5113495bSYour Name 
1088*5113495bSYour Name 	return NULL;
1089*5113495bSYour Name }
1090*5113495bSYour Name 
dp_rx_fst_release_ref_be(void)1091*5113495bSYour Name static uint32_t dp_rx_fst_release_ref_be(void)
1092*5113495bSYour Name {
1093*5113495bSYour Name 	struct dp_global_context *dp_global = wlan_objmgr_get_global_ctx();
1094*5113495bSYour Name 	uint32_t rx_fst_ref_cnt;
1095*5113495bSYour Name 
1096*5113495bSYour Name 	if (dp_global) {
1097*5113495bSYour Name 		rx_fst_ref_cnt = qdf_atomic_read(&dp_global->rx_fst_ref_cnt);
1098*5113495bSYour Name 		qdf_atomic_dec(&dp_global->rx_fst_ref_cnt);
1099*5113495bSYour Name 		return rx_fst_ref_cnt;
1100*5113495bSYour Name 	}
1101*5113495bSYour Name 
1102*5113495bSYour Name 	return 1;
1103*5113495bSYour Name }
1104*5113495bSYour Name 
dp_rx_fst_get_ref_be(void)1105*5113495bSYour Name static void dp_rx_fst_get_ref_be(void)
1106*5113495bSYour Name {
1107*5113495bSYour Name 	struct dp_global_context *dp_global = wlan_objmgr_get_global_ctx();
1108*5113495bSYour Name 
1109*5113495bSYour Name 	if (dp_global)
1110*5113495bSYour Name 		qdf_atomic_inc(&dp_global->rx_fst_ref_cnt);
1111*5113495bSYour Name }
1112*5113495bSYour Name 
1113*5113495bSYour Name #else
dp_set_rx_fst_be(struct dp_rx_fst * fst)1114*5113495bSYour Name static void dp_set_rx_fst_be(struct dp_rx_fst *fst)
1115*5113495bSYour Name {
1116*5113495bSYour Name }
1117*5113495bSYour Name 
dp_get_rx_fst_be(void)1118*5113495bSYour Name static struct dp_rx_fst *dp_get_rx_fst_be(void)
1119*5113495bSYour Name {
1120*5113495bSYour Name 	return NULL;
1121*5113495bSYour Name }
1122*5113495bSYour Name 
dp_rx_fst_release_ref_be(void)1123*5113495bSYour Name static uint32_t dp_rx_fst_release_ref_be(void)
1124*5113495bSYour Name {
1125*5113495bSYour Name 	return 1;
1126*5113495bSYour Name }
1127*5113495bSYour Name 
dp_rx_fst_get_ref_be(void)1128*5113495bSYour Name static void dp_rx_fst_get_ref_be(void)
1129*5113495bSYour Name {
1130*5113495bSYour Name }
1131*5113495bSYour Name #endif
1132*5113495bSYour Name 
1133*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
1134*5113495bSYour Name #ifdef WLAN_MCAST_MLO
1135*5113495bSYour Name static inline void
dp_mlo_mcast_init(struct dp_soc * soc,struct dp_vdev * vdev)1136*5113495bSYour Name dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
1137*5113495bSYour Name {
1138*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
1139*5113495bSYour Name 
1140*5113495bSYour Name 	be_vdev->mcast_primary = false;
1141*5113495bSYour Name 
1142*5113495bSYour Name 	hal_tx_mcast_mlo_reinject_routing_set(
1143*5113495bSYour Name 				soc->hal_soc,
1144*5113495bSYour Name 				HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY);
1145*5113495bSYour Name 
1146*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_ap) {
1147*5113495bSYour Name 		hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
1148*5113495bSYour Name 					   vdev->vdev_id,
1149*5113495bSYour Name 					   HAL_TX_MCAST_CTRL_FW_EXCEPTION);
1150*5113495bSYour Name 	}
1151*5113495bSYour Name }
1152*5113495bSYour Name 
1153*5113495bSYour Name static inline void
dp_mlo_mcast_deinit(struct dp_soc * soc,struct dp_vdev * vdev)1154*5113495bSYour Name dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
1155*5113495bSYour Name {
1156*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
1157*5113495bSYour Name 
1158*5113495bSYour Name 	be_vdev->mcast_primary = false;
1159*5113495bSYour Name 	vdev->mlo_vdev = 0;
1160*5113495bSYour Name }
1161*5113495bSYour Name 
1162*5113495bSYour Name #else
1163*5113495bSYour Name static inline void
dp_mlo_mcast_init(struct dp_soc * soc,struct dp_vdev * vdev)1164*5113495bSYour Name dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
1165*5113495bSYour Name {
1166*5113495bSYour Name }
1167*5113495bSYour Name 
1168*5113495bSYour Name static inline void
dp_mlo_mcast_deinit(struct dp_soc * soc,struct dp_vdev * vdev)1169*5113495bSYour Name dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
1170*5113495bSYour Name {
1171*5113495bSYour Name }
1172*5113495bSYour Name #endif
1173*5113495bSYour Name 
dp_get_rx_hash_key_be(struct dp_soc * soc,struct cdp_lro_hash_config * lro_hash)1174*5113495bSYour Name static void dp_get_rx_hash_key_be(struct dp_soc *soc,
1175*5113495bSYour Name 				  struct cdp_lro_hash_config *lro_hash)
1176*5113495bSYour Name {
1177*5113495bSYour Name 	dp_mlo_get_rx_hash_key(soc, lro_hash);
1178*5113495bSYour Name }
1179*5113495bSYour Name 
1180*5113495bSYour Name #ifdef WLAN_DP_MLO_DEV_CTX
1181*5113495bSYour Name static inline void
dp_attach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be * be_soc,struct dp_vdev * vdev,struct dp_mlo_dev_ctxt * mlo_dev_ctxt)1182*5113495bSYour Name dp_attach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be *be_soc,
1183*5113495bSYour Name 				    struct dp_vdev *vdev,
1184*5113495bSYour Name 				    struct dp_mlo_dev_ctxt *mlo_dev_ctxt)
1185*5113495bSYour Name {
1186*5113495bSYour Name 	uint8_t pdev_id = vdev->pdev->pdev_id;
1187*5113495bSYour Name 
1188*5113495bSYour Name 	qdf_spin_lock_bh(&mlo_dev_ctxt->vdev_list_lock);
1189*5113495bSYour Name 	if (vdev->is_bridge_vdev) {
1190*5113495bSYour Name 		if (mlo_dev_ctxt->bridge_vdev[be_soc->mlo_chip_id][pdev_id]
1191*5113495bSYour Name 		    != CDP_INVALID_VDEV_ID)
1192*5113495bSYour Name 			dp_alert("bridge vdevId in MLO dev ctx is not Invalid"
1193*5113495bSYour Name 				 "chip_id: %u, pdev_id: %u,"
1194*5113495bSYour Name 				 "existing vdev_id: %u, new vdev_id : %u",
1195*5113495bSYour Name 				 be_soc->mlo_chip_id, pdev_id,
1196*5113495bSYour Name 				 mlo_dev_ctxt->bridge_vdev[be_soc->mlo_chip_id][pdev_id],
1197*5113495bSYour Name 				 vdev->vdev_id);
1198*5113495bSYour Name 
1199*5113495bSYour Name 		mlo_dev_ctxt->bridge_vdev[be_soc->mlo_chip_id][pdev_id] =
1200*5113495bSYour Name 								vdev->vdev_id;
1201*5113495bSYour Name 		mlo_dev_ctxt->is_bridge_vdev_present = 1;
1202*5113495bSYour Name 	} else {
1203*5113495bSYour Name 		if (mlo_dev_ctxt->vdev_list[be_soc->mlo_chip_id][pdev_id]
1204*5113495bSYour Name 		    != CDP_INVALID_VDEV_ID)
1205*5113495bSYour Name 			dp_alert("vdevId in MLO dev ctx is not Invalid"
1206*5113495bSYour Name 				 "chip_id: %u, pdev_id: %u,"
1207*5113495bSYour Name 				 "existing vdev_id: %u, new vdev_id : %u",
1208*5113495bSYour Name 				 be_soc->mlo_chip_id, pdev_id,
1209*5113495bSYour Name 				 mlo_dev_ctxt->vdev_list[be_soc->mlo_chip_id][pdev_id],
1210*5113495bSYour Name 				 vdev->vdev_id);
1211*5113495bSYour Name 
1212*5113495bSYour Name 		mlo_dev_ctxt->vdev_list[be_soc->mlo_chip_id][pdev_id] =
1213*5113495bSYour Name 								vdev->vdev_id;
1214*5113495bSYour Name 	}
1215*5113495bSYour Name 	mlo_dev_ctxt->vdev_count++;
1216*5113495bSYour Name 	qdf_spin_unlock_bh(&mlo_dev_ctxt->vdev_list_lock);
1217*5113495bSYour Name }
1218*5113495bSYour Name 
1219*5113495bSYour Name static inline QDF_STATUS
dp_detach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be * be_soc,struct dp_vdev * vdev,struct dp_mlo_dev_ctxt * mlo_dev_ctxt)1220*5113495bSYour Name dp_detach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be *be_soc,
1221*5113495bSYour Name 				    struct dp_vdev *vdev,
1222*5113495bSYour Name 				    struct dp_mlo_dev_ctxt *mlo_dev_ctxt)
1223*5113495bSYour Name {
1224*5113495bSYour Name 	uint8_t pdev_id = vdev->pdev->pdev_id;
1225*5113495bSYour Name 
1226*5113495bSYour Name 	if (mlo_dev_ctxt->vdev_list[be_soc->mlo_chip_id][pdev_id] ==
1227*5113495bSYour Name 	    CDP_INVALID_VDEV_ID) {
1228*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1229*5113495bSYour Name 	}
1230*5113495bSYour Name 
1231*5113495bSYour Name 	qdf_spin_lock_bh(&mlo_dev_ctxt->vdev_list_lock);
1232*5113495bSYour Name 	if (vdev->is_bridge_vdev) {
1233*5113495bSYour Name 		mlo_dev_ctxt->bridge_vdev[be_soc->mlo_chip_id][pdev_id] =
1234*5113495bSYour Name 							CDP_INVALID_VDEV_ID;
1235*5113495bSYour Name 	} else {
1236*5113495bSYour Name 		mlo_dev_ctxt->vdev_list[be_soc->mlo_chip_id][pdev_id] =
1237*5113495bSYour Name 							CDP_INVALID_VDEV_ID;
1238*5113495bSYour Name 	}
1239*5113495bSYour Name 	mlo_dev_ctxt->vdev_count--;
1240*5113495bSYour Name 	qdf_spin_unlock_bh(&mlo_dev_ctxt->vdev_list_lock);
1241*5113495bSYour Name 
1242*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1243*5113495bSYour Name }
1244*5113495bSYour Name #endif /* WLAN_DP_MLO_DEV_CTX */
1245*5113495bSYour Name #else
1246*5113495bSYour Name static inline void
dp_mlo_mcast_init(struct dp_soc * soc,struct dp_vdev * vdev)1247*5113495bSYour Name dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
1248*5113495bSYour Name {
1249*5113495bSYour Name }
1250*5113495bSYour Name 
1251*5113495bSYour Name static inline void
dp_mlo_mcast_deinit(struct dp_soc * soc,struct dp_vdev * vdev)1252*5113495bSYour Name dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
1253*5113495bSYour Name {
1254*5113495bSYour Name }
1255*5113495bSYour Name 
dp_get_rx_hash_key_be(struct dp_soc * soc,struct cdp_lro_hash_config * lro_hash)1256*5113495bSYour Name static void dp_get_rx_hash_key_be(struct dp_soc *soc,
1257*5113495bSYour Name 				  struct cdp_lro_hash_config *lro_hash)
1258*5113495bSYour Name {
1259*5113495bSYour Name 	dp_get_rx_hash_key_bytes(lro_hash);
1260*5113495bSYour Name }
1261*5113495bSYour Name 
1262*5113495bSYour Name #ifdef WLAN_DP_MLO_DEV_CTX
1263*5113495bSYour Name static inline void
dp_attach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be * be_soc,struct dp_vdev * vdev,struct dp_mlo_dev_ctxt * mlo_dev_ctxt)1264*5113495bSYour Name dp_attach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be *be_soc,
1265*5113495bSYour Name 				    struct dp_vdev *vdev,
1266*5113495bSYour Name 				    struct dp_mlo_dev_ctxt *mlo_dev_ctxt)
1267*5113495bSYour Name {
1268*5113495bSYour Name }
1269*5113495bSYour Name 
1270*5113495bSYour Name static inline QDF_STATUS
dp_detach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be * be_soc,struct dp_vdev * vdev,struct dp_mlo_dev_ctxt * mlo_dev_ctxt)1271*5113495bSYour Name dp_detach_vdev_list_in_mlo_dev_ctxt(struct dp_soc_be *be_soc,
1272*5113495bSYour Name 				    struct dp_vdev *vdev,
1273*5113495bSYour Name 				    struct dp_mlo_dev_ctxt *mlo_dev_ctxt)
1274*5113495bSYour Name {
1275*5113495bSYour Name }
1276*5113495bSYour Name #endif /* WLAN_DP_MLO_DEV_CTX */
1277*5113495bSYour Name #endif
1278*5113495bSYour Name 
dp_soc_attach_be(struct dp_soc * soc,struct cdp_soc_attach_params * params)1279*5113495bSYour Name static QDF_STATUS dp_soc_attach_be(struct dp_soc *soc,
1280*5113495bSYour Name 				   struct cdp_soc_attach_params *params)
1281*5113495bSYour Name {
1282*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1283*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1284*5113495bSYour Name 	uint32_t max_tx_rx_desc_num, num_spt_pages;
1285*5113495bSYour Name 	uint32_t num_entries;
1286*5113495bSYour Name 	int i = 0;
1287*5113495bSYour Name 	dp_mlo_dev_obj_t mlo_dev_obj;
1288*5113495bSYour Name 
1289*5113495bSYour Name 	mlo_dev_obj = dp_get_mlo_dev_list_obj(be_soc);
1290*5113495bSYour Name 	max_tx_rx_desc_num = WLAN_CFG_NUM_TX_DESC_MAX * MAX_TXDESC_POOLS +
1291*5113495bSYour Name 		WLAN_CFG_RX_SW_DESC_NUM_SIZE_MAX * MAX_RXDESC_POOLS +
1292*5113495bSYour Name 		WLAN_CFG_NUM_PPEDS_TX_DESC_MAX * MAX_PPE_TXDESC_POOLS;
1293*5113495bSYour Name 	/* estimate how many SPT DDR pages needed */
1294*5113495bSYour Name 	num_spt_pages = max_tx_rx_desc_num / DP_CC_SPT_PAGE_MAX_ENTRIES;
1295*5113495bSYour Name 	num_spt_pages = num_spt_pages <= DP_CC_PPT_MAX_ENTRIES ?
1296*5113495bSYour Name 					num_spt_pages : DP_CC_PPT_MAX_ENTRIES;
1297*5113495bSYour Name 
1298*5113495bSYour Name 	be_soc->page_desc_base = qdf_mem_malloc(
1299*5113495bSYour Name 		DP_CC_PPT_MAX_ENTRIES * sizeof(struct dp_spt_page_desc));
1300*5113495bSYour Name 	if (!be_soc->page_desc_base) {
1301*5113495bSYour Name 		dp_err("spt page descs allocation failed");
1302*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1303*5113495bSYour Name 	}
1304*5113495bSYour Name 
1305*5113495bSYour Name 	soc->wbm_sw0_bm_id = hal_tx_get_wbm_sw0_bm_id();
1306*5113495bSYour Name 
1307*5113495bSYour Name 	qdf_status = dp_get_cmem_allocation(soc, COOKIE_CONVERSION);
1308*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1309*5113495bSYour Name 		goto fail;
1310*5113495bSYour Name 
1311*5113495bSYour Name 	dp_soc_mlo_fill_params(soc, params);
1312*5113495bSYour Name 
1313*5113495bSYour Name 	/* Initialize common cdp mlo ops */
1314*5113495bSYour Name 	dp_soc_initialize_cdp_cmn_mlo_ops(soc);
1315*5113495bSYour Name 
1316*5113495bSYour Name 	/* Initialize MLO device ctxt list */
1317*5113495bSYour Name 	dp_mlo_dev_ctxt_list_attach_wrapper(mlo_dev_obj);
1318*5113495bSYour Name 
1319*5113495bSYour Name 	qdf_status = dp_soc_ppeds_attach_be(soc);
1320*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1321*5113495bSYour Name 		goto fail;
1322*5113495bSYour Name 
1323*5113495bSYour Name 	qdf_status = dp_soc_tx_cookie_attach_be(soc);
1324*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1325*5113495bSYour Name 		goto fail;
1326*5113495bSYour Name 
1327*5113495bSYour Name 	for (i = 0; i < MAX_RXDESC_POOLS; i++) {
1328*5113495bSYour Name 		num_entries =
1329*5113495bSYour Name 			wlan_cfg_get_dp_soc_rx_sw_desc_num(soc->wlan_cfg_ctx);
1330*5113495bSYour Name 		qdf_status =
1331*5113495bSYour Name 			dp_hw_cookie_conversion_attach(be_soc,
1332*5113495bSYour Name 						       &be_soc->rx_cc_ctx[i],
1333*5113495bSYour Name 						       num_entries,
1334*5113495bSYour Name 						       QDF_DP_RX_DESC_BUF_TYPE,
1335*5113495bSYour Name 						       i);
1336*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1337*5113495bSYour Name 			goto fail;
1338*5113495bSYour Name 	}
1339*5113495bSYour Name 
1340*5113495bSYour Name 	return qdf_status;
1341*5113495bSYour Name fail:
1342*5113495bSYour Name 	dp_soc_detach_be(soc);
1343*5113495bSYour Name 	return qdf_status;
1344*5113495bSYour Name }
1345*5113495bSYour Name 
dp_soc_deinit_be(struct dp_soc * soc)1346*5113495bSYour Name static QDF_STATUS dp_soc_deinit_be(struct dp_soc *soc)
1347*5113495bSYour Name {
1348*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1349*5113495bSYour Name 	int i = 0;
1350*5113495bSYour Name 
1351*5113495bSYour Name 	qdf_atomic_set(&soc->cmn_init_done, 0);
1352*5113495bSYour Name 
1353*5113495bSYour Name 	dp_ppeds_stop_soc_be(soc);
1354*5113495bSYour Name 
1355*5113495bSYour Name 	dp_tx_deinit_bank_profiles(be_soc);
1356*5113495bSYour Name 	dp_soc_tx_cookie_deinit_be(soc);
1357*5113495bSYour Name 
1358*5113495bSYour Name 	for (i = 0; i < MAX_RXDESC_POOLS; i++)
1359*5113495bSYour Name 		dp_hw_cookie_conversion_deinit(be_soc,
1360*5113495bSYour Name 					       &be_soc->rx_cc_ctx[i]);
1361*5113495bSYour Name 
1362*5113495bSYour Name 	dp_ppeds_deinit_soc_be(soc);
1363*5113495bSYour Name 
1364*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1365*5113495bSYour Name }
1366*5113495bSYour Name 
dp_soc_deinit_be_wrapper(struct dp_soc * soc)1367*5113495bSYour Name static QDF_STATUS dp_soc_deinit_be_wrapper(struct dp_soc *soc)
1368*5113495bSYour Name {
1369*5113495bSYour Name 	QDF_STATUS qdf_status;
1370*5113495bSYour Name 
1371*5113495bSYour Name 	qdf_status = dp_soc_deinit_be(soc);
1372*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status))
1373*5113495bSYour Name 		return qdf_status;
1374*5113495bSYour Name 
1375*5113495bSYour Name 	dp_soc_deinit(soc);
1376*5113495bSYour Name 
1377*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1378*5113495bSYour Name }
1379*5113495bSYour Name 
dp_soc_init_be(struct dp_soc * soc,HTC_HANDLE htc_handle,struct hif_opaque_softc * hif_handle)1380*5113495bSYour Name static void *dp_soc_init_be(struct dp_soc *soc, HTC_HANDLE htc_handle,
1381*5113495bSYour Name 			    struct hif_opaque_softc *hif_handle)
1382*5113495bSYour Name {
1383*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1384*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1385*5113495bSYour Name 	int i = 0;
1386*5113495bSYour Name 	void *ret_addr;
1387*5113495bSYour Name 
1388*5113495bSYour Name 	wlan_minidump_log(soc, sizeof(*soc), soc->ctrl_psoc,
1389*5113495bSYour Name 			  WLAN_MD_DP_SOC, "dp_soc");
1390*5113495bSYour Name 
1391*5113495bSYour Name 	soc->hif_handle = hif_handle;
1392*5113495bSYour Name 
1393*5113495bSYour Name 	soc->hal_soc = hif_get_hal_handle(soc->hif_handle);
1394*5113495bSYour Name 	if (!soc->hal_soc)
1395*5113495bSYour Name 		return NULL;
1396*5113495bSYour Name 
1397*5113495bSYour Name 	dp_ppeds_init_soc_be(soc);
1398*5113495bSYour Name 
1399*5113495bSYour Name 	qdf_status = dp_soc_tx_cookie_init_be(soc);
1400*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1401*5113495bSYour Name 		goto fail;
1402*5113495bSYour Name 
1403*5113495bSYour Name 	for (i = 0; i < MAX_RXDESC_POOLS; i++) {
1404*5113495bSYour Name 		qdf_status =
1405*5113495bSYour Name 			dp_hw_cookie_conversion_init(be_soc,
1406*5113495bSYour Name 						     &be_soc->rx_cc_ctx[i]);
1407*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1408*5113495bSYour Name 			goto fail;
1409*5113495bSYour Name 	}
1410*5113495bSYour Name 
1411*5113495bSYour Name 	/* route vdev_id mismatch notification via FW completion */
1412*5113495bSYour Name 	hal_tx_vdev_mismatch_routing_set(soc->hal_soc,
1413*5113495bSYour Name 					 HAL_TX_VDEV_MISMATCH_FW_NOTIFY);
1414*5113495bSYour Name 
1415*5113495bSYour Name 	qdf_status = dp_tx_init_bank_profiles(be_soc);
1416*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1417*5113495bSYour Name 		goto fail;
1418*5113495bSYour Name 
1419*5113495bSYour Name 	/* write WBM/REO cookie conversion CFG register */
1420*5113495bSYour Name 	dp_cc_reg_cfg_init(soc, true);
1421*5113495bSYour Name 
1422*5113495bSYour Name 	ret_addr = dp_soc_init(soc, htc_handle, hif_handle);
1423*5113495bSYour Name 	if (!ret_addr)
1424*5113495bSYour Name 		goto fail;
1425*5113495bSYour Name 
1426*5113495bSYour Name 	return ret_addr;
1427*5113495bSYour Name fail:
1428*5113495bSYour Name 	dp_soc_deinit_be(soc);
1429*5113495bSYour Name 	return NULL;
1430*5113495bSYour Name }
1431*5113495bSYour Name 
dp_pdev_attach_be(struct dp_pdev * pdev,struct cdp_pdev_attach_params * params)1432*5113495bSYour Name static QDF_STATUS dp_pdev_attach_be(struct dp_pdev *pdev,
1433*5113495bSYour Name 				    struct cdp_pdev_attach_params *params)
1434*5113495bSYour Name {
1435*5113495bSYour Name 	dp_pdev_mlo_fill_params(pdev, params);
1436*5113495bSYour Name 
1437*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1438*5113495bSYour Name }
1439*5113495bSYour Name 
dp_pdev_detach_be(struct dp_pdev * pdev)1440*5113495bSYour Name static QDF_STATUS dp_pdev_detach_be(struct dp_pdev *pdev)
1441*5113495bSYour Name {
1442*5113495bSYour Name 	dp_mlo_update_link_to_pdev_unmap(pdev->soc, pdev);
1443*5113495bSYour Name 
1444*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1445*5113495bSYour Name }
1446*5113495bSYour Name 
1447*5113495bSYour Name #ifdef INTRA_BSS_FWD_OFFLOAD
1448*5113495bSYour Name static
dp_vdev_set_intra_bss(struct dp_soc * soc,uint16_t vdev_id,bool enable)1449*5113495bSYour Name void dp_vdev_set_intra_bss(struct dp_soc *soc, uint16_t vdev_id, bool enable)
1450*5113495bSYour Name {
1451*5113495bSYour Name 	soc->cdp_soc.ol_ops->vdev_set_intra_bss(soc->ctrl_psoc, vdev_id,
1452*5113495bSYour Name 						enable);
1453*5113495bSYour Name }
1454*5113495bSYour Name #else
1455*5113495bSYour Name static
dp_vdev_set_intra_bss(struct dp_soc * soc,uint16_t vdev_id,bool enable)1456*5113495bSYour Name void dp_vdev_set_intra_bss(struct dp_soc *soc, uint16_t vdev_id, bool enable)
1457*5113495bSYour Name {
1458*5113495bSYour Name }
1459*5113495bSYour Name #endif
1460*5113495bSYour Name 
dp_vdev_attach_be(struct dp_soc * soc,struct dp_vdev * vdev)1461*5113495bSYour Name static QDF_STATUS dp_vdev_attach_be(struct dp_soc *soc, struct dp_vdev *vdev)
1462*5113495bSYour Name {
1463*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1464*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
1465*5113495bSYour Name 	struct dp_pdev *pdev = vdev->pdev;
1466*5113495bSYour Name 
1467*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_monitor)
1468*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1469*5113495bSYour Name 
1470*5113495bSYour Name 	be_vdev->vdev_id_check_en = DP_TX_VDEV_ID_CHECK_ENABLE;
1471*5113495bSYour Name 
1472*5113495bSYour Name 	be_vdev->bank_id = dp_tx_get_bank_profile(be_soc, be_vdev);
1473*5113495bSYour Name 	vdev->bank_id = be_vdev->bank_id;
1474*5113495bSYour Name 
1475*5113495bSYour Name 	if (be_vdev->bank_id == DP_BE_INVALID_BANK_ID) {
1476*5113495bSYour Name 		QDF_BUG(0);
1477*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1478*5113495bSYour Name 	}
1479*5113495bSYour Name 
1480*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_sta) {
1481*5113495bSYour Name 		if (soc->cdp_soc.ol_ops->set_mec_timer)
1482*5113495bSYour Name 			soc->cdp_soc.ol_ops->set_mec_timer(
1483*5113495bSYour Name 					soc->ctrl_psoc,
1484*5113495bSYour Name 					vdev->vdev_id,
1485*5113495bSYour Name 					DP_AST_AGING_TIMER_DEFAULT_MS);
1486*5113495bSYour Name 
1487*5113495bSYour Name 		if (pdev->isolation)
1488*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(soc->hal_soc, vdev->vdev_id,
1489*5113495bSYour Name 						   HAL_TX_MCAST_CTRL_FW_EXCEPTION);
1490*5113495bSYour Name 		else
1491*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(soc->hal_soc, vdev->vdev_id,
1492*5113495bSYour Name 						   HAL_TX_MCAST_CTRL_MEC_NOTIFY);
1493*5113495bSYour Name 	} else if (vdev->ap_bridge_enabled) {
1494*5113495bSYour Name 		dp_vdev_set_intra_bss(soc, vdev->vdev_id, true);
1495*5113495bSYour Name 	}
1496*5113495bSYour Name 
1497*5113495bSYour Name 	dp_mlo_mcast_init(soc, vdev);
1498*5113495bSYour Name 
1499*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1500*5113495bSYour Name }
1501*5113495bSYour Name 
dp_vdev_detach_be(struct dp_soc * soc,struct dp_vdev * vdev)1502*5113495bSYour Name static QDF_STATUS dp_vdev_detach_be(struct dp_soc *soc, struct dp_vdev *vdev)
1503*5113495bSYour Name {
1504*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1505*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
1506*5113495bSYour Name 
1507*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_monitor)
1508*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1509*5113495bSYour Name 
1510*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_ap)
1511*5113495bSYour Name 		dp_mlo_mcast_deinit(soc, vdev);
1512*5113495bSYour Name 
1513*5113495bSYour Name 	dp_tx_put_bank_profile(be_soc, be_vdev);
1514*5113495bSYour Name 
1515*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1516*5113495bSYour Name }
1517*5113495bSYour Name 
1518*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
dp_soc_txrx_peer_setup_be(struct dp_soc * soc,uint8_t vdev_id,uint8_t * peer_mac)1519*5113495bSYour Name static void dp_soc_txrx_peer_setup_be(struct dp_soc *soc, uint8_t vdev_id,
1520*5113495bSYour Name 				      uint8_t *peer_mac)
1521*5113495bSYour Name {
1522*5113495bSYour Name 	struct dp_vdev_be *be_vdev;
1523*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1524*5113495bSYour Name 	struct dp_soc_be *be_soc;
1525*5113495bSYour Name 	struct cdp_ds_vp_params vp_params = {0};
1526*5113495bSYour Name 	struct cdp_soc_t *cdp_soc;
1527*5113495bSYour Name 	enum wlan_op_mode vdev_opmode;
1528*5113495bSYour Name 	struct dp_peer *peer;
1529*5113495bSYour Name 	struct dp_peer *tgt_peer = NULL;
1530*5113495bSYour Name 	struct dp_soc *tgt_soc = NULL;
1531*5113495bSYour Name 
1532*5113495bSYour Name 	peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id, DP_MOD_ID_CDP);
1533*5113495bSYour Name 	if (!peer)
1534*5113495bSYour Name 		return;
1535*5113495bSYour Name 	vdev_opmode = peer->vdev->opmode;
1536*5113495bSYour Name 
1537*5113495bSYour Name 	if (vdev_opmode != wlan_op_mode_ap &&
1538*5113495bSYour Name 	    vdev_opmode != wlan_op_mode_sta) {
1539*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
1540*5113495bSYour Name 		return;
1541*5113495bSYour Name 	}
1542*5113495bSYour Name 
1543*5113495bSYour Name 	tgt_peer = dp_get_tgt_peer_from_peer(peer);
1544*5113495bSYour Name 	tgt_soc = tgt_peer->vdev->pdev->soc;
1545*5113495bSYour Name 	be_soc = dp_get_be_soc_from_dp_soc(tgt_soc);
1546*5113495bSYour Name 	cdp_soc = &tgt_soc->cdp_soc;
1547*5113495bSYour Name 
1548*5113495bSYour Name 	be_vdev = dp_get_be_vdev_from_dp_vdev(tgt_peer->vdev);
1549*5113495bSYour Name 	if (!be_vdev) {
1550*5113495bSYour Name 		qdf_err("BE vap is null");
1551*5113495bSYour Name 		qdf_status = QDF_STATUS_E_NULL_VALUE;
1552*5113495bSYour Name 		goto fail;
1553*5113495bSYour Name 	}
1554*5113495bSYour Name 
1555*5113495bSYour Name 	/*
1556*5113495bSYour Name 	 * Extract the VP profile from the VAP
1557*5113495bSYour Name 	 */
1558*5113495bSYour Name 	if (!cdp_soc->ol_ops->get_ppeds_profile_info_for_vap) {
1559*5113495bSYour Name 		dp_err("%pK: Register get ppeds profile info first", cdp_soc);
1560*5113495bSYour Name 		qdf_status = QDF_STATUS_E_NULL_VALUE;
1561*5113495bSYour Name 		goto fail;
1562*5113495bSYour Name 	}
1563*5113495bSYour Name 
1564*5113495bSYour Name 	/*
1565*5113495bSYour Name 	 * Check if PPE DS routing is enabled on the associated vap.
1566*5113495bSYour Name 	 */
1567*5113495bSYour Name 	qdf_status =
1568*5113495bSYour Name 	cdp_soc->ol_ops->get_ppeds_profile_info_for_vap(tgt_soc->ctrl_psoc,
1569*5113495bSYour Name 							tgt_peer->vdev->vdev_id,
1570*5113495bSYour Name 							&vp_params);
1571*5113495bSYour Name 	if (qdf_status == QDF_STATUS_E_NULL_VALUE) {
1572*5113495bSYour Name 		dp_err("%pK: Could not find ppeds profile info vdev", be_vdev);
1573*5113495bSYour Name 		qdf_status = QDF_STATUS_E_NULL_VALUE;
1574*5113495bSYour Name 		goto fail;
1575*5113495bSYour Name 	}
1576*5113495bSYour Name 
1577*5113495bSYour Name 	if (vp_params.ppe_vp_type == PPE_VP_USER_TYPE_DS) {
1578*5113495bSYour Name 		qdf_status = dp_peer_setup_ppeds_be(tgt_soc, tgt_peer, be_vdev,
1579*5113495bSYour Name 						    (void *)&be_soc->ppe_vp_profile[vp_params.ppe_vp_profile_idx]);
1580*5113495bSYour Name 	}
1581*5113495bSYour Name 
1582*5113495bSYour Name fail:
1583*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
1584*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1585*5113495bSYour Name 		dp_err("Unable to do ppeds peer setup");
1586*5113495bSYour Name 		qdf_assert_always(0);
1587*5113495bSYour Name 	}
1588*5113495bSYour Name }
1589*5113495bSYour Name 
1590*5113495bSYour Name static inline
dp_tx_update_vp_profile(struct dp_soc_be * soc,struct dp_vdev_be * vdev)1591*5113495bSYour Name void dp_tx_update_vp_profile(struct dp_soc_be *soc,
1592*5113495bSYour Name 			     struct dp_vdev_be *vdev)
1593*5113495bSYour Name {
1594*5113495bSYour Name 	dp_tx_ppeds_vp_profile_update(soc, vdev);
1595*5113495bSYour Name }
1596*5113495bSYour Name #else
1597*5113495bSYour Name static inline
dp_soc_txrx_peer_setup_be(struct dp_soc * soc,uint8_t vdev_id,uint8_t * peer_mac)1598*5113495bSYour Name void dp_soc_txrx_peer_setup_be(struct dp_soc *soc, uint8_t vdev_id,
1599*5113495bSYour Name 			       uint8_t *peer_mac)
1600*5113495bSYour Name {
1601*5113495bSYour Name }
1602*5113495bSYour Name 
1603*5113495bSYour Name static inline
dp_tx_update_vp_profile(struct dp_soc_be * soc,struct dp_vdev_be * vdev)1604*5113495bSYour Name void dp_tx_update_vp_profile(struct dp_soc_be *soc,
1605*5113495bSYour Name 			     struct dp_vdev_be *vdev)
1606*5113495bSYour Name {
1607*5113495bSYour Name }
1608*5113495bSYour Name #endif
1609*5113495bSYour Name 
dp_peer_setup_be(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,struct cdp_peer_setup_info * setup_info)1610*5113495bSYour Name static QDF_STATUS dp_peer_setup_be(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
1611*5113495bSYour Name 				   uint8_t *peer_mac,
1612*5113495bSYour Name 				   struct cdp_peer_setup_info *setup_info)
1613*5113495bSYour Name {
1614*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
1615*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1616*5113495bSYour Name 
1617*5113495bSYour Name 	qdf_status = dp_peer_setup_wifi3(soc_hdl, vdev_id, peer_mac,
1618*5113495bSYour Name 					 setup_info);
1619*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1620*5113495bSYour Name 		dp_err("Unable to dp peer setup");
1621*5113495bSYour Name 		return qdf_status;
1622*5113495bSYour Name 	}
1623*5113495bSYour Name 
1624*5113495bSYour Name 	dp_soc_txrx_peer_setup_be(soc, vdev_id, peer_mac);
1625*5113495bSYour Name 
1626*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1627*5113495bSYour Name }
1628*5113495bSYour Name 
dp_get_soc_context_size_be(void)1629*5113495bSYour Name qdf_size_t dp_get_soc_context_size_be(void)
1630*5113495bSYour Name {
1631*5113495bSYour Name 	return sizeof(struct dp_soc_be);
1632*5113495bSYour Name }
1633*5113495bSYour Name 
1634*5113495bSYour Name #ifdef CONFIG_WORD_BASED_TLV
1635*5113495bSYour Name /**
1636*5113495bSYour Name  * dp_rxdma_ring_wmask_cfg_be() - Setup RXDMA ring word mask config
1637*5113495bSYour Name  * @soc: Common DP soc handle
1638*5113495bSYour Name  * @htt_tlv_filter: Rx SRNG TLV and filter setting
1639*5113495bSYour Name  *
1640*5113495bSYour Name  * Return: none
1641*5113495bSYour Name  */
1642*5113495bSYour Name static inline void
dp_rxdma_ring_wmask_cfg_be(struct dp_soc * soc,struct htt_rx_ring_tlv_filter * htt_tlv_filter)1643*5113495bSYour Name dp_rxdma_ring_wmask_cfg_be(struct dp_soc *soc,
1644*5113495bSYour Name 			   struct htt_rx_ring_tlv_filter *htt_tlv_filter)
1645*5113495bSYour Name {
1646*5113495bSYour Name 	htt_tlv_filter->rx_msdu_end_wmask =
1647*5113495bSYour Name 				 hal_rx_msdu_end_wmask_get(soc->hal_soc);
1648*5113495bSYour Name 	htt_tlv_filter->rx_mpdu_start_wmask =
1649*5113495bSYour Name 				 hal_rx_mpdu_start_wmask_get(soc->hal_soc);
1650*5113495bSYour Name }
1651*5113495bSYour Name #else
1652*5113495bSYour Name static inline void
dp_rxdma_ring_wmask_cfg_be(struct dp_soc * soc,struct htt_rx_ring_tlv_filter * htt_tlv_filter)1653*5113495bSYour Name dp_rxdma_ring_wmask_cfg_be(struct dp_soc *soc,
1654*5113495bSYour Name 			   struct htt_rx_ring_tlv_filter *htt_tlv_filter)
1655*5113495bSYour Name {
1656*5113495bSYour Name }
1657*5113495bSYour Name #endif
1658*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
1659*5113495bSYour Name static
dp_free_ppeds_interrupts(struct dp_soc * soc,struct dp_srng * srng,int ring_type,int ring_num)1660*5113495bSYour Name void dp_free_ppeds_interrupts(struct dp_soc *soc, struct dp_srng *srng,
1661*5113495bSYour Name 			      int ring_type, int ring_num)
1662*5113495bSYour Name {
1663*5113495bSYour Name 	if (srng->irq >= 0) {
1664*5113495bSYour Name 		qdf_dev_clear_irq_status_flags(srng->irq, IRQ_DISABLE_UNLAZY);
1665*5113495bSYour Name 		if (ring_type == WBM2SW_RELEASE &&
1666*5113495bSYour Name 		    ring_num == WBM2_SW_PPE_REL_RING_ID)
1667*5113495bSYour Name 			pld_pfrm_free_irq(soc->osdev->dev, srng->irq, soc);
1668*5113495bSYour Name 		else if (ring_type == REO2PPE || ring_type == PPE2TCL)
1669*5113495bSYour Name 			pld_pfrm_free_irq(soc->osdev->dev, srng->irq,
1670*5113495bSYour Name 					  dp_get_ppe_ds_ctxt(soc));
1671*5113495bSYour Name 	}
1672*5113495bSYour Name }
1673*5113495bSYour Name 
1674*5113495bSYour Name static
dp_register_ppeds_interrupts(struct dp_soc * soc,struct dp_srng * srng,int vector,int ring_type,int ring_num)1675*5113495bSYour Name int dp_register_ppeds_interrupts(struct dp_soc *soc, struct dp_srng *srng,
1676*5113495bSYour Name 				 int vector, int ring_type, int ring_num)
1677*5113495bSYour Name {
1678*5113495bSYour Name 	int irq = -1, ret = 0;
1679*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
1680*5113495bSYour Name 	int pci_slot = pld_get_pci_slot(soc->osdev->dev);
1681*5113495bSYour Name 
1682*5113495bSYour Name 	srng->irq = -1;
1683*5113495bSYour Name 	irq = pld_get_msi_irq(soc->osdev->dev, vector);
1684*5113495bSYour Name 	qdf_dev_set_irq_status_flags(irq, IRQ_DISABLE_UNLAZY);
1685*5113495bSYour Name 
1686*5113495bSYour Name 	if (ring_type == WBM2SW_RELEASE &&
1687*5113495bSYour Name 	    ring_num == WBM2_SW_PPE_REL_RING_ID) {
1688*5113495bSYour Name 		snprintf(be_soc->irq_name[2], DP_PPE_INTR_STRNG_LEN,
1689*5113495bSYour Name 			 "pci%d_ppe_wbm_rel", pci_slot);
1690*5113495bSYour Name 
1691*5113495bSYour Name 		ret = pld_pfrm_request_irq(soc->osdev->dev, irq,
1692*5113495bSYour Name 					   dp_ppeds_handle_tx_comp,
1693*5113495bSYour Name 					   IRQF_SHARED | IRQF_NO_SUSPEND,
1694*5113495bSYour Name 					   be_soc->irq_name[2], (void *)soc);
1695*5113495bSYour Name 
1696*5113495bSYour Name 		if (ret)
1697*5113495bSYour Name 			goto fail;
1698*5113495bSYour Name 	} else if (ring_type == REO2PPE && be_soc->ppeds_int_mode_enabled) {
1699*5113495bSYour Name 		snprintf(be_soc->irq_name[0], DP_PPE_INTR_STRNG_LEN,
1700*5113495bSYour Name 			 "pci%d_reo2ppe", pci_slot);
1701*5113495bSYour Name 		ret = pld_pfrm_request_irq(soc->osdev->dev, irq,
1702*5113495bSYour Name 					   dp_ppe_ds_reo2ppe_irq_handler,
1703*5113495bSYour Name 					   IRQF_SHARED | IRQF_NO_SUSPEND,
1704*5113495bSYour Name 					   be_soc->irq_name[0],
1705*5113495bSYour Name 					   dp_get_ppe_ds_ctxt(soc));
1706*5113495bSYour Name 
1707*5113495bSYour Name 		if (ret)
1708*5113495bSYour Name 			goto fail;
1709*5113495bSYour Name 	} else if (ring_type == PPE2TCL && be_soc->ppeds_int_mode_enabled) {
1710*5113495bSYour Name 		snprintf(be_soc->irq_name[1], DP_PPE_INTR_STRNG_LEN,
1711*5113495bSYour Name 			 "pci%d_ppe2tcl", pci_slot);
1712*5113495bSYour Name 		ret = pld_pfrm_request_irq(soc->osdev->dev, irq,
1713*5113495bSYour Name 					   dp_ppe_ds_ppe2tcl_irq_handler,
1714*5113495bSYour Name 					   IRQF_NO_SUSPEND,
1715*5113495bSYour Name 					   be_soc->irq_name[1],
1716*5113495bSYour Name 					   dp_get_ppe_ds_ctxt(soc));
1717*5113495bSYour Name 		if (ret)
1718*5113495bSYour Name 			goto fail;
1719*5113495bSYour Name 
1720*5113495bSYour Name 		pld_pfrm_disable_irq_nosync(soc->osdev->dev, irq);
1721*5113495bSYour Name 	} else {
1722*5113495bSYour Name 		return 0;
1723*5113495bSYour Name 	}
1724*5113495bSYour Name 
1725*5113495bSYour Name 	srng->irq = irq;
1726*5113495bSYour Name 
1727*5113495bSYour Name 	dp_info("Registered irq %d for soc %pK ring type %d",
1728*5113495bSYour Name 		irq, soc, ring_type);
1729*5113495bSYour Name 
1730*5113495bSYour Name 	return 0;
1731*5113495bSYour Name fail:
1732*5113495bSYour Name 	dp_err("Unable to config irq : ring type %d irq %d vector %d",
1733*5113495bSYour Name 	       ring_type, irq, vector);
1734*5113495bSYour Name 	qdf_dev_clear_irq_status_flags(irq, IRQ_DISABLE_UNLAZY);
1735*5113495bSYour Name 
1736*5113495bSYour Name 	return ret;
1737*5113495bSYour Name }
1738*5113495bSYour Name 
dp_ppeds_disable_irq(struct dp_soc * soc,struct dp_srng * srng)1739*5113495bSYour Name void dp_ppeds_disable_irq(struct dp_soc *soc, struct dp_srng *srng)
1740*5113495bSYour Name {
1741*5113495bSYour Name 	if (srng->irq >= 0)
1742*5113495bSYour Name 		pld_pfrm_disable_irq_nosync(soc->osdev->dev, srng->irq);
1743*5113495bSYour Name }
1744*5113495bSYour Name 
dp_ppeds_enable_irq(struct dp_soc * soc,struct dp_srng * srng)1745*5113495bSYour Name void dp_ppeds_enable_irq(struct dp_soc *soc, struct dp_srng *srng)
1746*5113495bSYour Name {
1747*5113495bSYour Name 	if (srng->irq >= 0)
1748*5113495bSYour Name 		pld_pfrm_enable_irq(soc->osdev->dev, srng->irq);
1749*5113495bSYour Name }
1750*5113495bSYour Name #endif
1751*5113495bSYour Name 
1752*5113495bSYour Name #ifdef NO_RX_PKT_HDR_TLV
1753*5113495bSYour Name /**
1754*5113495bSYour Name  * dp_rxdma_ring_sel_cfg_be() - Setup RXDMA ring config
1755*5113495bSYour Name  * @soc: Common DP soc handle
1756*5113495bSYour Name  *
1757*5113495bSYour Name  * Return: QDF_STATUS
1758*5113495bSYour Name  */
1759*5113495bSYour Name static QDF_STATUS
dp_rxdma_ring_sel_cfg_be(struct dp_soc * soc)1760*5113495bSYour Name dp_rxdma_ring_sel_cfg_be(struct dp_soc *soc)
1761*5113495bSYour Name {
1762*5113495bSYour Name 	int i;
1763*5113495bSYour Name 	int mac_id;
1764*5113495bSYour Name 	struct htt_rx_ring_tlv_filter htt_tlv_filter = {0};
1765*5113495bSYour Name 	struct dp_srng *rx_mac_srng;
1766*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1767*5113495bSYour Name 	uint16_t buf_size;
1768*5113495bSYour Name 
1769*5113495bSYour Name 	buf_size = wlan_cfg_rx_buffer_size(soc->wlan_cfg_ctx);
1770*5113495bSYour Name 
1771*5113495bSYour Name 	/*
1772*5113495bSYour Name 	 * In Beryllium chipset msdu_start, mpdu_end
1773*5113495bSYour Name 	 * and rx_attn are part of msdu_end/mpdu_start
1774*5113495bSYour Name 	 */
1775*5113495bSYour Name 	htt_tlv_filter.msdu_start = 0;
1776*5113495bSYour Name 	htt_tlv_filter.mpdu_end = 0;
1777*5113495bSYour Name 	htt_tlv_filter.attention = 0;
1778*5113495bSYour Name 	htt_tlv_filter.mpdu_start = 1;
1779*5113495bSYour Name 	htt_tlv_filter.msdu_end = 1;
1780*5113495bSYour Name 	htt_tlv_filter.packet = 1;
1781*5113495bSYour Name 	htt_tlv_filter.packet_header = 0;
1782*5113495bSYour Name 
1783*5113495bSYour Name 	htt_tlv_filter.ppdu_start = 0;
1784*5113495bSYour Name 	htt_tlv_filter.ppdu_end = 0;
1785*5113495bSYour Name 	htt_tlv_filter.ppdu_end_user_stats = 0;
1786*5113495bSYour Name 	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
1787*5113495bSYour Name 	htt_tlv_filter.ppdu_end_status_done = 0;
1788*5113495bSYour Name 	htt_tlv_filter.enable_fp = 1;
1789*5113495bSYour Name 	htt_tlv_filter.enable_md = 0;
1790*5113495bSYour Name 	htt_tlv_filter.enable_md = 0;
1791*5113495bSYour Name 	htt_tlv_filter.enable_mo = 0;
1792*5113495bSYour Name 
1793*5113495bSYour Name 	htt_tlv_filter.fp_mgmt_filter = 0;
1794*5113495bSYour Name 	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ;
1795*5113495bSYour Name 	htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST |
1796*5113495bSYour Name 					 FILTER_DATA_DATA);
1797*5113495bSYour Name 	htt_tlv_filter.fp_data_filter |=
1798*5113495bSYour Name 		hal_rx_en_mcast_fp_data_filter(soc->hal_soc) ?
1799*5113495bSYour Name 					FILTER_DATA_MCAST : 0;
1800*5113495bSYour Name 	htt_tlv_filter.mo_mgmt_filter = 0;
1801*5113495bSYour Name 	htt_tlv_filter.mo_ctrl_filter = 0;
1802*5113495bSYour Name 	htt_tlv_filter.mo_data_filter = 0;
1803*5113495bSYour Name 	htt_tlv_filter.md_data_filter = 0;
1804*5113495bSYour Name 
1805*5113495bSYour Name 	htt_tlv_filter.offset_valid = true;
1806*5113495bSYour Name 
1807*5113495bSYour Name 	/* Not subscribing to mpdu_end, msdu_start and rx_attn */
1808*5113495bSYour Name 	htt_tlv_filter.rx_mpdu_end_offset = 0;
1809*5113495bSYour Name 	htt_tlv_filter.rx_msdu_start_offset = 0;
1810*5113495bSYour Name 	htt_tlv_filter.rx_attn_offset = 0;
1811*5113495bSYour Name 
1812*5113495bSYour Name 	/*
1813*5113495bSYour Name 	 * For monitor mode, the packet hdr tlv is enabled later during
1814*5113495bSYour Name 	 * filter update
1815*5113495bSYour Name 	 */
1816*5113495bSYour Name 	if (soc->cdp_soc.ol_ops->get_con_mode &&
1817*5113495bSYour Name 	    soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE)
1818*5113495bSYour Name 		htt_tlv_filter.rx_packet_offset = soc->rx_mon_pkt_tlv_size;
1819*5113495bSYour Name 	else
1820*5113495bSYour Name 		htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size;
1821*5113495bSYour Name 
1822*5113495bSYour Name 	/*Not subscribing rx_pkt_header*/
1823*5113495bSYour Name 	htt_tlv_filter.rx_header_offset = 0;
1824*5113495bSYour Name 	htt_tlv_filter.rx_mpdu_start_offset =
1825*5113495bSYour Name 				hal_rx_mpdu_start_offset_get(soc->hal_soc);
1826*5113495bSYour Name 	htt_tlv_filter.rx_msdu_end_offset =
1827*5113495bSYour Name 				hal_rx_msdu_end_offset_get(soc->hal_soc);
1828*5113495bSYour Name 
1829*5113495bSYour Name 	dp_rxdma_ring_wmask_cfg_be(soc, &htt_tlv_filter);
1830*5113495bSYour Name 
1831*5113495bSYour Name 	for (i = 0; i < MAX_PDEV_CNT; i++) {
1832*5113495bSYour Name 		struct dp_pdev *pdev = soc->pdev_list[i];
1833*5113495bSYour Name 
1834*5113495bSYour Name 		if (!pdev)
1835*5113495bSYour Name 			continue;
1836*5113495bSYour Name 
1837*5113495bSYour Name 		for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
1838*5113495bSYour Name 			int mac_for_pdev =
1839*5113495bSYour Name 				dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
1840*5113495bSYour Name 			/*
1841*5113495bSYour Name 			 * Obtain lmac id from pdev to access the LMAC ring
1842*5113495bSYour Name 			 * in soc context
1843*5113495bSYour Name 			 */
1844*5113495bSYour Name 			int lmac_id =
1845*5113495bSYour Name 				dp_get_lmac_id_for_pdev_id(soc, mac_id,
1846*5113495bSYour Name 							   pdev->pdev_id);
1847*5113495bSYour Name 
1848*5113495bSYour Name 			rx_mac_srng = dp_get_rxdma_ring(pdev, lmac_id);
1849*5113495bSYour Name 
1850*5113495bSYour Name 			if (!rx_mac_srng->hal_srng)
1851*5113495bSYour Name 				continue;
1852*5113495bSYour Name 
1853*5113495bSYour Name 			htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
1854*5113495bSYour Name 					    rx_mac_srng->hal_srng,
1855*5113495bSYour Name 					    RXDMA_BUF, buf_size,
1856*5113495bSYour Name 					    &htt_tlv_filter);
1857*5113495bSYour Name 		}
1858*5113495bSYour Name 	}
1859*5113495bSYour Name 	return status;
1860*5113495bSYour Name }
1861*5113495bSYour Name #else
1862*5113495bSYour Name /**
1863*5113495bSYour Name  * dp_rxdma_ring_sel_cfg_be() - Setup RXDMA ring config
1864*5113495bSYour Name  * @soc: Common DP soc handle
1865*5113495bSYour Name  *
1866*5113495bSYour Name  * Return: QDF_STATUS
1867*5113495bSYour Name  */
1868*5113495bSYour Name static QDF_STATUS
dp_rxdma_ring_sel_cfg_be(struct dp_soc * soc)1869*5113495bSYour Name dp_rxdma_ring_sel_cfg_be(struct dp_soc *soc)
1870*5113495bSYour Name {
1871*5113495bSYour Name 	int i;
1872*5113495bSYour Name 	int mac_id;
1873*5113495bSYour Name 	struct htt_rx_ring_tlv_filter htt_tlv_filter = {0};
1874*5113495bSYour Name 	struct dp_srng *rx_mac_srng;
1875*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1876*5113495bSYour Name 	uint16_t buf_size;
1877*5113495bSYour Name 
1878*5113495bSYour Name 	buf_size = wlan_cfg_rx_buffer_size(soc->wlan_cfg_ctx);
1879*5113495bSYour Name 
1880*5113495bSYour Name 	/*
1881*5113495bSYour Name 	 * In Beryllium chipset msdu_start, mpdu_end
1882*5113495bSYour Name 	 * and rx_attn are part of msdu_end/mpdu_start
1883*5113495bSYour Name 	 */
1884*5113495bSYour Name 	htt_tlv_filter.msdu_start = 0;
1885*5113495bSYour Name 	htt_tlv_filter.mpdu_end = 0;
1886*5113495bSYour Name 	htt_tlv_filter.attention = 0;
1887*5113495bSYour Name 	htt_tlv_filter.mpdu_start = 1;
1888*5113495bSYour Name 	htt_tlv_filter.msdu_end = 1;
1889*5113495bSYour Name 	htt_tlv_filter.packet = 1;
1890*5113495bSYour Name 	htt_tlv_filter.packet_header = 1;
1891*5113495bSYour Name 
1892*5113495bSYour Name 	htt_tlv_filter.ppdu_start = 0;
1893*5113495bSYour Name 	htt_tlv_filter.ppdu_end = 0;
1894*5113495bSYour Name 	htt_tlv_filter.ppdu_end_user_stats = 0;
1895*5113495bSYour Name 	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
1896*5113495bSYour Name 	htt_tlv_filter.ppdu_end_status_done = 0;
1897*5113495bSYour Name 	htt_tlv_filter.enable_fp = 1;
1898*5113495bSYour Name 	htt_tlv_filter.enable_md = 0;
1899*5113495bSYour Name 	htt_tlv_filter.enable_md = 0;
1900*5113495bSYour Name 	htt_tlv_filter.enable_mo = 0;
1901*5113495bSYour Name 
1902*5113495bSYour Name 	htt_tlv_filter.fp_mgmt_filter = 0;
1903*5113495bSYour Name 	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_BA_REQ;
1904*5113495bSYour Name 	htt_tlv_filter.fp_data_filter = (FILTER_DATA_UCAST |
1905*5113495bSYour Name 					 FILTER_DATA_DATA);
1906*5113495bSYour Name 	htt_tlv_filter.fp_data_filter |=
1907*5113495bSYour Name 		hal_rx_en_mcast_fp_data_filter(soc->hal_soc) ?
1908*5113495bSYour Name 					FILTER_DATA_MCAST : 0;
1909*5113495bSYour Name 	htt_tlv_filter.mo_mgmt_filter = 0;
1910*5113495bSYour Name 	htt_tlv_filter.mo_ctrl_filter = 0;
1911*5113495bSYour Name 	htt_tlv_filter.mo_data_filter = 0;
1912*5113495bSYour Name 	htt_tlv_filter.md_data_filter = 0;
1913*5113495bSYour Name 
1914*5113495bSYour Name 	htt_tlv_filter.offset_valid = true;
1915*5113495bSYour Name 
1916*5113495bSYour Name 	/* Not subscribing to mpdu_end, msdu_start and rx_attn */
1917*5113495bSYour Name 	htt_tlv_filter.rx_mpdu_end_offset = 0;
1918*5113495bSYour Name 	htt_tlv_filter.rx_msdu_start_offset = 0;
1919*5113495bSYour Name 	htt_tlv_filter.rx_attn_offset = 0;
1920*5113495bSYour Name 
1921*5113495bSYour Name 	/*
1922*5113495bSYour Name 	 * For monitor mode, the packet hdr tlv is enabled later during
1923*5113495bSYour Name 	 * filter update
1924*5113495bSYour Name 	 */
1925*5113495bSYour Name 	if (soc->cdp_soc.ol_ops->get_con_mode &&
1926*5113495bSYour Name 	    soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE)
1927*5113495bSYour Name 		htt_tlv_filter.rx_packet_offset = soc->rx_mon_pkt_tlv_size;
1928*5113495bSYour Name 	else
1929*5113495bSYour Name 		htt_tlv_filter.rx_packet_offset = soc->rx_pkt_tlv_size;
1930*5113495bSYour Name 
1931*5113495bSYour Name 	htt_tlv_filter.rx_header_offset =
1932*5113495bSYour Name 				hal_rx_pkt_tlv_offset_get(soc->hal_soc);
1933*5113495bSYour Name 	htt_tlv_filter.rx_mpdu_start_offset =
1934*5113495bSYour Name 				hal_rx_mpdu_start_offset_get(soc->hal_soc);
1935*5113495bSYour Name 	htt_tlv_filter.rx_msdu_end_offset =
1936*5113495bSYour Name 				hal_rx_msdu_end_offset_get(soc->hal_soc);
1937*5113495bSYour Name 
1938*5113495bSYour Name 	dp_info("TLV subscription\n"
1939*5113495bSYour Name 		"msdu_start %d, mpdu_end %d, attention %d"
1940*5113495bSYour Name 		"mpdu_start %d, msdu_end %d, pkt_hdr %d, pkt %d\n"
1941*5113495bSYour Name 		"TLV offsets\n"
1942*5113495bSYour Name 		"msdu_start %d, mpdu_end %d, attention %d"
1943*5113495bSYour Name 		"mpdu_start %d, msdu_end %d, pkt_hdr %d, pkt %d\n",
1944*5113495bSYour Name 		htt_tlv_filter.msdu_start,
1945*5113495bSYour Name 		htt_tlv_filter.mpdu_end,
1946*5113495bSYour Name 		htt_tlv_filter.attention,
1947*5113495bSYour Name 		htt_tlv_filter.mpdu_start,
1948*5113495bSYour Name 		htt_tlv_filter.msdu_end,
1949*5113495bSYour Name 		htt_tlv_filter.packet_header,
1950*5113495bSYour Name 		htt_tlv_filter.packet,
1951*5113495bSYour Name 		htt_tlv_filter.rx_msdu_start_offset,
1952*5113495bSYour Name 		htt_tlv_filter.rx_mpdu_end_offset,
1953*5113495bSYour Name 		htt_tlv_filter.rx_attn_offset,
1954*5113495bSYour Name 		htt_tlv_filter.rx_mpdu_start_offset,
1955*5113495bSYour Name 		htt_tlv_filter.rx_msdu_end_offset,
1956*5113495bSYour Name 		htt_tlv_filter.rx_header_offset,
1957*5113495bSYour Name 		htt_tlv_filter.rx_packet_offset);
1958*5113495bSYour Name 
1959*5113495bSYour Name 	dp_rxdma_ring_wmask_cfg_be(soc, &htt_tlv_filter);
1960*5113495bSYour Name 	for (i = 0; i < MAX_PDEV_CNT; i++) {
1961*5113495bSYour Name 		struct dp_pdev *pdev = soc->pdev_list[i];
1962*5113495bSYour Name 
1963*5113495bSYour Name 		if (!pdev)
1964*5113495bSYour Name 			continue;
1965*5113495bSYour Name 
1966*5113495bSYour Name 		for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
1967*5113495bSYour Name 			int mac_for_pdev =
1968*5113495bSYour Name 				dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
1969*5113495bSYour Name 			/*
1970*5113495bSYour Name 			 * Obtain lmac id from pdev to access the LMAC ring
1971*5113495bSYour Name 			 * in soc context
1972*5113495bSYour Name 			 */
1973*5113495bSYour Name 			int lmac_id =
1974*5113495bSYour Name 				dp_get_lmac_id_for_pdev_id(soc, mac_id,
1975*5113495bSYour Name 							   pdev->pdev_id);
1976*5113495bSYour Name 
1977*5113495bSYour Name 			rx_mac_srng = dp_get_rxdma_ring(pdev, lmac_id);
1978*5113495bSYour Name 
1979*5113495bSYour Name 			if (!rx_mac_srng->hal_srng)
1980*5113495bSYour Name 				continue;
1981*5113495bSYour Name 
1982*5113495bSYour Name 			htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
1983*5113495bSYour Name 					    rx_mac_srng->hal_srng,
1984*5113495bSYour Name 					    RXDMA_BUF, buf_size,
1985*5113495bSYour Name 					    &htt_tlv_filter);
1986*5113495bSYour Name 		}
1987*5113495bSYour Name 	}
1988*5113495bSYour Name 	return status;
1989*5113495bSYour Name 
1990*5113495bSYour Name }
1991*5113495bSYour Name #endif
1992*5113495bSYour Name 
1993*5113495bSYour Name #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
1994*5113495bSYour Name /**
1995*5113495bSYour Name  * dp_service_near_full_srngs_be() - Main bottom half callback for the
1996*5113495bSYour Name  *				near-full IRQs.
1997*5113495bSYour Name  * @soc: Datapath SoC handle
1998*5113495bSYour Name  * @int_ctx: Interrupt context
1999*5113495bSYour Name  * @dp_budget: Budget of the work that can be done in the bottom half
2000*5113495bSYour Name  *
2001*5113495bSYour Name  * Return: work done in the handler
2002*5113495bSYour Name  */
2003*5113495bSYour Name static uint32_t
dp_service_near_full_srngs_be(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t dp_budget)2004*5113495bSYour Name dp_service_near_full_srngs_be(struct dp_soc *soc, struct dp_intr *int_ctx,
2005*5113495bSYour Name 			      uint32_t dp_budget)
2006*5113495bSYour Name {
2007*5113495bSYour Name 	int ring = 0;
2008*5113495bSYour Name 	int budget = dp_budget;
2009*5113495bSYour Name 	uint32_t work_done  = 0;
2010*5113495bSYour Name 	uint32_t remaining_quota = dp_budget;
2011*5113495bSYour Name 	struct dp_intr_stats *intr_stats = &int_ctx->intr_stats;
2012*5113495bSYour Name 	int tx_ring_near_full_mask = int_ctx->tx_ring_near_full_mask;
2013*5113495bSYour Name 	int rx_near_full_grp_1_mask = int_ctx->rx_near_full_grp_1_mask;
2014*5113495bSYour Name 	int rx_near_full_grp_2_mask = int_ctx->rx_near_full_grp_2_mask;
2015*5113495bSYour Name 	int rx_near_full_mask = rx_near_full_grp_1_mask |
2016*5113495bSYour Name 				rx_near_full_grp_2_mask;
2017*5113495bSYour Name 
2018*5113495bSYour Name 	dp_verbose_debug("rx_ring_near_full 0x%x tx_ring_near_full 0x%x",
2019*5113495bSYour Name 			 rx_near_full_mask,
2020*5113495bSYour Name 			 tx_ring_near_full_mask);
2021*5113495bSYour Name 
2022*5113495bSYour Name 	if (rx_near_full_mask) {
2023*5113495bSYour Name 		for (ring = 0; ring < soc->num_reo_dest_rings; ring++) {
2024*5113495bSYour Name 			if (!(rx_near_full_mask & (1 << ring)))
2025*5113495bSYour Name 				continue;
2026*5113495bSYour Name 
2027*5113495bSYour Name 			work_done = dp_rx_nf_process(int_ctx,
2028*5113495bSYour Name 					soc->reo_dest_ring[ring].hal_srng,
2029*5113495bSYour Name 					ring, remaining_quota);
2030*5113495bSYour Name 			if (work_done) {
2031*5113495bSYour Name 				intr_stats->num_rx_ring_near_full_masks[ring]++;
2032*5113495bSYour Name 				dp_verbose_debug("rx NF mask 0x%x ring %d, work_done %d budget %d",
2033*5113495bSYour Name 						 rx_near_full_mask, ring,
2034*5113495bSYour Name 						 work_done,
2035*5113495bSYour Name 						 budget);
2036*5113495bSYour Name 				budget -=  work_done;
2037*5113495bSYour Name 				if (budget <= 0)
2038*5113495bSYour Name 					goto budget_done;
2039*5113495bSYour Name 				remaining_quota = budget;
2040*5113495bSYour Name 			}
2041*5113495bSYour Name 		}
2042*5113495bSYour Name 	}
2043*5113495bSYour Name 
2044*5113495bSYour Name 	if (tx_ring_near_full_mask) {
2045*5113495bSYour Name 		for (ring = 0; ring < soc->num_tcl_data_rings; ring++) {
2046*5113495bSYour Name 			if (!(tx_ring_near_full_mask & (1 << ring)))
2047*5113495bSYour Name 				continue;
2048*5113495bSYour Name 
2049*5113495bSYour Name 			work_done = dp_tx_comp_nf_handler(int_ctx, soc,
2050*5113495bSYour Name 					soc->tx_comp_ring[ring].hal_srng,
2051*5113495bSYour Name 					ring, remaining_quota);
2052*5113495bSYour Name 			if (work_done) {
2053*5113495bSYour Name 				intr_stats->num_tx_comp_ring_near_full_masks[ring]++;
2054*5113495bSYour Name 				dp_verbose_debug("tx NF mask 0x%x ring %d, work_done %d budget %d",
2055*5113495bSYour Name 						 tx_ring_near_full_mask, ring,
2056*5113495bSYour Name 						 work_done, budget);
2057*5113495bSYour Name 				budget -=  work_done;
2058*5113495bSYour Name 				if (budget <= 0)
2059*5113495bSYour Name 					break;
2060*5113495bSYour Name 				remaining_quota = budget;
2061*5113495bSYour Name 			}
2062*5113495bSYour Name 		}
2063*5113495bSYour Name 	}
2064*5113495bSYour Name 
2065*5113495bSYour Name 	intr_stats->num_near_full_masks++;
2066*5113495bSYour Name 
2067*5113495bSYour Name budget_done:
2068*5113495bSYour Name 	return dp_budget - budget;
2069*5113495bSYour Name }
2070*5113495bSYour Name 
2071*5113495bSYour Name /**
2072*5113495bSYour Name  * dp_srng_test_and_update_nf_params_be() - Check if the srng is in near full
2073*5113495bSYour Name  *				state and set the reap_limit appropriately
2074*5113495bSYour Name  *				as per the near full state
2075*5113495bSYour Name  * @soc: Datapath soc handle
2076*5113495bSYour Name  * @dp_srng: Datapath handle for SRNG
2077*5113495bSYour Name  * @max_reap_limit: [Output Buffer] Buffer to set the max reap limit as per
2078*5113495bSYour Name  *			the srng near-full state
2079*5113495bSYour Name  *
2080*5113495bSYour Name  * Return: 1, if the srng is in near-full state
2081*5113495bSYour Name  *	   0, if the srng is not in near-full state
2082*5113495bSYour Name  */
2083*5113495bSYour Name static int
dp_srng_test_and_update_nf_params_be(struct dp_soc * soc,struct dp_srng * dp_srng,int * max_reap_limit)2084*5113495bSYour Name dp_srng_test_and_update_nf_params_be(struct dp_soc *soc,
2085*5113495bSYour Name 				     struct dp_srng *dp_srng,
2086*5113495bSYour Name 				     int *max_reap_limit)
2087*5113495bSYour Name {
2088*5113495bSYour Name 	return _dp_srng_test_and_update_nf_params(soc, dp_srng, max_reap_limit);
2089*5113495bSYour Name }
2090*5113495bSYour Name 
2091*5113495bSYour Name /**
2092*5113495bSYour Name  * dp_init_near_full_arch_ops_be() - Initialize the arch ops handler for the
2093*5113495bSYour Name  *			near full IRQ handling operations.
2094*5113495bSYour Name  * @arch_ops: arch ops handle
2095*5113495bSYour Name  *
2096*5113495bSYour Name  * Return: none
2097*5113495bSYour Name  */
2098*5113495bSYour Name static inline void
dp_init_near_full_arch_ops_be(struct dp_arch_ops * arch_ops)2099*5113495bSYour Name dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
2100*5113495bSYour Name {
2101*5113495bSYour Name 	arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be;
2102*5113495bSYour Name 	arch_ops->dp_srng_test_and_update_nf_params =
2103*5113495bSYour Name 					dp_srng_test_and_update_nf_params_be;
2104*5113495bSYour Name }
2105*5113495bSYour Name 
2106*5113495bSYour Name #else
2107*5113495bSYour Name static inline void
dp_init_near_full_arch_ops_be(struct dp_arch_ops * arch_ops)2108*5113495bSYour Name dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
2109*5113495bSYour Name {
2110*5113495bSYour Name }
2111*5113495bSYour Name #endif
2112*5113495bSYour Name 
2113*5113495bSYour Name static inline
dp_srng_init_be(struct dp_soc * soc,struct dp_srng * srng,int ring_type,int ring_num,int mac_id)2114*5113495bSYour Name QDF_STATUS dp_srng_init_be(struct dp_soc *soc, struct dp_srng *srng,
2115*5113495bSYour Name 			   int ring_type, int ring_num, int mac_id)
2116*5113495bSYour Name {
2117*5113495bSYour Name 	return dp_srng_init_idx(soc, srng, ring_type, ring_num, mac_id, 0);
2118*5113495bSYour Name }
2119*5113495bSYour Name 
dp_soc_interrupt_attach_be(struct cdp_soc_t * txrx_soc)2120*5113495bSYour Name static QDF_STATUS dp_soc_interrupt_attach_be(struct cdp_soc_t *txrx_soc)
2121*5113495bSYour Name {
2122*5113495bSYour Name 	return dp_soc_interrupt_attach(txrx_soc);
2123*5113495bSYour Name }
2124*5113495bSYour Name 
dp_soc_attach_poll_be(struct cdp_soc_t * txrx_soc)2125*5113495bSYour Name static QDF_STATUS dp_soc_attach_poll_be(struct cdp_soc_t *txrx_soc)
2126*5113495bSYour Name {
2127*5113495bSYour Name 	return dp_soc_attach_poll(txrx_soc);
2128*5113495bSYour Name }
2129*5113495bSYour Name 
dp_soc_interrupt_detach_be(struct cdp_soc_t * txrx_soc)2130*5113495bSYour Name static void dp_soc_interrupt_detach_be(struct cdp_soc_t *txrx_soc)
2131*5113495bSYour Name {
2132*5113495bSYour Name 	return dp_soc_interrupt_detach(txrx_soc);
2133*5113495bSYour Name }
2134*5113495bSYour Name 
dp_service_srngs_be(void * dp_ctx,uint32_t dp_budget,int cpu)2135*5113495bSYour Name static uint32_t dp_service_srngs_be(void *dp_ctx, uint32_t dp_budget, int cpu)
2136*5113495bSYour Name {
2137*5113495bSYour Name 	return dp_service_srngs(dp_ctx, dp_budget, cpu);
2138*5113495bSYour Name }
2139*5113495bSYour Name 
2140*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
dp_soc_ppeds_srng_deinit(struct dp_soc * soc)2141*5113495bSYour Name static void dp_soc_ppeds_srng_deinit(struct dp_soc *soc)
2142*5113495bSYour Name {
2143*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2144*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2145*5113495bSYour Name 
2146*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2147*5113495bSYour Name 
2148*5113495bSYour Name 	if (!be_soc->ppeds_handle)
2149*5113495bSYour Name 		return;
2150*5113495bSYour Name 
2151*5113495bSYour Name 	dp_srng_deinit(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0);
2152*5113495bSYour Name 	wlan_minidump_remove(be_soc->ppe2tcl_ring.base_vaddr_unaligned,
2153*5113495bSYour Name 			     be_soc->ppe2tcl_ring.alloc_size,
2154*5113495bSYour Name 			     soc->ctrl_psoc,
2155*5113495bSYour Name 			     WLAN_MD_DP_SRNG_PPE2TCL,
2156*5113495bSYour Name 			     "ppe2tcl_ring");
2157*5113495bSYour Name 
2158*5113495bSYour Name 	dp_srng_deinit(soc, &be_soc->reo2ppe_ring, REO2PPE, 0);
2159*5113495bSYour Name 	wlan_minidump_remove(be_soc->reo2ppe_ring.base_vaddr_unaligned,
2160*5113495bSYour Name 			     be_soc->reo2ppe_ring.alloc_size,
2161*5113495bSYour Name 			     soc->ctrl_psoc,
2162*5113495bSYour Name 			     WLAN_MD_DP_SRNG_REO2PPE,
2163*5113495bSYour Name 			     "reo2ppe_ring");
2164*5113495bSYour Name 
2165*5113495bSYour Name 	dp_srng_deinit(soc, &be_soc->ppeds_wbm_release_ring, WBM2SW_RELEASE,
2166*5113495bSYour Name 		       WBM2_SW_PPE_REL_RING_ID);
2167*5113495bSYour Name 	wlan_minidump_remove(be_soc->ppeds_wbm_release_ring.base_vaddr_unaligned,
2168*5113495bSYour Name 			     be_soc->ppeds_wbm_release_ring.alloc_size,
2169*5113495bSYour Name 			     soc->ctrl_psoc,
2170*5113495bSYour Name 			     WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE,
2171*5113495bSYour Name 			     "ppeds_wbm_release_ring");
2172*5113495bSYour Name 
2173*5113495bSYour Name }
2174*5113495bSYour Name 
dp_soc_ppeds_srng_free(struct dp_soc * soc)2175*5113495bSYour Name static void dp_soc_ppeds_srng_free(struct dp_soc *soc)
2176*5113495bSYour Name {
2177*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2178*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2179*5113495bSYour Name 
2180*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2181*5113495bSYour Name 
2182*5113495bSYour Name 	dp_srng_free(soc, &be_soc->ppeds_wbm_release_ring);
2183*5113495bSYour Name 
2184*5113495bSYour Name 	dp_srng_free(soc, &be_soc->ppe2tcl_ring);
2185*5113495bSYour Name 
2186*5113495bSYour Name 	dp_srng_free(soc, &be_soc->reo2ppe_ring);
2187*5113495bSYour Name }
2188*5113495bSYour Name 
dp_soc_ppeds_srng_alloc(struct dp_soc * soc)2189*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_srng_alloc(struct dp_soc *soc)
2190*5113495bSYour Name {
2191*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2192*5113495bSYour Name 	uint32_t entries;
2193*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2194*5113495bSYour Name 
2195*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2196*5113495bSYour Name 
2197*5113495bSYour Name 	if (!be_soc->ppeds_handle)
2198*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2199*5113495bSYour Name 
2200*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_reo2ppe_ring_size(soc_cfg_ctx);
2201*5113495bSYour Name 
2202*5113495bSYour Name 	if (dp_srng_alloc(soc, &be_soc->reo2ppe_ring, REO2PPE,
2203*5113495bSYour Name 			  entries, 0)) {
2204*5113495bSYour Name 		dp_err("%pK: dp_srng_alloc failed for reo2ppe", soc);
2205*5113495bSYour Name 		goto fail;
2206*5113495bSYour Name 	}
2207*5113495bSYour Name 
2208*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_ppe2tcl_ring_size(soc_cfg_ctx);
2209*5113495bSYour Name 	if (dp_srng_alloc(soc, &be_soc->ppe2tcl_ring, PPE2TCL,
2210*5113495bSYour Name 			  entries, 0)) {
2211*5113495bSYour Name 		dp_err("%pK: dp_srng_alloc failed for ppe2tcl_ring", soc);
2212*5113495bSYour Name 		goto fail;
2213*5113495bSYour Name 	}
2214*5113495bSYour Name 
2215*5113495bSYour Name 	entries = wlan_cfg_tx_comp_ring_size(soc_cfg_ctx);
2216*5113495bSYour Name 	if (dp_srng_alloc(soc, &be_soc->ppeds_wbm_release_ring, WBM2SW_RELEASE,
2217*5113495bSYour Name 			  entries, 1)) {
2218*5113495bSYour Name 		dp_err("%pK: dp_srng_alloc failed for ppeds_wbm_release_ring",
2219*5113495bSYour Name 		       soc);
2220*5113495bSYour Name 		goto fail;
2221*5113495bSYour Name 	}
2222*5113495bSYour Name 
2223*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2224*5113495bSYour Name fail:
2225*5113495bSYour Name 	dp_soc_ppeds_srng_free(soc);
2226*5113495bSYour Name 	return QDF_STATUS_E_NOMEM;
2227*5113495bSYour Name }
2228*5113495bSYour Name 
dp_soc_ppeds_srng_init(struct dp_soc * soc)2229*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_srng_init(struct dp_soc *soc)
2230*5113495bSYour Name {
2231*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2232*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2233*5113495bSYour Name 	hal_soc_handle_t hal_soc = soc->hal_soc;
2234*5113495bSYour Name 
2235*5113495bSYour Name 	struct dp_ppe_ds_idxs idx = {0};
2236*5113495bSYour Name 
2237*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2238*5113495bSYour Name 
2239*5113495bSYour Name 	if (!be_soc->ppeds_handle)
2240*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2241*5113495bSYour Name 
2242*5113495bSYour Name 	if (dp_ppeds_register_soc_be(be_soc, &idx)) {
2243*5113495bSYour Name 		dp_err("%pK: ppeds registration failed", soc);
2244*5113495bSYour Name 		goto fail;
2245*5113495bSYour Name 	}
2246*5113495bSYour Name 
2247*5113495bSYour Name 	if (dp_srng_init_idx(soc, &be_soc->reo2ppe_ring, REO2PPE, 0, 0,
2248*5113495bSYour Name 			     idx.reo2ppe_start_idx)) {
2249*5113495bSYour Name 		dp_err("%pK: dp_srng_init failed for reo2ppe", soc);
2250*5113495bSYour Name 		goto fail;
2251*5113495bSYour Name 	}
2252*5113495bSYour Name 
2253*5113495bSYour Name 	wlan_minidump_log(be_soc->reo2ppe_ring.base_vaddr_unaligned,
2254*5113495bSYour Name 			  be_soc->reo2ppe_ring.alloc_size,
2255*5113495bSYour Name 			  soc->ctrl_psoc,
2256*5113495bSYour Name 			  WLAN_MD_DP_SRNG_REO2PPE,
2257*5113495bSYour Name 			  "reo2ppe_ring");
2258*5113495bSYour Name 
2259*5113495bSYour Name 	hal_reo_config_reo2ppe_dest_info(hal_soc);
2260*5113495bSYour Name 
2261*5113495bSYour Name 	if (dp_srng_init_idx(soc, &be_soc->ppe2tcl_ring, PPE2TCL, 0, 0,
2262*5113495bSYour Name 			     idx.ppe2tcl_start_idx)) {
2263*5113495bSYour Name 		dp_err("%pK: dp_srng_init failed for ppe2tcl_ring", soc);
2264*5113495bSYour Name 		goto fail;
2265*5113495bSYour Name 	}
2266*5113495bSYour Name 
2267*5113495bSYour Name 	wlan_minidump_log(be_soc->ppe2tcl_ring.base_vaddr_unaligned,
2268*5113495bSYour Name 			  be_soc->ppe2tcl_ring.alloc_size,
2269*5113495bSYour Name 			  soc->ctrl_psoc,
2270*5113495bSYour Name 			  WLAN_MD_DP_SRNG_PPE2TCL,
2271*5113495bSYour Name 			  "ppe2tcl_ring");
2272*5113495bSYour Name 
2273*5113495bSYour Name 	hal_tx_config_rbm_mapping_be(soc->hal_soc,
2274*5113495bSYour Name 				     be_soc->ppe2tcl_ring.hal_srng,
2275*5113495bSYour Name 				     WBM2_SW_PPE_REL_MAP_ID);
2276*5113495bSYour Name 
2277*5113495bSYour Name 	if (dp_srng_init(soc, &be_soc->ppeds_wbm_release_ring, WBM2SW_RELEASE,
2278*5113495bSYour Name 			 WBM2_SW_PPE_REL_RING_ID, 0)) {
2279*5113495bSYour Name 		dp_err("%pK: dp_srng_init failed for ppeds_wbm_release_ring",
2280*5113495bSYour Name 		       soc);
2281*5113495bSYour Name 		goto fail;
2282*5113495bSYour Name 	}
2283*5113495bSYour Name 
2284*5113495bSYour Name 	wlan_minidump_log(be_soc->ppeds_wbm_release_ring.base_vaddr_unaligned,
2285*5113495bSYour Name 			  be_soc->ppeds_wbm_release_ring.alloc_size,
2286*5113495bSYour Name 			  soc->ctrl_psoc, WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE,
2287*5113495bSYour Name 			  "ppeds_wbm_release_ring");
2288*5113495bSYour Name 
2289*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2290*5113495bSYour Name fail:
2291*5113495bSYour Name 	dp_soc_ppeds_srng_deinit(soc);
2292*5113495bSYour Name 	return QDF_STATUS_E_NOMEM;
2293*5113495bSYour Name }
2294*5113495bSYour Name #else
dp_soc_ppeds_srng_deinit(struct dp_soc * soc)2295*5113495bSYour Name static void dp_soc_ppeds_srng_deinit(struct dp_soc *soc)
2296*5113495bSYour Name {
2297*5113495bSYour Name }
2298*5113495bSYour Name 
dp_soc_ppeds_srng_free(struct dp_soc * soc)2299*5113495bSYour Name static void dp_soc_ppeds_srng_free(struct dp_soc *soc)
2300*5113495bSYour Name {
2301*5113495bSYour Name }
2302*5113495bSYour Name 
dp_soc_ppeds_srng_alloc(struct dp_soc * soc)2303*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_srng_alloc(struct dp_soc *soc)
2304*5113495bSYour Name {
2305*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2306*5113495bSYour Name }
2307*5113495bSYour Name 
dp_soc_ppeds_srng_init(struct dp_soc * soc)2308*5113495bSYour Name static QDF_STATUS dp_soc_ppeds_srng_init(struct dp_soc *soc)
2309*5113495bSYour Name {
2310*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2311*5113495bSYour Name }
2312*5113495bSYour Name #endif
2313*5113495bSYour Name 
dp_soc_srng_deinit_be(struct dp_soc * soc)2314*5113495bSYour Name static void dp_soc_srng_deinit_be(struct dp_soc *soc)
2315*5113495bSYour Name {
2316*5113495bSYour Name 	uint32_t i;
2317*5113495bSYour Name 
2318*5113495bSYour Name 	dp_soc_ppeds_srng_deinit(soc);
2319*5113495bSYour Name 
2320*5113495bSYour Name 	if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
2321*5113495bSYour Name 		for (i = 0; i < soc->num_rx_refill_buf_rings; i++) {
2322*5113495bSYour Name 			dp_ssr_dump_srng_unregister("rx_refill_buf_ring", i);
2323*5113495bSYour Name 			dp_srng_deinit(soc, &soc->rx_refill_buf_ring[i],
2324*5113495bSYour Name 				       RXDMA_BUF, 0);
2325*5113495bSYour Name 		}
2326*5113495bSYour Name 	}
2327*5113495bSYour Name }
2328*5113495bSYour Name 
dp_soc_srng_free_be(struct dp_soc * soc)2329*5113495bSYour Name static void dp_soc_srng_free_be(struct dp_soc *soc)
2330*5113495bSYour Name {
2331*5113495bSYour Name 	uint32_t i;
2332*5113495bSYour Name 
2333*5113495bSYour Name 	dp_soc_ppeds_srng_free(soc);
2334*5113495bSYour Name 
2335*5113495bSYour Name 	if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
2336*5113495bSYour Name 		for (i = 0; i < soc->num_rx_refill_buf_rings; i++)
2337*5113495bSYour Name 			dp_srng_free(soc, &soc->rx_refill_buf_ring[i]);
2338*5113495bSYour Name 	}
2339*5113495bSYour Name }
2340*5113495bSYour Name 
dp_soc_srng_alloc_be(struct dp_soc * soc)2341*5113495bSYour Name static QDF_STATUS dp_soc_srng_alloc_be(struct dp_soc *soc)
2342*5113495bSYour Name {
2343*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2344*5113495bSYour Name 	uint32_t ring_size;
2345*5113495bSYour Name 	uint32_t i;
2346*5113495bSYour Name 
2347*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
2348*5113495bSYour Name 
2349*5113495bSYour Name 	ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx);
2350*5113495bSYour Name 	if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
2351*5113495bSYour Name 		for (i = 0; i < soc->num_rx_refill_buf_rings; i++) {
2352*5113495bSYour Name 			if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[i],
2353*5113495bSYour Name 					  RXDMA_BUF, ring_size, 0)) {
2354*5113495bSYour Name 				dp_err("%pK: dp_srng_alloc failed refill ring",
2355*5113495bSYour Name 				       soc);
2356*5113495bSYour Name 				goto fail;
2357*5113495bSYour Name 			}
2358*5113495bSYour Name 		}
2359*5113495bSYour Name 	}
2360*5113495bSYour Name 
2361*5113495bSYour Name 	if (dp_soc_ppeds_srng_alloc(soc)) {
2362*5113495bSYour Name 		dp_err("%pK: ppe rings alloc failed",
2363*5113495bSYour Name 		       soc);
2364*5113495bSYour Name 		goto fail;
2365*5113495bSYour Name 	}
2366*5113495bSYour Name 
2367*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2368*5113495bSYour Name fail:
2369*5113495bSYour Name 	dp_soc_srng_free_be(soc);
2370*5113495bSYour Name 	return QDF_STATUS_E_NOMEM;
2371*5113495bSYour Name }
2372*5113495bSYour Name 
dp_soc_srng_init_be(struct dp_soc * soc)2373*5113495bSYour Name static QDF_STATUS dp_soc_srng_init_be(struct dp_soc *soc)
2374*5113495bSYour Name {
2375*5113495bSYour Name 	int i = 0;
2376*5113495bSYour Name 
2377*5113495bSYour Name 	if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
2378*5113495bSYour Name 		for (i = 0; i < soc->num_rx_refill_buf_rings; i++) {
2379*5113495bSYour Name 			if (dp_srng_init(soc, &soc->rx_refill_buf_ring[i],
2380*5113495bSYour Name 					 RXDMA_BUF, 0, 0)) {
2381*5113495bSYour Name 				dp_err("%pK: dp_srng_init failed refill ring",
2382*5113495bSYour Name 				       soc);
2383*5113495bSYour Name 				goto fail;
2384*5113495bSYour Name 			}
2385*5113495bSYour Name 			dp_ssr_dump_srng_register("rx_refill_buf_ring",
2386*5113495bSYour Name 						  &soc->rx_refill_buf_ring[i],
2387*5113495bSYour Name 						  i);
2388*5113495bSYour Name 		}
2389*5113495bSYour Name 	}
2390*5113495bSYour Name 
2391*5113495bSYour Name 	if (dp_soc_ppeds_srng_init(soc)) {
2392*5113495bSYour Name 		dp_err("%pK: ppe ds rings init failed",
2393*5113495bSYour Name 		       soc);
2394*5113495bSYour Name 		goto fail;
2395*5113495bSYour Name 	}
2396*5113495bSYour Name 
2397*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2398*5113495bSYour Name fail:
2399*5113495bSYour Name 	dp_soc_srng_deinit_be(soc);
2400*5113495bSYour Name 	return QDF_STATUS_E_NOMEM;
2401*5113495bSYour Name }
2402*5113495bSYour Name 
2403*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2404*5113495bSYour Name static inline unsigned
dp_mlo_peer_find_hash_index(dp_mld_peer_hash_obj_t mld_hash_obj,union dp_align_mac_addr * mac_addr)2405*5113495bSYour Name dp_mlo_peer_find_hash_index(dp_mld_peer_hash_obj_t mld_hash_obj,
2406*5113495bSYour Name 			    union dp_align_mac_addr *mac_addr)
2407*5113495bSYour Name {
2408*5113495bSYour Name 	uint32_t index;
2409*5113495bSYour Name 
2410*5113495bSYour Name 	index =
2411*5113495bSYour Name 		mac_addr->align2.bytes_ab ^
2412*5113495bSYour Name 		mac_addr->align2.bytes_cd ^
2413*5113495bSYour Name 		mac_addr->align2.bytes_ef;
2414*5113495bSYour Name 
2415*5113495bSYour Name 	index ^= index >> mld_hash_obj->mld_peer_hash.idx_bits;
2416*5113495bSYour Name 	index &= mld_hash_obj->mld_peer_hash.mask;
2417*5113495bSYour Name 
2418*5113495bSYour Name 	return index;
2419*5113495bSYour Name }
2420*5113495bSYour Name 
2421*5113495bSYour Name QDF_STATUS
dp_mlo_peer_find_hash_attach_be(dp_mld_peer_hash_obj_t mld_hash_obj,int hash_elems)2422*5113495bSYour Name dp_mlo_peer_find_hash_attach_be(dp_mld_peer_hash_obj_t mld_hash_obj,
2423*5113495bSYour Name 				int hash_elems)
2424*5113495bSYour Name {
2425*5113495bSYour Name 	int i, log2;
2426*5113495bSYour Name 
2427*5113495bSYour Name 	if (!mld_hash_obj)
2428*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2429*5113495bSYour Name 
2430*5113495bSYour Name 	hash_elems *= DP_PEER_HASH_LOAD_MULT;
2431*5113495bSYour Name 	hash_elems >>= DP_PEER_HASH_LOAD_SHIFT;
2432*5113495bSYour Name 	log2 = dp_log2_ceil(hash_elems);
2433*5113495bSYour Name 	hash_elems = 1 << log2;
2434*5113495bSYour Name 
2435*5113495bSYour Name 	mld_hash_obj->mld_peer_hash.mask = hash_elems - 1;
2436*5113495bSYour Name 	mld_hash_obj->mld_peer_hash.idx_bits = log2;
2437*5113495bSYour Name 	/* allocate an array of TAILQ peer object lists */
2438*5113495bSYour Name 	mld_hash_obj->mld_peer_hash.bins = qdf_mem_malloc(
2439*5113495bSYour Name 		hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, dp_peer)));
2440*5113495bSYour Name 	if (!mld_hash_obj->mld_peer_hash.bins)
2441*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2442*5113495bSYour Name 
2443*5113495bSYour Name 	for (i = 0; i < hash_elems; i++)
2444*5113495bSYour Name 		TAILQ_INIT(&mld_hash_obj->mld_peer_hash.bins[i]);
2445*5113495bSYour Name 
2446*5113495bSYour Name 	qdf_spinlock_create(&mld_hash_obj->mld_peer_hash_lock);
2447*5113495bSYour Name 
2448*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2449*5113495bSYour Name }
2450*5113495bSYour Name 
2451*5113495bSYour Name void
dp_mlo_peer_find_hash_detach_be(dp_mld_peer_hash_obj_t mld_hash_obj)2452*5113495bSYour Name dp_mlo_peer_find_hash_detach_be(dp_mld_peer_hash_obj_t mld_hash_obj)
2453*5113495bSYour Name {
2454*5113495bSYour Name 	if (!mld_hash_obj)
2455*5113495bSYour Name 		return;
2456*5113495bSYour Name 
2457*5113495bSYour Name 	if (mld_hash_obj->mld_peer_hash.bins) {
2458*5113495bSYour Name 		qdf_mem_free(mld_hash_obj->mld_peer_hash.bins);
2459*5113495bSYour Name 		mld_hash_obj->mld_peer_hash.bins = NULL;
2460*5113495bSYour Name 		qdf_spinlock_destroy(&mld_hash_obj->mld_peer_hash_lock);
2461*5113495bSYour Name 	}
2462*5113495bSYour Name }
2463*5113495bSYour Name 
2464*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc * soc)2465*5113495bSYour Name static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc)
2466*5113495bSYour Name {
2467*5113495bSYour Name 	/* In case of MULTI chip MLO peer hash table when MLO global object
2468*5113495bSYour Name 	 * is created, avoid from SOC attach path
2469*5113495bSYour Name 	 */
2470*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2471*5113495bSYour Name }
2472*5113495bSYour Name 
dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc * soc)2473*5113495bSYour Name static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc)
2474*5113495bSYour Name {
2475*5113495bSYour Name }
2476*5113495bSYour Name 
dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2477*5113495bSYour Name void dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2478*5113495bSYour Name {
2479*5113495bSYour Name }
2480*5113495bSYour Name 
dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2481*5113495bSYour Name void dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2482*5113495bSYour Name {
2483*5113495bSYour Name }
2484*5113495bSYour Name #else
dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc * soc)2485*5113495bSYour Name static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc)
2486*5113495bSYour Name {
2487*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2488*5113495bSYour Name 
2489*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2490*5113495bSYour Name 
2491*5113495bSYour Name 	if (!mld_hash_obj)
2492*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2493*5113495bSYour Name 
2494*5113495bSYour Name 	return dp_mlo_peer_find_hash_attach_be(mld_hash_obj, soc->max_peers);
2495*5113495bSYour Name }
2496*5113495bSYour Name 
dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc * soc)2497*5113495bSYour Name static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc)
2498*5113495bSYour Name {
2499*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2500*5113495bSYour Name 
2501*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2502*5113495bSYour Name 
2503*5113495bSYour Name 	if (!mld_hash_obj)
2504*5113495bSYour Name 		return;
2505*5113495bSYour Name 
2506*5113495bSYour Name 	return dp_mlo_peer_find_hash_detach_be(mld_hash_obj);
2507*5113495bSYour Name }
2508*5113495bSYour Name 
dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2509*5113495bSYour Name void dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2510*5113495bSYour Name {
2511*5113495bSYour Name 	dp_mlo_dev_ctxt_list_attach(mlo_dev_obj);
2512*5113495bSYour Name }
2513*5113495bSYour Name 
dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2514*5113495bSYour Name void dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2515*5113495bSYour Name {
2516*5113495bSYour Name 	dp_mlo_dev_ctxt_list_detach(mlo_dev_obj);
2517*5113495bSYour Name }
2518*5113495bSYour Name #endif
2519*5113495bSYour Name 
2520*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
2521*5113495bSYour Name static uint8_t
dp_get_hw_link_id_be(struct dp_pdev * pdev)2522*5113495bSYour Name dp_get_hw_link_id_be(struct dp_pdev *pdev)
2523*5113495bSYour Name {
2524*5113495bSYour Name 	struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
2525*5113495bSYour Name 
2526*5113495bSYour Name 	return be_pdev->mlo_link_id;
2527*5113495bSYour Name }
2528*5113495bSYour Name #else
2529*5113495bSYour Name static uint8_t
dp_get_hw_link_id_be(struct dp_pdev * pdev)2530*5113495bSYour Name dp_get_hw_link_id_be(struct dp_pdev *pdev)
2531*5113495bSYour Name {
2532*5113495bSYour Name 	return 0;
2533*5113495bSYour Name }
2534*5113495bSYour Name #endif /* QCA_ENHANCED_STATS_SUPPORT */
2535*5113495bSYour Name 
2536*5113495bSYour Name static struct dp_peer *
dp_mlo_peer_find_hash_find_be(struct dp_soc * soc,uint8_t * peer_mac_addr,int mac_addr_is_aligned,enum dp_mod_id mod_id,uint8_t vdev_id)2537*5113495bSYour Name dp_mlo_peer_find_hash_find_be(struct dp_soc *soc,
2538*5113495bSYour Name 			      uint8_t *peer_mac_addr,
2539*5113495bSYour Name 			      int mac_addr_is_aligned,
2540*5113495bSYour Name 			      enum dp_mod_id mod_id,
2541*5113495bSYour Name 			      uint8_t vdev_id)
2542*5113495bSYour Name {
2543*5113495bSYour Name 	union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
2544*5113495bSYour Name 	uint32_t index;
2545*5113495bSYour Name 	struct dp_peer *peer;
2546*5113495bSYour Name 	struct dp_vdev *vdev;
2547*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2548*5113495bSYour Name 
2549*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2550*5113495bSYour Name 	if (!mld_hash_obj)
2551*5113495bSYour Name 		return NULL;
2552*5113495bSYour Name 
2553*5113495bSYour Name 	if (!mld_hash_obj->mld_peer_hash.bins)
2554*5113495bSYour Name 		return NULL;
2555*5113495bSYour Name 
2556*5113495bSYour Name 	if (mac_addr_is_aligned) {
2557*5113495bSYour Name 		mac_addr = (union dp_align_mac_addr *)peer_mac_addr;
2558*5113495bSYour Name 	} else {
2559*5113495bSYour Name 		qdf_mem_copy(
2560*5113495bSYour Name 			&local_mac_addr_aligned.raw[0],
2561*5113495bSYour Name 			peer_mac_addr, QDF_MAC_ADDR_SIZE);
2562*5113495bSYour Name 		mac_addr = &local_mac_addr_aligned;
2563*5113495bSYour Name 	}
2564*5113495bSYour Name 
2565*5113495bSYour Name 	if (vdev_id != DP_VDEV_ALL) {
2566*5113495bSYour Name 		vdev = dp_vdev_get_ref_by_id(soc, vdev_id, mod_id);
2567*5113495bSYour Name 		if (!vdev) {
2568*5113495bSYour Name 			dp_err("vdev is null");
2569*5113495bSYour Name 			return NULL;
2570*5113495bSYour Name 		}
2571*5113495bSYour Name 	} else {
2572*5113495bSYour Name 		vdev = NULL;
2573*5113495bSYour Name 	}
2574*5113495bSYour Name 
2575*5113495bSYour Name 	/* search mld peer table if no link peer for given mac address */
2576*5113495bSYour Name 	index = dp_mlo_peer_find_hash_index(mld_hash_obj, mac_addr);
2577*5113495bSYour Name 	qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
2578*5113495bSYour Name 	TAILQ_FOREACH(peer, &mld_hash_obj->mld_peer_hash.bins[index],
2579*5113495bSYour Name 		      hash_list_elem) {
2580*5113495bSYour Name 		if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) {
2581*5113495bSYour Name 			if ((vdev_id == DP_VDEV_ALL) || (
2582*5113495bSYour Name 				dp_peer_find_mac_addr_cmp(
2583*5113495bSYour Name 						&peer->vdev->mld_mac_addr,
2584*5113495bSYour Name 						&vdev->mld_mac_addr) == 0)) {
2585*5113495bSYour Name 				/* take peer reference before returning */
2586*5113495bSYour Name 				if (dp_peer_get_ref(NULL, peer, mod_id) !=
2587*5113495bSYour Name 						QDF_STATUS_SUCCESS)
2588*5113495bSYour Name 					peer = NULL;
2589*5113495bSYour Name 
2590*5113495bSYour Name 				if (vdev)
2591*5113495bSYour Name 					dp_vdev_unref_delete(soc, vdev, mod_id);
2592*5113495bSYour Name 
2593*5113495bSYour Name 				qdf_spin_unlock_bh(
2594*5113495bSYour Name 					&mld_hash_obj->mld_peer_hash_lock);
2595*5113495bSYour Name 				return peer;
2596*5113495bSYour Name 			}
2597*5113495bSYour Name 		}
2598*5113495bSYour Name 	}
2599*5113495bSYour Name 
2600*5113495bSYour Name 	if (vdev)
2601*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, mod_id);
2602*5113495bSYour Name 
2603*5113495bSYour Name 	qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
2604*5113495bSYour Name 
2605*5113495bSYour Name 	return NULL; /* failure */
2606*5113495bSYour Name }
2607*5113495bSYour Name 
2608*5113495bSYour Name static void
dp_mlo_peer_find_hash_remove_be(struct dp_soc * soc,struct dp_peer * peer)2609*5113495bSYour Name dp_mlo_peer_find_hash_remove_be(struct dp_soc *soc, struct dp_peer *peer)
2610*5113495bSYour Name {
2611*5113495bSYour Name 	uint32_t index;
2612*5113495bSYour Name 	struct dp_peer *tmppeer = NULL;
2613*5113495bSYour Name 	int found = 0;
2614*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2615*5113495bSYour Name 
2616*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2617*5113495bSYour Name 
2618*5113495bSYour Name 	if (!mld_hash_obj)
2619*5113495bSYour Name 		return;
2620*5113495bSYour Name 
2621*5113495bSYour Name 	index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr);
2622*5113495bSYour Name 	QDF_ASSERT(!TAILQ_EMPTY(&mld_hash_obj->mld_peer_hash.bins[index]));
2623*5113495bSYour Name 
2624*5113495bSYour Name 	qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
2625*5113495bSYour Name 	TAILQ_FOREACH(tmppeer, &mld_hash_obj->mld_peer_hash.bins[index],
2626*5113495bSYour Name 		      hash_list_elem) {
2627*5113495bSYour Name 		if (tmppeer == peer) {
2628*5113495bSYour Name 			found = 1;
2629*5113495bSYour Name 			break;
2630*5113495bSYour Name 		}
2631*5113495bSYour Name 	}
2632*5113495bSYour Name 	QDF_ASSERT(found);
2633*5113495bSYour Name 	TAILQ_REMOVE(&mld_hash_obj->mld_peer_hash.bins[index], peer,
2634*5113495bSYour Name 		     hash_list_elem);
2635*5113495bSYour Name 
2636*5113495bSYour Name 	dp_info("Peer %pK (" QDF_MAC_ADDR_FMT ") removed. (found %u)",
2637*5113495bSYour Name 		peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw), found);
2638*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
2639*5113495bSYour Name 	qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
2640*5113495bSYour Name 
2641*5113495bSYour Name }
2642*5113495bSYour Name 
2643*5113495bSYour Name static void
dp_mlo_peer_find_hash_add_be(struct dp_soc * soc,struct dp_peer * peer)2644*5113495bSYour Name dp_mlo_peer_find_hash_add_be(struct dp_soc *soc, struct dp_peer *peer)
2645*5113495bSYour Name {
2646*5113495bSYour Name 	uint32_t index;
2647*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2648*5113495bSYour Name 
2649*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2650*5113495bSYour Name 
2651*5113495bSYour Name 	if (!mld_hash_obj)
2652*5113495bSYour Name 		return;
2653*5113495bSYour Name 
2654*5113495bSYour Name 	index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr);
2655*5113495bSYour Name 
2656*5113495bSYour Name 	qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
2657*5113495bSYour Name 
2658*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(dp_peer_get_ref(NULL, peer,
2659*5113495bSYour Name 						DP_MOD_ID_CONFIG))) {
2660*5113495bSYour Name 		dp_err("fail to get peer ref:" QDF_MAC_ADDR_FMT,
2661*5113495bSYour Name 		       QDF_MAC_ADDR_REF(peer->mac_addr.raw));
2662*5113495bSYour Name 		qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
2663*5113495bSYour Name 		return;
2664*5113495bSYour Name 	}
2665*5113495bSYour Name 	TAILQ_INSERT_TAIL(&mld_hash_obj->mld_peer_hash.bins[index], peer,
2666*5113495bSYour Name 			  hash_list_elem);
2667*5113495bSYour Name 	qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
2668*5113495bSYour Name 
2669*5113495bSYour Name 	dp_info("Peer %pK (" QDF_MAC_ADDR_FMT ") added",
2670*5113495bSYour Name 		peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw));
2671*5113495bSYour Name }
2672*5113495bSYour Name 
dp_print_mlo_ast_stats_be(struct dp_soc * soc)2673*5113495bSYour Name void dp_print_mlo_ast_stats_be(struct dp_soc *soc)
2674*5113495bSYour Name {
2675*5113495bSYour Name 	uint32_t index;
2676*5113495bSYour Name 	struct dp_peer *peer;
2677*5113495bSYour Name 	dp_mld_peer_hash_obj_t mld_hash_obj;
2678*5113495bSYour Name 
2679*5113495bSYour Name 	mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
2680*5113495bSYour Name 
2681*5113495bSYour Name 	if (!mld_hash_obj)
2682*5113495bSYour Name 		return;
2683*5113495bSYour Name 
2684*5113495bSYour Name 	qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
2685*5113495bSYour Name 	for (index = 0; index < mld_hash_obj->mld_peer_hash.mask; index++) {
2686*5113495bSYour Name 		TAILQ_FOREACH(peer, &mld_hash_obj->mld_peer_hash.bins[index],
2687*5113495bSYour Name 			      hash_list_elem) {
2688*5113495bSYour Name 			dp_print_peer_ast_entries(soc, peer, NULL);
2689*5113495bSYour Name 		}
2690*5113495bSYour Name 	}
2691*5113495bSYour Name 	qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
2692*5113495bSYour Name }
2693*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO */
dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2694*5113495bSYour Name void dp_mlo_dev_ctxt_list_attach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2695*5113495bSYour Name {
2696*5113495bSYour Name }
2697*5113495bSYour Name 
dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)2698*5113495bSYour Name void dp_mlo_dev_ctxt_list_detach_wrapper(dp_mlo_dev_obj_t mlo_dev_obj)
2699*5113495bSYour Name {
2700*5113495bSYour Name }
2701*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
2702*5113495bSYour Name 
2703*5113495bSYour Name #if defined(DP_UMAC_HW_HARD_RESET) && defined(DP_UMAC_HW_RESET_SUPPORT)
dp_reconfig_tx_vdev_mcast_ctrl_be(struct dp_soc * soc,struct dp_vdev * vdev)2704*5113495bSYour Name static void dp_reconfig_tx_vdev_mcast_ctrl_be(struct dp_soc *soc,
2705*5113495bSYour Name 					      struct dp_vdev *vdev)
2706*5113495bSYour Name {
2707*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2708*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2709*5113495bSYour Name 	hal_soc_handle_t hal_soc = soc->hal_soc;
2710*5113495bSYour Name 	uint8_t vdev_id = vdev->vdev_id;
2711*5113495bSYour Name 
2712*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_sta) {
2713*5113495bSYour Name 		if (vdev->pdev->isolation)
2714*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
2715*5113495bSYour Name 						HAL_TX_MCAST_CTRL_FW_EXCEPTION);
2716*5113495bSYour Name 		else
2717*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id,
2718*5113495bSYour Name 						HAL_TX_MCAST_CTRL_MEC_NOTIFY);
2719*5113495bSYour Name 	} else if (vdev->opmode == wlan_op_mode_ap) {
2720*5113495bSYour Name 		hal_tx_mcast_mlo_reinject_routing_set(
2721*5113495bSYour Name 					hal_soc,
2722*5113495bSYour Name 					HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY);
2723*5113495bSYour Name 		if (vdev->mlo_vdev) {
2724*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(
2725*5113495bSYour Name 						hal_soc,
2726*5113495bSYour Name 						vdev_id,
2727*5113495bSYour Name 						HAL_TX_MCAST_CTRL_NO_SPECIAL);
2728*5113495bSYour Name 		} else {
2729*5113495bSYour Name 			hal_tx_vdev_mcast_ctrl_set(hal_soc,
2730*5113495bSYour Name 						   vdev_id,
2731*5113495bSYour Name 						   HAL_TX_MCAST_CTRL_FW_EXCEPTION);
2732*5113495bSYour Name 		}
2733*5113495bSYour Name 	}
2734*5113495bSYour Name }
2735*5113495bSYour Name 
dp_bank_reconfig_be(struct dp_soc * soc,struct dp_vdev * vdev)2736*5113495bSYour Name static void dp_bank_reconfig_be(struct dp_soc *soc, struct dp_vdev *vdev)
2737*5113495bSYour Name {
2738*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2739*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2740*5113495bSYour Name 	union hal_tx_bank_config *bank_config;
2741*5113495bSYour Name 
2742*5113495bSYour Name 	if (!be_vdev || be_vdev->bank_id == DP_BE_INVALID_BANK_ID)
2743*5113495bSYour Name 		return;
2744*5113495bSYour Name 
2745*5113495bSYour Name 	bank_config = &be_soc->bank_profiles[be_vdev->bank_id].bank_config;
2746*5113495bSYour Name 
2747*5113495bSYour Name 	hal_tx_populate_bank_register(be_soc->soc.hal_soc, bank_config,
2748*5113495bSYour Name 				      be_vdev->bank_id);
2749*5113495bSYour Name }
2750*5113495bSYour Name 
2751*5113495bSYour Name #endif
2752*5113495bSYour Name 
2753*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
2754*5113495bSYour Name 	defined(WLAN_MCAST_MLO)
dp_mlo_mcast_reset_pri_mcast(struct dp_vdev_be * be_vdev,struct dp_vdev * ptnr_vdev,void * arg)2755*5113495bSYour Name static void dp_mlo_mcast_reset_pri_mcast(struct dp_vdev_be *be_vdev,
2756*5113495bSYour Name 					 struct dp_vdev *ptnr_vdev,
2757*5113495bSYour Name 					 void *arg)
2758*5113495bSYour Name {
2759*5113495bSYour Name 	struct dp_vdev_be *be_ptnr_vdev =
2760*5113495bSYour Name 				dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
2761*5113495bSYour Name 
2762*5113495bSYour Name 	be_ptnr_vdev->mcast_primary = false;
2763*5113495bSYour Name }
2764*5113495bSYour Name 
2765*5113495bSYour Name #if defined(CONFIG_MLO_SINGLE_DEV)
dp_txrx_set_mlo_mcast_primary_vdev_param_be(struct dp_vdev * vdev,cdp_config_param_type val)2766*5113495bSYour Name static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
2767*5113495bSYour Name 					struct dp_vdev *vdev,
2768*5113495bSYour Name 					cdp_config_param_type val)
2769*5113495bSYour Name {
2770*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2771*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(
2772*5113495bSYour Name 						be_vdev->vdev.pdev->soc);
2773*5113495bSYour Name 
2774*5113495bSYour Name 	be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev;
2775*5113495bSYour Name 	vdev->mlo_vdev = 1;
2776*5113495bSYour Name 
2777*5113495bSYour Name 	if (be_vdev->mcast_primary) {
2778*5113495bSYour Name 		struct cdp_txrx_peer_params_update params = {0};
2779*5113495bSYour Name 
2780*5113495bSYour Name 		dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
2781*5113495bSYour Name 				      dp_mlo_mcast_reset_pri_mcast,
2782*5113495bSYour Name 				      (void *)&be_vdev->mcast_primary,
2783*5113495bSYour Name 				      DP_MOD_ID_TX_MCAST,
2784*5113495bSYour Name 				      DP_LINK_VDEV_ITER,
2785*5113495bSYour Name 				      DP_VDEV_ITERATE_SKIP_SELF);
2786*5113495bSYour Name 
2787*5113495bSYour Name 		params.chip_id = be_soc->mlo_chip_id;
2788*5113495bSYour Name 		params.pdev_id = be_vdev->vdev.pdev->pdev_id;
2789*5113495bSYour Name 		params.vdev_id = vdev->vdev_id;
2790*5113495bSYour Name 		dp_wdi_event_handler(
2791*5113495bSYour Name 				WDI_EVENT_MCAST_PRIMARY_UPDATE,
2792*5113495bSYour Name 				be_vdev->vdev.pdev->soc,
2793*5113495bSYour Name 				(void *)&params, CDP_INVALID_PEER,
2794*5113495bSYour Name 				WDI_NO_VAL, params.pdev_id);
2795*5113495bSYour Name 	}
2796*5113495bSYour Name }
2797*5113495bSYour Name 
dp_get_vdev_stats_for_unmap_peer_mlo(struct dp_vdev * vdev,struct dp_peer * peer)2798*5113495bSYour Name static void dp_get_vdev_stats_for_unmap_peer_mlo(struct dp_vdev *vdev,
2799*5113495bSYour Name 						    struct dp_peer *peer)
2800*5113495bSYour Name {
2801*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2802*5113495bSYour Name 	struct cdp_vdev_stats *vdev_stats = &be_vdev->mlo_stats;
2803*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = dp_get_txrx_peer(peer);
2804*5113495bSYour Name 	struct dp_pdev *pdev = vdev->pdev;
2805*5113495bSYour Name 	struct dp_soc *soc = vdev->pdev->soc;
2806*5113495bSYour Name 	uint8_t link_id = dp_get_peer_hw_link_id(soc, pdev);
2807*5113495bSYour Name 	struct dp_peer_per_pkt_stats *per_pkt_stats;
2808*5113495bSYour Name 
2809*5113495bSYour Name 	if (!txrx_peer)
2810*5113495bSYour Name 		goto link_stats;
2811*5113495bSYour Name 
2812*5113495bSYour Name 	dp_peer_aggregate_tid_stats(peer);
2813*5113495bSYour Name 
2814*5113495bSYour Name 	if (!IS_MLO_DP_LINK_PEER(peer)) {
2815*5113495bSYour Name 		per_pkt_stats = &txrx_peer->stats[0].per_pkt_stats;
2816*5113495bSYour Name 		dp_update_vdev_basic_stats(txrx_peer, vdev_stats);
2817*5113495bSYour Name 		DP_UPDATE_PER_PKT_STATS(vdev_stats, per_pkt_stats);
2818*5113495bSYour Name 	}
2819*5113495bSYour Name 
2820*5113495bSYour Name 	if (IS_MLO_DP_LINK_PEER(peer)) {
2821*5113495bSYour Name 		link_id = dp_get_peer_hw_link_id(soc, pdev);
2822*5113495bSYour Name 		if (link_id > 0) {
2823*5113495bSYour Name 			per_pkt_stats =
2824*5113495bSYour Name 				&txrx_peer->stats[link_id].per_pkt_stats;
2825*5113495bSYour Name 			DP_UPDATE_PER_PKT_STATS(vdev_stats, per_pkt_stats);
2826*5113495bSYour Name 		}
2827*5113495bSYour Name 	}
2828*5113495bSYour Name 
2829*5113495bSYour Name link_stats:
2830*5113495bSYour Name 	dp_monitor_peer_get_stats(soc, peer, vdev_stats, UPDATE_VDEV_STATS_MLD);
2831*5113495bSYour Name }
2832*5113495bSYour Name 
2833*5113495bSYour Name static
dp_get_vdev_stats_for_unmap_peer_be(struct dp_vdev * vdev,struct dp_peer * peer)2834*5113495bSYour Name void dp_get_vdev_stats_for_unmap_peer_be(struct dp_vdev *vdev,
2835*5113495bSYour Name 					 struct dp_peer *peer)
2836*5113495bSYour Name {
2837*5113495bSYour Name 
2838*5113495bSYour Name 	if (IS_DP_LEGACY_PEER(peer))
2839*5113495bSYour Name 		dp_get_vdev_stats_for_unmap_peer_legacy(vdev, peer);
2840*5113495bSYour Name 	else
2841*5113495bSYour Name 		dp_get_vdev_stats_for_unmap_peer_mlo(vdev, peer);
2842*5113495bSYour Name }
2843*5113495bSYour Name #else
dp_txrx_set_mlo_mcast_primary_vdev_param_be(struct dp_vdev * vdev,cdp_config_param_type val)2844*5113495bSYour Name static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
2845*5113495bSYour Name 					struct dp_vdev *vdev,
2846*5113495bSYour Name 					cdp_config_param_type val)
2847*5113495bSYour Name {
2848*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2849*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(
2850*5113495bSYour Name 						be_vdev->vdev.pdev->soc);
2851*5113495bSYour Name 
2852*5113495bSYour Name 	be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev;
2853*5113495bSYour Name 	vdev->mlo_vdev = 1;
2854*5113495bSYour Name 	hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
2855*5113495bSYour Name 				   vdev->vdev_id,
2856*5113495bSYour Name 				   HAL_TX_MCAST_CTRL_NO_SPECIAL);
2857*5113495bSYour Name 
2858*5113495bSYour Name 	if (be_vdev->mcast_primary) {
2859*5113495bSYour Name 		struct cdp_txrx_peer_params_update params = {0};
2860*5113495bSYour Name 
2861*5113495bSYour Name 		dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
2862*5113495bSYour Name 				      dp_mlo_mcast_reset_pri_mcast,
2863*5113495bSYour Name 				      (void *)&be_vdev->mcast_primary,
2864*5113495bSYour Name 				      DP_MOD_ID_TX_MCAST,
2865*5113495bSYour Name 				      DP_LINK_VDEV_ITER,
2866*5113495bSYour Name 				      DP_VDEV_ITERATE_SKIP_SELF);
2867*5113495bSYour Name 
2868*5113495bSYour Name 		params.chip_id = be_soc->mlo_chip_id;
2869*5113495bSYour Name 		params.pdev_id = vdev->pdev->pdev_id;
2870*5113495bSYour Name 		params.vdev_id = vdev->vdev_id;
2871*5113495bSYour Name 		dp_wdi_event_handler(
2872*5113495bSYour Name 				WDI_EVENT_MCAST_PRIMARY_UPDATE,
2873*5113495bSYour Name 				vdev->pdev->soc,
2874*5113495bSYour Name 				(void *)&params, CDP_INVALID_PEER,
2875*5113495bSYour Name 				WDI_NO_VAL, params.pdev_id);
2876*5113495bSYour Name 	}
2877*5113495bSYour Name }
2878*5113495bSYour Name #endif
2879*5113495bSYour Name 
dp_txrx_reset_mlo_mcast_primary_vdev_param_be(struct dp_vdev * vdev,cdp_config_param_type val)2880*5113495bSYour Name static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be(
2881*5113495bSYour Name 					struct dp_vdev *vdev,
2882*5113495bSYour Name 					cdp_config_param_type val)
2883*5113495bSYour Name {
2884*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2885*5113495bSYour Name 
2886*5113495bSYour Name 	be_vdev->mcast_primary = false;
2887*5113495bSYour Name 	vdev->mlo_vdev = 0;
2888*5113495bSYour Name 	hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
2889*5113495bSYour Name 				   vdev->vdev_id,
2890*5113495bSYour Name 				   HAL_TX_MCAST_CTRL_FW_EXCEPTION);
2891*5113495bSYour Name }
2892*5113495bSYour Name 
2893*5113495bSYour Name /**
2894*5113495bSYour Name  * dp_txrx_get_vdev_mcast_param_be() - Target specific ops for getting vdev
2895*5113495bSYour Name  *                                      params related to multicast
2896*5113495bSYour Name  * @soc: DP soc handle
2897*5113495bSYour Name  * @vdev: pointer to vdev structure
2898*5113495bSYour Name  * @val: buffer address
2899*5113495bSYour Name  *
2900*5113495bSYour Name  * Return: QDF_STATUS
2901*5113495bSYour Name  */
2902*5113495bSYour Name static
dp_txrx_get_vdev_mcast_param_be(struct dp_soc * soc,struct dp_vdev * vdev,cdp_config_param_type * val)2903*5113495bSYour Name QDF_STATUS dp_txrx_get_vdev_mcast_param_be(struct dp_soc *soc,
2904*5113495bSYour Name 					   struct dp_vdev *vdev,
2905*5113495bSYour Name 					   cdp_config_param_type *val)
2906*5113495bSYour Name {
2907*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2908*5113495bSYour Name 
2909*5113495bSYour Name 	if (be_vdev->mcast_primary)
2910*5113495bSYour Name 		val->cdp_vdev_param_mcast_vdev = true;
2911*5113495bSYour Name 	else
2912*5113495bSYour Name 		val->cdp_vdev_param_mcast_vdev = false;
2913*5113495bSYour Name 
2914*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2915*5113495bSYour Name }
2916*5113495bSYour Name #else
dp_txrx_set_mlo_mcast_primary_vdev_param_be(struct dp_vdev * vdev,cdp_config_param_type val)2917*5113495bSYour Name static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
2918*5113495bSYour Name 					struct dp_vdev *vdev,
2919*5113495bSYour Name 					cdp_config_param_type val)
2920*5113495bSYour Name {
2921*5113495bSYour Name }
2922*5113495bSYour Name 
dp_txrx_reset_mlo_mcast_primary_vdev_param_be(struct dp_vdev * vdev,cdp_config_param_type val)2923*5113495bSYour Name static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be(
2924*5113495bSYour Name 					struct dp_vdev *vdev,
2925*5113495bSYour Name 					cdp_config_param_type val)
2926*5113495bSYour Name {
2927*5113495bSYour Name }
2928*5113495bSYour Name 
2929*5113495bSYour Name static
dp_txrx_get_vdev_mcast_param_be(struct dp_soc * soc,struct dp_vdev * vdev,cdp_config_param_type * val)2930*5113495bSYour Name QDF_STATUS dp_txrx_get_vdev_mcast_param_be(struct dp_soc *soc,
2931*5113495bSYour Name 					   struct dp_vdev *vdev,
2932*5113495bSYour Name 					   cdp_config_param_type *val)
2933*5113495bSYour Name {
2934*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2935*5113495bSYour Name }
2936*5113495bSYour Name 
2937*5113495bSYour Name static
dp_get_vdev_stats_for_unmap_peer_be(struct dp_vdev * vdev,struct dp_peer * peer)2938*5113495bSYour Name void dp_get_vdev_stats_for_unmap_peer_be(struct dp_vdev *vdev,
2939*5113495bSYour Name 					 struct dp_peer *peer)
2940*5113495bSYour Name {
2941*5113495bSYour Name }
2942*5113495bSYour Name #endif
2943*5113495bSYour Name 
2944*5113495bSYour Name #ifdef DP_TX_IMPLICIT_RBM_MAPPING
dp_tx_implicit_rbm_set_be(struct dp_soc * soc,uint8_t tx_ring_id,uint8_t bm_id)2945*5113495bSYour Name static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc,
2946*5113495bSYour Name 				      uint8_t tx_ring_id,
2947*5113495bSYour Name 				      uint8_t bm_id)
2948*5113495bSYour Name {
2949*5113495bSYour Name 	hal_tx_config_rbm_mapping_be(soc->hal_soc,
2950*5113495bSYour Name 				     soc->tcl_data_ring[tx_ring_id].hal_srng,
2951*5113495bSYour Name 				     bm_id);
2952*5113495bSYour Name }
2953*5113495bSYour Name #else
dp_tx_implicit_rbm_set_be(struct dp_soc * soc,uint8_t tx_ring_id,uint8_t bm_id)2954*5113495bSYour Name static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc,
2955*5113495bSYour Name 				      uint8_t tx_ring_id,
2956*5113495bSYour Name 				      uint8_t bm_id)
2957*5113495bSYour Name {
2958*5113495bSYour Name }
2959*5113495bSYour Name #endif
2960*5113495bSYour Name 
2961*5113495bSYour Name /**
2962*5113495bSYour Name  * dp_txrx_set_vdev_param_be() - Target specific ops while setting vdev params
2963*5113495bSYour Name  * @soc: DP soc handle
2964*5113495bSYour Name  * @vdev: pointer to vdev structure
2965*5113495bSYour Name  * @param: parameter type to get value
2966*5113495bSYour Name  * @val: value
2967*5113495bSYour Name  *
2968*5113495bSYour Name  * Return: QDF_STATUS
2969*5113495bSYour Name  */
2970*5113495bSYour Name static
dp_txrx_set_vdev_param_be(struct dp_soc * soc,struct dp_vdev * vdev,enum cdp_vdev_param_type param,cdp_config_param_type val)2971*5113495bSYour Name QDF_STATUS dp_txrx_set_vdev_param_be(struct dp_soc *soc,
2972*5113495bSYour Name 				     struct dp_vdev *vdev,
2973*5113495bSYour Name 				     enum cdp_vdev_param_type param,
2974*5113495bSYour Name 				     cdp_config_param_type val)
2975*5113495bSYour Name {
2976*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
2977*5113495bSYour Name 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
2978*5113495bSYour Name 
2979*5113495bSYour Name 	switch (param) {
2980*5113495bSYour Name 	case CDP_TX_ENCAP_TYPE:
2981*5113495bSYour Name 	case CDP_UPDATE_DSCP_TO_TID_MAP:
2982*5113495bSYour Name 	case CDP_UPDATE_TDLS_FLAGS:
2983*5113495bSYour Name 		dp_tx_update_bank_profile(be_soc, be_vdev);
2984*5113495bSYour Name 		dp_tx_update_vp_profile(be_soc, be_vdev);
2985*5113495bSYour Name 		break;
2986*5113495bSYour Name 	case CDP_ENABLE_CIPHER:
2987*5113495bSYour Name 		if (vdev->tx_encap_type == htt_cmn_pkt_type_raw)
2988*5113495bSYour Name 			dp_tx_update_bank_profile(be_soc, be_vdev);
2989*5113495bSYour Name 		break;
2990*5113495bSYour Name 	case CDP_SET_MCAST_VDEV:
2991*5113495bSYour Name 		dp_txrx_set_mlo_mcast_primary_vdev_param_be(vdev, val);
2992*5113495bSYour Name 		break;
2993*5113495bSYour Name 	case CDP_RESET_MLO_MCAST_VDEV:
2994*5113495bSYour Name 		dp_txrx_reset_mlo_mcast_primary_vdev_param_be(vdev, val);
2995*5113495bSYour Name 		break;
2996*5113495bSYour Name 	default:
2997*5113495bSYour Name 		dp_warn("invalid param %d", param);
2998*5113495bSYour Name 		break;
2999*5113495bSYour Name 	}
3000*5113495bSYour Name 
3001*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3002*5113495bSYour Name }
3003*5113495bSYour Name 
3004*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
3005*5113495bSYour Name #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
3006*5113495bSYour Name static inline void
dp_soc_max_peer_id_set(struct dp_soc * soc)3007*5113495bSYour Name dp_soc_max_peer_id_set(struct dp_soc *soc)
3008*5113495bSYour Name {
3009*5113495bSYour Name 	soc->peer_id_shift = dp_log2_ceil(soc->max_peers);
3010*5113495bSYour Name 	soc->peer_id_mask = (1 << soc->peer_id_shift) - 1;
3011*5113495bSYour Name 	/*
3012*5113495bSYour Name 	 * Double the peers since we use ML indication bit
3013*5113495bSYour Name 	 * alongwith peer_id to find peers.
3014*5113495bSYour Name 	 */
3015*5113495bSYour Name 	soc->max_peer_id = 1 << (soc->peer_id_shift + 1);
3016*5113495bSYour Name }
3017*5113495bSYour Name #else
3018*5113495bSYour Name static inline void
dp_soc_max_peer_id_set(struct dp_soc * soc)3019*5113495bSYour Name dp_soc_max_peer_id_set(struct dp_soc *soc)
3020*5113495bSYour Name {
3021*5113495bSYour Name 	soc->max_peer_id =
3022*5113495bSYour Name 		(1 << (HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S + 1)) - 1;
3023*5113495bSYour Name }
3024*5113495bSYour Name #endif /* DP_USE_REDUCED_PEER_ID_FIELD_WIDTH */
3025*5113495bSYour Name #else
3026*5113495bSYour Name static inline void
dp_soc_max_peer_id_set(struct dp_soc * soc)3027*5113495bSYour Name dp_soc_max_peer_id_set(struct dp_soc *soc)
3028*5113495bSYour Name {
3029*5113495bSYour Name 	soc->max_peer_id = soc->max_peers;
3030*5113495bSYour Name }
3031*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
3032*5113495bSYour Name 
dp_peer_map_detach_be(struct dp_soc * soc)3033*5113495bSYour Name static void dp_peer_map_detach_be(struct dp_soc *soc)
3034*5113495bSYour Name {
3035*5113495bSYour Name 	if (soc->host_ast_db_enable)
3036*5113495bSYour Name 		dp_peer_ast_hash_detach(soc);
3037*5113495bSYour Name }
3038*5113495bSYour Name 
dp_peer_map_attach_be(struct dp_soc * soc)3039*5113495bSYour Name static QDF_STATUS dp_peer_map_attach_be(struct dp_soc *soc)
3040*5113495bSYour Name {
3041*5113495bSYour Name 	QDF_STATUS status;
3042*5113495bSYour Name 
3043*5113495bSYour Name 	if (soc->host_ast_db_enable) {
3044*5113495bSYour Name 		status = dp_peer_ast_hash_attach(soc);
3045*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
3046*5113495bSYour Name 			return status;
3047*5113495bSYour Name 	}
3048*5113495bSYour Name 
3049*5113495bSYour Name 	dp_soc_max_peer_id_set(soc);
3050*5113495bSYour Name 
3051*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3052*5113495bSYour Name }
3053*5113495bSYour Name 
3054*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_DP_MLO_DEV_CTX)
3055*5113495bSYour Name 
dp_mlo_dev_ctxt_list_attach(dp_mlo_dev_obj_t mlo_dev_obj)3056*5113495bSYour Name void dp_mlo_dev_ctxt_list_attach(dp_mlo_dev_obj_t mlo_dev_obj)
3057*5113495bSYour Name {
3058*5113495bSYour Name 	TAILQ_INIT(&mlo_dev_obj->mlo_dev_list);
3059*5113495bSYour Name 	qdf_spinlock_create(&mlo_dev_obj->mlo_dev_list_lock);
3060*5113495bSYour Name }
3061*5113495bSYour Name 
dp_mlo_dev_ctxt_list_detach(dp_mlo_dev_obj_t mlo_dev_obj)3062*5113495bSYour Name void dp_mlo_dev_ctxt_list_detach(dp_mlo_dev_obj_t mlo_dev_obj)
3063*5113495bSYour Name {
3064*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mld_ctxt = NULL;
3065*5113495bSYour Name 	struct dp_mlo_dev_ctxt *tmp_mld_ctxt = NULL;
3066*5113495bSYour Name 
3067*5113495bSYour Name 	if (!TAILQ_EMPTY(&mlo_dev_obj->mlo_dev_list)) {
3068*5113495bSYour Name 		dp_alert("DP MLO dev list is not empty");
3069*5113495bSYour Name 		qdf_spin_lock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3070*5113495bSYour Name 		TAILQ_FOREACH_SAFE(mld_ctxt, &mlo_dev_obj->mlo_dev_list,
3071*5113495bSYour Name 				   ml_dev_list_elem, tmp_mld_ctxt) {
3072*5113495bSYour Name 			if (mld_ctxt) {
3073*5113495bSYour Name 				dp_alert("MLD MAC " QDF_MAC_ADDR_FMT " ",
3074*5113495bSYour Name 					 QDF_MAC_ADDR_REF(
3075*5113495bSYour Name 						&mld_ctxt->mld_mac_addr.raw));
3076*5113495bSYour Name 				qdf_mem_free(mld_ctxt);
3077*5113495bSYour Name 			}
3078*5113495bSYour Name 		}
3079*5113495bSYour Name 		qdf_spin_unlock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3080*5113495bSYour Name 	}
3081*5113495bSYour Name 
3082*5113495bSYour Name 	qdf_spinlock_destroy(&mlo_dev_obj->mlo_dev_list_lock);
3083*5113495bSYour Name }
3084*5113495bSYour Name 
dp_mlo_dev_ctxt_unref_delete(struct dp_mlo_dev_ctxt * mlo_dev_ctxt,enum dp_mod_id mod_id)3085*5113495bSYour Name void dp_mlo_dev_ctxt_unref_delete(struct dp_mlo_dev_ctxt *mlo_dev_ctxt,
3086*5113495bSYour Name 				  enum dp_mod_id mod_id)
3087*5113495bSYour Name {
3088*5113495bSYour Name 	QDF_ASSERT(qdf_atomic_dec_return(&mlo_dev_ctxt->mod_refs[mod_id]) >= 0);
3089*5113495bSYour Name 
3090*5113495bSYour Name 	/* Return if this is not the last reference*/
3091*5113495bSYour Name 	if (!qdf_atomic_dec_and_test(&mlo_dev_ctxt->ref_cnt))
3092*5113495bSYour Name 		return;
3093*5113495bSYour Name 
3094*5113495bSYour Name 	QDF_ASSERT(mlo_dev_ctxt->ref_delete_pending);
3095*5113495bSYour Name 	qdf_spinlock_destroy(&mlo_dev_ctxt->vdev_list_lock);
3096*5113495bSYour Name 	qdf_mem_free(mlo_dev_ctxt);
3097*5113495bSYour Name }
3098*5113495bSYour Name 
dp_mlo_dev_get_ref(struct dp_mlo_dev_ctxt * mlo_dev_ctxt,enum dp_mod_id mod_id)3099*5113495bSYour Name QDF_STATUS dp_mlo_dev_get_ref(struct dp_mlo_dev_ctxt *mlo_dev_ctxt,
3100*5113495bSYour Name 			      enum dp_mod_id mod_id)
3101*5113495bSYour Name {
3102*5113495bSYour Name 	if (!qdf_atomic_inc_return(&mlo_dev_ctxt->ref_cnt))
3103*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3104*5113495bSYour Name 
3105*5113495bSYour Name 	qdf_atomic_inc(&mlo_dev_ctxt->mod_refs[mod_id]);
3106*5113495bSYour Name 
3107*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3108*5113495bSYour Name }
3109*5113495bSYour Name 
3110*5113495bSYour Name struct dp_mlo_dev_ctxt *
dp_get_mlo_dev_ctx_by_mld_mac_addr(struct dp_soc_be * be_soc,uint8_t * mldaddr,enum dp_mod_id mod_id)3111*5113495bSYour Name dp_get_mlo_dev_ctx_by_mld_mac_addr(struct dp_soc_be *be_soc,
3112*5113495bSYour Name 				   uint8_t *mldaddr,
3113*5113495bSYour Name 				   enum dp_mod_id mod_id)
3114*5113495bSYour Name {
3115*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mld_cur = NULL;
3116*5113495bSYour Name 	struct dp_mlo_dev_ctxt *tmp_mld_cur = NULL;
3117*5113495bSYour Name 	dp_mlo_dev_obj_t mlo_dev_obj;
3118*5113495bSYour Name 
3119*5113495bSYour Name 	mlo_dev_obj = dp_get_mlo_dev_list_obj(be_soc);
3120*5113495bSYour Name 	if (!mlo_dev_obj) {
3121*5113495bSYour Name 		dp_err("DP Global MLO Context is NULL");
3122*5113495bSYour Name 		return NULL;
3123*5113495bSYour Name 	}
3124*5113495bSYour Name 
3125*5113495bSYour Name 	/*
3126*5113495bSYour Name 	 * Iterate through ml dev list, till mldaddr matches with
3127*5113495bSYour Name 	 * entry of list
3128*5113495bSYour Name 	 */
3129*5113495bSYour Name 	qdf_spin_lock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3130*5113495bSYour Name 	TAILQ_FOREACH_SAFE(mld_cur, &mlo_dev_obj->mlo_dev_list,
3131*5113495bSYour Name 			   ml_dev_list_elem, tmp_mld_cur) {
3132*5113495bSYour Name 		if (!qdf_mem_cmp(&mld_cur->mld_mac_addr.raw, mldaddr,
3133*5113495bSYour Name 				 QDF_MAC_ADDR_SIZE)) {
3134*5113495bSYour Name 			if (dp_mlo_dev_get_ref(mld_cur, mod_id)
3135*5113495bSYour Name 			    == QDF_STATUS_SUCCESS) {
3136*5113495bSYour Name 				qdf_spin_unlock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3137*5113495bSYour Name 				return mld_cur;
3138*5113495bSYour Name 			}
3139*5113495bSYour Name 		}
3140*5113495bSYour Name 	}
3141*5113495bSYour Name 	qdf_spin_unlock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3142*5113495bSYour Name 	return NULL;
3143*5113495bSYour Name }
3144*5113495bSYour Name 
3145*5113495bSYour Name /**
3146*5113495bSYour Name  * dp_mlo_dev_ctxt_create() - Allocate DP MLO dev context
3147*5113495bSYour Name  * @soc_hdl: SOC handle
3148*5113495bSYour Name  * @mld_mac_addr: MLD MAC address
3149*5113495bSYour Name  *
3150*5113495bSYour Name  * Return: QDF_STATUS
3151*5113495bSYour Name  */
3152*5113495bSYour Name static inline
dp_mlo_dev_ctxt_create(struct cdp_soc_t * soc_hdl,uint8_t * mld_mac_addr)3153*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_create(struct cdp_soc_t *soc_hdl,
3154*5113495bSYour Name 				  uint8_t *mld_mac_addr)
3155*5113495bSYour Name {
3156*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mlo_dev_ctxt = NULL;
3157*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
3158*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3159*5113495bSYour Name 	dp_mlo_dev_obj_t mlo_dev_obj;
3160*5113495bSYour Name 
3161*5113495bSYour Name 	mlo_dev_obj = dp_get_mlo_dev_list_obj(be_soc);
3162*5113495bSYour Name 	if (!mlo_dev_obj) {
3163*5113495bSYour Name 		dp_err("DP Global MLO Context is NULL");
3164*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3165*5113495bSYour Name 	}
3166*5113495bSYour Name 
3167*5113495bSYour Name 	/* check if MLO dev ctx already available */
3168*5113495bSYour Name 	mlo_dev_ctxt = dp_get_mlo_dev_ctx_by_mld_mac_addr(be_soc,
3169*5113495bSYour Name 							  mld_mac_addr,
3170*5113495bSYour Name 							  DP_MOD_ID_MLO_DEV);
3171*5113495bSYour Name 	if (mlo_dev_ctxt) {
3172*5113495bSYour Name 		dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3173*5113495bSYour Name 		/* assert if we get two create request for same MLD MAC */
3174*5113495bSYour Name 		qdf_assert_always(0);
3175*5113495bSYour Name 	}
3176*5113495bSYour Name 
3177*5113495bSYour Name 	/* Allocate MLO dev ctx */
3178*5113495bSYour Name 	mlo_dev_ctxt = qdf_mem_malloc(sizeof(struct dp_mlo_dev_ctxt));
3179*5113495bSYour Name 
3180*5113495bSYour Name 	if (!mlo_dev_ctxt) {
3181*5113495bSYour Name 		dp_err("Failed to allocate DP MLO Dev Context");
3182*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3183*5113495bSYour Name 	}
3184*5113495bSYour Name 
3185*5113495bSYour Name 	qdf_copy_macaddr((struct qdf_mac_addr *)&mlo_dev_ctxt->mld_mac_addr.raw[0],
3186*5113495bSYour Name 			 (struct qdf_mac_addr *)mld_mac_addr);
3187*5113495bSYour Name 
3188*5113495bSYour Name 	qdf_mem_set(mlo_dev_ctxt->vdev_list,
3189*5113495bSYour Name 		    WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC,
3190*5113495bSYour Name 		    CDP_INVALID_VDEV_ID);
3191*5113495bSYour Name 	qdf_mem_set(mlo_dev_ctxt->bridge_vdev,
3192*5113495bSYour Name 		    WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC,
3193*5113495bSYour Name 		    CDP_INVALID_VDEV_ID);
3194*5113495bSYour Name 	mlo_dev_ctxt->seq_num = 0;
3195*5113495bSYour Name 
3196*5113495bSYour Name 	/* Add mlo_dev_ctxt to the global DP MLO list */
3197*5113495bSYour Name 	qdf_spin_lock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3198*5113495bSYour Name 	TAILQ_INSERT_TAIL(&mlo_dev_obj->mlo_dev_list,
3199*5113495bSYour Name 			  mlo_dev_ctxt, ml_dev_list_elem);
3200*5113495bSYour Name 	qdf_spin_unlock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3201*5113495bSYour Name 
3202*5113495bSYour Name 	/* Ref for MLO ctxt saved in global list */
3203*5113495bSYour Name 	dp_mlo_dev_get_ref(mlo_dev_ctxt, DP_MOD_ID_CONFIG);
3204*5113495bSYour Name 
3205*5113495bSYour Name 	mlo_dev_ctxt->ref_delete_pending = 0;
3206*5113495bSYour Name 	qdf_spinlock_create(&mlo_dev_ctxt->vdev_list_lock);
3207*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3208*5113495bSYour Name }
3209*5113495bSYour Name 
3210*5113495bSYour Name /**
3211*5113495bSYour Name  * dp_mlo_dev_ctxt_destroy() - Destroy DP MLO dev context
3212*5113495bSYour Name  * @soc_hdl: SOC handle
3213*5113495bSYour Name  * @mld_mac_addr: MLD MAC address
3214*5113495bSYour Name  *
3215*5113495bSYour Name  * Return: QDF_STATUS
3216*5113495bSYour Name  */
3217*5113495bSYour Name static inline
dp_mlo_dev_ctxt_destroy(struct cdp_soc_t * soc_hdl,uint8_t * mld_mac_addr)3218*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_destroy(struct cdp_soc_t *soc_hdl,
3219*5113495bSYour Name 				   uint8_t *mld_mac_addr)
3220*5113495bSYour Name {
3221*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mlo_dev_ctxt = NULL;
3222*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
3223*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3224*5113495bSYour Name 	dp_mlo_dev_obj_t mlo_dev_obj;
3225*5113495bSYour Name 
3226*5113495bSYour Name 	mlo_dev_obj = dp_get_mlo_dev_list_obj(be_soc);
3227*5113495bSYour Name 	if (!mlo_dev_obj) {
3228*5113495bSYour Name 		dp_err("DP Global MLO Context is NULL");
3229*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3230*5113495bSYour Name 	}
3231*5113495bSYour Name 
3232*5113495bSYour Name 	/* GET mlo_dev_ctxt from the global list */
3233*5113495bSYour Name 	mlo_dev_ctxt = dp_get_mlo_dev_ctx_by_mld_mac_addr(be_soc,
3234*5113495bSYour Name 							  mld_mac_addr,
3235*5113495bSYour Name 							  DP_MOD_ID_MLO_DEV);
3236*5113495bSYour Name 	if (!mlo_dev_ctxt) {
3237*5113495bSYour Name 		dp_err("Failed to get DP MLO Dev Context by MLD mac addr");
3238*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3239*5113495bSYour Name 	}
3240*5113495bSYour Name 
3241*5113495bSYour Name 	if (mlo_dev_ctxt->vdev_count)
3242*5113495bSYour Name 		dp_alert("deleting MLO dev ctxt with non zero vdev count");
3243*5113495bSYour Name 
3244*5113495bSYour Name 	qdf_spin_lock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3245*5113495bSYour Name 	TAILQ_REMOVE(&mlo_dev_obj->mlo_dev_list,
3246*5113495bSYour Name 		     mlo_dev_ctxt, ml_dev_list_elem);
3247*5113495bSYour Name 	qdf_spin_unlock_bh(&mlo_dev_obj->mlo_dev_list_lock);
3248*5113495bSYour Name 
3249*5113495bSYour Name 	/* unref for MLO ctxt ref released from Global list */
3250*5113495bSYour Name 	dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_CONFIG);
3251*5113495bSYour Name 
3252*5113495bSYour Name 	mlo_dev_ctxt->ref_delete_pending = 1;
3253*5113495bSYour Name 	dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3254*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3255*5113495bSYour Name }
3256*5113495bSYour Name 
3257*5113495bSYour Name /**
3258*5113495bSYour Name  * dp_mlo_dev_ctxt_vdev_attach() - Attach vdev to DP MLO dev context
3259*5113495bSYour Name  * @soc_hdl: SOC handle
3260*5113495bSYour Name  * @vdev_id: vdev id for the vdev to be attached
3261*5113495bSYour Name  * @mld_mac_addr: MLD MAC address
3262*5113495bSYour Name  *
3263*5113495bSYour Name  * Return: QDF_STATUS
3264*5113495bSYour Name  */
3265*5113495bSYour Name static inline
dp_mlo_dev_ctxt_vdev_attach(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mld_mac_addr)3266*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_vdev_attach(struct cdp_soc_t *soc_hdl,
3267*5113495bSYour Name 				       uint8_t vdev_id,
3268*5113495bSYour Name 				       uint8_t *mld_mac_addr)
3269*5113495bSYour Name {
3270*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mlo_dev_ctxt = NULL;
3271*5113495bSYour Name 	struct dp_vdev *vdev = NULL;
3272*5113495bSYour Name 	struct dp_vdev_be *be_vdev = NULL;
3273*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
3274*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3275*5113495bSYour Name 
3276*5113495bSYour Name 	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
3277*5113495bSYour Name 	if (!vdev)
3278*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3279*5113495bSYour Name 	be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
3280*5113495bSYour Name 
3281*5113495bSYour Name 	/* GET mlo_dev_ctxt from the global list */
3282*5113495bSYour Name 	mlo_dev_ctxt = dp_get_mlo_dev_ctx_by_mld_mac_addr(be_soc,
3283*5113495bSYour Name 							  mld_mac_addr,
3284*5113495bSYour Name 							  DP_MOD_ID_MLO_DEV);
3285*5113495bSYour Name 	if (!mlo_dev_ctxt) {
3286*5113495bSYour Name 		dp_err("Failed to get MLO ctxt for " QDF_MAC_ADDR_FMT "",
3287*5113495bSYour Name 		       QDF_MAC_ADDR_REF(mld_mac_addr));
3288*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
3289*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3290*5113495bSYour Name 	}
3291*5113495bSYour Name 
3292*5113495bSYour Name 	dp_attach_vdev_list_in_mlo_dev_ctxt(be_soc, vdev, mlo_dev_ctxt);
3293*5113495bSYour Name 	be_vdev->mlo_dev_ctxt = mlo_dev_ctxt;
3294*5113495bSYour Name 
3295*5113495bSYour Name 	/* ref for holding MLO ctxt in be_vdev */
3296*5113495bSYour Name 	dp_mlo_dev_get_ref(mlo_dev_ctxt, DP_MOD_ID_CHILD);
3297*5113495bSYour Name 
3298*5113495bSYour Name 	/* unref for mlo ctxt taken at the start of this function */
3299*5113495bSYour Name 	dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3300*5113495bSYour Name 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
3301*5113495bSYour Name 
3302*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3303*5113495bSYour Name }
3304*5113495bSYour Name 
3305*5113495bSYour Name /**
3306*5113495bSYour Name  * dp_mlo_dev_ctxt_vdev_detach() - Detach vdev from DP MLO dev context
3307*5113495bSYour Name  * @soc_hdl: SOC handle
3308*5113495bSYour Name  * @vdev_id: vdev id for the vdev to be attached
3309*5113495bSYour Name  * @mld_mac_addr: MLD MAC address
3310*5113495bSYour Name  *
3311*5113495bSYour Name  * Return: QDF_STATUS
3312*5113495bSYour Name  */
3313*5113495bSYour Name static inline
dp_mlo_dev_ctxt_vdev_detach(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mld_mac_addr)3314*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_vdev_detach(struct cdp_soc_t *soc_hdl,
3315*5113495bSYour Name 				       uint8_t vdev_id,
3316*5113495bSYour Name 				       uint8_t *mld_mac_addr)
3317*5113495bSYour Name {
3318*5113495bSYour Name 	struct dp_vdev *vdev = NULL;
3319*5113495bSYour Name 	struct dp_vdev_be *be_vdev = NULL;
3320*5113495bSYour Name 	struct dp_mlo_dev_ctxt *mlo_dev_ctxt = NULL;
3321*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
3322*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3323*5113495bSYour Name 
3324*5113495bSYour Name 	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
3325*5113495bSYour Name 	if (!vdev)
3326*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3327*5113495bSYour Name 
3328*5113495bSYour Name 	be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
3329*5113495bSYour Name 
3330*5113495bSYour Name 	/* GET mlo_dev_ctxt from the global list */
3331*5113495bSYour Name 	mlo_dev_ctxt = dp_get_mlo_dev_ctx_by_mld_mac_addr(be_soc,
3332*5113495bSYour Name 							  mld_mac_addr,
3333*5113495bSYour Name 							  DP_MOD_ID_MLO_DEV);
3334*5113495bSYour Name 
3335*5113495bSYour Name 	if (!mlo_dev_ctxt) {
3336*5113495bSYour Name 		dp_err("Failed to get DP MLO Dev Context by MLD mac addr");
3337*5113495bSYour Name 		if (!be_vdev->mlo_dev_ctxt) {
3338*5113495bSYour Name 			dp_err("Failed to get DP MLO Dev Context from vdev");
3339*5113495bSYour Name 			dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
3340*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
3341*5113495bSYour Name 		}
3342*5113495bSYour Name 		mlo_dev_ctxt = be_vdev->mlo_dev_ctxt;
3343*5113495bSYour Name 		dp_mlo_dev_get_ref(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3344*5113495bSYour Name 	}
3345*5113495bSYour Name 
3346*5113495bSYour Name 	if (dp_detach_vdev_list_in_mlo_dev_ctxt(be_soc, vdev, mlo_dev_ctxt)
3347*5113495bSYour Name 	    != QDF_STATUS_SUCCESS) {
3348*5113495bSYour Name 		dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3349*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
3350*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
3351*5113495bSYour Name 	}
3352*5113495bSYour Name 
3353*5113495bSYour Name 	be_vdev->mlo_dev_ctxt = NULL;
3354*5113495bSYour Name 
3355*5113495bSYour Name 	/* Save vdev stats in MLO dev ctx */
3356*5113495bSYour Name 	dp_update_mlo_mld_vdev_ctxt_stats(&mlo_dev_ctxt->stats, &vdev->stats);
3357*5113495bSYour Name 
3358*5113495bSYour Name 	/* reset vdev stats to zero */
3359*5113495bSYour Name 	qdf_mem_set(&vdev->stats, sizeof(struct dp_vdev_stats), 0);
3360*5113495bSYour Name 
3361*5113495bSYour Name 	/* unref for mlo ctxt removed from be_vdev*/
3362*5113495bSYour Name 	dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_CHILD);
3363*5113495bSYour Name 
3364*5113495bSYour Name 	/* unref for mlo ctxt taken at the start of this function */
3365*5113495bSYour Name 	dp_mlo_dev_ctxt_unref_delete(mlo_dev_ctxt, DP_MOD_ID_MLO_DEV);
3366*5113495bSYour Name 
3367*5113495bSYour Name 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
3368*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3369*5113495bSYour Name }
3370*5113495bSYour Name #else
dp_mlo_dev_ctxt_list_attach(dp_mlo_dev_obj_t mlo_dev_obj)3371*5113495bSYour Name void dp_mlo_dev_ctxt_list_attach(dp_mlo_dev_obj_t mlo_dev_obj)
3372*5113495bSYour Name {
3373*5113495bSYour Name }
3374*5113495bSYour Name 
dp_mlo_dev_ctxt_list_detach(dp_mlo_dev_obj_t mlo_dev_obj)3375*5113495bSYour Name void dp_mlo_dev_ctxt_list_detach(dp_mlo_dev_obj_t mlo_dev_obj)
3376*5113495bSYour Name {
3377*5113495bSYour Name }
3378*5113495bSYour Name 
3379*5113495bSYour Name static inline
dp_mlo_dev_ctxt_create(struct cdp_soc_t * soc_hdl,uint8_t * mld_mac_addr)3380*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_create(struct cdp_soc_t *soc_hdl,
3381*5113495bSYour Name 				  uint8_t *mld_mac_addr)
3382*5113495bSYour Name {
3383*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3384*5113495bSYour Name }
3385*5113495bSYour Name 
3386*5113495bSYour Name static inline
dp_mlo_dev_ctxt_destroy(struct cdp_soc_t * soc_hdl,uint8_t * mld_mac_addr)3387*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_destroy(struct cdp_soc_t *soc_hdl,
3388*5113495bSYour Name 				   uint8_t *mld_mac_addr)
3389*5113495bSYour Name {
3390*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3391*5113495bSYour Name }
3392*5113495bSYour Name 
3393*5113495bSYour Name static inline
dp_mlo_dev_ctxt_vdev_attach(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mld_mac_addr)3394*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_vdev_attach(struct cdp_soc_t *soc_hdl,
3395*5113495bSYour Name 				       uint8_t vdev_id,
3396*5113495bSYour Name 				       uint8_t *mld_mac_addr)
3397*5113495bSYour Name {
3398*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3399*5113495bSYour Name }
3400*5113495bSYour Name 
3401*5113495bSYour Name static inline
dp_mlo_dev_ctxt_vdev_detach(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mld_mac_addr)3402*5113495bSYour Name QDF_STATUS dp_mlo_dev_ctxt_vdev_detach(struct cdp_soc_t *soc_hdl,
3403*5113495bSYour Name 				       uint8_t vdev_id,
3404*5113495bSYour Name 				       uint8_t *mld_mac_addr)
3405*5113495bSYour Name {
3406*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3407*5113495bSYour Name }
3408*5113495bSYour Name #endif /* WLAN_DP_MLO_DEV_CTX */
3409*5113495bSYour Name 
3410*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
3411*5113495bSYour Name #ifdef WLAN_MCAST_MLO
3412*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops * arch_ops)3413*5113495bSYour Name dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops)
3414*5113495bSYour Name {
3415*5113495bSYour Name 	arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be;
3416*5113495bSYour Name 	arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler;
3417*5113495bSYour Name 	arch_ops->dp_tx_is_mcast_primary = dp_tx_mlo_is_mcast_primary_be;
3418*5113495bSYour Name }
3419*5113495bSYour Name #else /* WLAN_MCAST_MLO */
3420*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops * arch_ops)3421*5113495bSYour Name dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops)
3422*5113495bSYour Name {
3423*5113495bSYour Name }
3424*5113495bSYour Name #endif /* WLAN_MCAST_MLO */
3425*5113495bSYour Name 
3426*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
3427*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mlo_multi_chip(struct dp_arch_ops * arch_ops)3428*5113495bSYour Name dp_initialize_arch_ops_be_mlo_multi_chip(struct dp_arch_ops *arch_ops)
3429*5113495bSYour Name {
3430*5113495bSYour Name 	arch_ops->dp_partner_chips_map = dp_mlo_partner_chips_map;
3431*5113495bSYour Name 	arch_ops->dp_partner_chips_unmap = dp_mlo_partner_chips_unmap;
3432*5113495bSYour Name 	arch_ops->dp_soc_get_by_idle_bm_id = dp_soc_get_by_idle_bm_id;
3433*5113495bSYour Name 	arch_ops->dp_get_soc_by_chip_id = dp_get_soc_by_chip_id_be;
3434*5113495bSYour Name 	arch_ops->dp_mlo_print_ptnr_info = dp_mlo_debug_print_ptnr_info;
3435*5113495bSYour Name 	arch_ops->dp_get_interface_stats = dp_get_interface_stats_be;
3436*5113495bSYour Name 	arch_ops->mlo_get_chip_id = dp_mlo_get_chip_id;
3437*5113495bSYour Name 	arch_ops->mlo_link_peer_find_hash_find_by_chip_id =
3438*5113495bSYour Name 				dp_mlo_link_peer_hash_find_by_chip_id;
3439*5113495bSYour Name }
3440*5113495bSYour Name #else
3441*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mlo_multi_chip(struct dp_arch_ops * arch_ops)3442*5113495bSYour Name dp_initialize_arch_ops_be_mlo_multi_chip(struct dp_arch_ops *arch_ops)
3443*5113495bSYour Name {
3444*5113495bSYour Name }
3445*5113495bSYour Name #endif
3446*5113495bSYour Name 
3447*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mlo(struct dp_arch_ops * arch_ops)3448*5113495bSYour Name dp_initialize_arch_ops_be_mlo(struct dp_arch_ops *arch_ops)
3449*5113495bSYour Name {
3450*5113495bSYour Name 	dp_initialize_arch_ops_be_mcast_mlo(arch_ops);
3451*5113495bSYour Name 	dp_initialize_arch_ops_be_mlo_multi_chip(arch_ops);
3452*5113495bSYour Name 	arch_ops->mlo_peer_find_hash_detach =
3453*5113495bSYour Name 	dp_mlo_peer_find_hash_detach_wrapper;
3454*5113495bSYour Name 	arch_ops->mlo_peer_find_hash_attach =
3455*5113495bSYour Name 	dp_mlo_peer_find_hash_attach_wrapper;
3456*5113495bSYour Name 	arch_ops->mlo_peer_find_hash_add = dp_mlo_peer_find_hash_add_be;
3457*5113495bSYour Name 	arch_ops->mlo_peer_find_hash_remove = dp_mlo_peer_find_hash_remove_be;
3458*5113495bSYour Name 	arch_ops->mlo_peer_find_hash_find = dp_mlo_peer_find_hash_find_be;
3459*5113495bSYour Name 	arch_ops->get_hw_link_id = dp_get_hw_link_id_be;
3460*5113495bSYour Name }
3461*5113495bSYour Name 
3462*5113495bSYour Name static struct cdp_cmn_mlo_ops dp_cmn_mlo_ops = {
3463*5113495bSYour Name 	.mlo_dev_ctxt_create = dp_mlo_dev_ctxt_create,
3464*5113495bSYour Name 	.mlo_dev_ctxt_attach = dp_mlo_dev_ctxt_vdev_attach,
3465*5113495bSYour Name 	.mlo_dev_ctxt_detach = dp_mlo_dev_ctxt_vdev_detach,
3466*5113495bSYour Name 	.mlo_dev_ctxt_destroy = dp_mlo_dev_ctxt_destroy,
3467*5113495bSYour Name };
3468*5113495bSYour Name 
dp_soc_initialize_cdp_cmn_mlo_ops(struct dp_soc * soc)3469*5113495bSYour Name void dp_soc_initialize_cdp_cmn_mlo_ops(struct dp_soc *soc)
3470*5113495bSYour Name {
3471*5113495bSYour Name 	soc->cdp_soc.ops->cmn_mlo_ops = &dp_cmn_mlo_ops;
3472*5113495bSYour Name }
3473*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO */
3474*5113495bSYour Name static inline void
dp_initialize_arch_ops_be_mlo(struct dp_arch_ops * arch_ops)3475*5113495bSYour Name dp_initialize_arch_ops_be_mlo(struct dp_arch_ops *arch_ops)
3476*5113495bSYour Name {
3477*5113495bSYour Name }
3478*5113495bSYour Name 
dp_soc_initialize_cdp_cmn_mlo_ops(struct dp_soc * soc)3479*5113495bSYour Name void dp_soc_initialize_cdp_cmn_mlo_ops(struct dp_soc *soc)
3480*5113495bSYour Name {
3481*5113495bSYour Name }
3482*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
3483*5113495bSYour Name 
3484*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
3485*5113495bSYour Name #define DP_LMAC_PEER_ID_MSB_LEGACY 2
3486*5113495bSYour Name #define DP_LMAC_PEER_ID_MSB_MLO 3
3487*5113495bSYour Name 
dp_peer_get_reo_hash_be(struct dp_vdev * vdev,struct cdp_peer_setup_info * setup_info,enum cdp_host_reo_dest_ring * reo_dest,bool * hash_based,uint8_t * lmac_peer_id_msb)3488*5113495bSYour Name static void dp_peer_get_reo_hash_be(struct dp_vdev *vdev,
3489*5113495bSYour Name 				    struct cdp_peer_setup_info *setup_info,
3490*5113495bSYour Name 				    enum cdp_host_reo_dest_ring *reo_dest,
3491*5113495bSYour Name 				    bool *hash_based,
3492*5113495bSYour Name 				    uint8_t *lmac_peer_id_msb)
3493*5113495bSYour Name {
3494*5113495bSYour Name 	struct dp_soc *soc = vdev->pdev->soc;
3495*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3496*5113495bSYour Name 
3497*5113495bSYour Name 	if (!be_soc->mlo_enabled)
3498*5113495bSYour Name 		return dp_vdev_get_default_reo_hash(vdev, reo_dest,
3499*5113495bSYour Name 						    hash_based);
3500*5113495bSYour Name 
3501*5113495bSYour Name 	*hash_based = wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx);
3502*5113495bSYour Name 	*reo_dest = vdev->pdev->reo_dest;
3503*5113495bSYour Name 
3504*5113495bSYour Name 	/* Not a ML link peer use non-mlo */
3505*5113495bSYour Name 	if (!setup_info) {
3506*5113495bSYour Name 		*lmac_peer_id_msb = DP_LMAC_PEER_ID_MSB_LEGACY;
3507*5113495bSYour Name 		return;
3508*5113495bSYour Name 	}
3509*5113495bSYour Name 
3510*5113495bSYour Name 	/* For STA ML VAP we do not have num links info at this point
3511*5113495bSYour Name 	 * use MLO case always
3512*5113495bSYour Name 	 */
3513*5113495bSYour Name 	if (vdev->opmode == wlan_op_mode_sta) {
3514*5113495bSYour Name 		*lmac_peer_id_msb = DP_LMAC_PEER_ID_MSB_MLO;
3515*5113495bSYour Name 		return;
3516*5113495bSYour Name 	}
3517*5113495bSYour Name 
3518*5113495bSYour Name 	/* For AP ML VAP consider the peer as ML only it associates with
3519*5113495bSYour Name 	 * multiple links
3520*5113495bSYour Name 	 */
3521*5113495bSYour Name 	if (setup_info->num_links == 1) {
3522*5113495bSYour Name 		*lmac_peer_id_msb = DP_LMAC_PEER_ID_MSB_LEGACY;
3523*5113495bSYour Name 		return;
3524*5113495bSYour Name 	}
3525*5113495bSYour Name 
3526*5113495bSYour Name 	*lmac_peer_id_msb = DP_LMAC_PEER_ID_MSB_MLO;
3527*5113495bSYour Name }
3528*5113495bSYour Name 
dp_reo_remap_config_be(struct dp_soc * soc,uint32_t * remap0,uint32_t * remap1,uint32_t * remap2)3529*5113495bSYour Name static bool dp_reo_remap_config_be(struct dp_soc *soc,
3530*5113495bSYour Name 				   uint32_t *remap0,
3531*5113495bSYour Name 				   uint32_t *remap1,
3532*5113495bSYour Name 				   uint32_t *remap2)
3533*5113495bSYour Name {
3534*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3535*5113495bSYour Name 	uint32_t reo_config = wlan_cfg_get_reo_rings_mapping(soc->wlan_cfg_ctx);
3536*5113495bSYour Name 	uint32_t reo_mlo_config =
3537*5113495bSYour Name 		wlan_cfg_mlo_rx_ring_map_get(soc->wlan_cfg_ctx);
3538*5113495bSYour Name 
3539*5113495bSYour Name 	if (!be_soc->mlo_enabled)
3540*5113495bSYour Name 		return dp_reo_remap_config(soc, remap0, remap1, remap2);
3541*5113495bSYour Name 
3542*5113495bSYour Name 	*remap0 = hal_reo_ix_remap_value_get_be(soc->hal_soc, reo_mlo_config);
3543*5113495bSYour Name 	*remap1 = hal_reo_ix_remap_value_get_be(soc->hal_soc, reo_config);
3544*5113495bSYour Name 	*remap2 = hal_reo_ix_remap_value_get_be(soc->hal_soc, reo_mlo_config);
3545*5113495bSYour Name 
3546*5113495bSYour Name 	return true;
3547*5113495bSYour Name }
3548*5113495bSYour Name #else
dp_peer_get_reo_hash_be(struct dp_vdev * vdev,struct cdp_peer_setup_info * setup_info,enum cdp_host_reo_dest_ring * reo_dest,bool * hash_based,uint8_t * lmac_peer_id_msb)3549*5113495bSYour Name static void dp_peer_get_reo_hash_be(struct dp_vdev *vdev,
3550*5113495bSYour Name 				    struct cdp_peer_setup_info *setup_info,
3551*5113495bSYour Name 				    enum cdp_host_reo_dest_ring *reo_dest,
3552*5113495bSYour Name 				    bool *hash_based,
3553*5113495bSYour Name 				    uint8_t *lmac_peer_id_msb)
3554*5113495bSYour Name {
3555*5113495bSYour Name 	dp_vdev_get_default_reo_hash(vdev, reo_dest, hash_based);
3556*5113495bSYour Name }
3557*5113495bSYour Name 
dp_reo_remap_config_be(struct dp_soc * soc,uint32_t * remap0,uint32_t * remap1,uint32_t * remap2)3558*5113495bSYour Name static bool dp_reo_remap_config_be(struct dp_soc *soc,
3559*5113495bSYour Name 				   uint32_t *remap0,
3560*5113495bSYour Name 				   uint32_t *remap1,
3561*5113495bSYour Name 				   uint32_t *remap2)
3562*5113495bSYour Name {
3563*5113495bSYour Name 	return dp_reo_remap_config(soc, remap0, remap1, remap2);
3564*5113495bSYour Name }
3565*5113495bSYour Name #endif
3566*5113495bSYour Name 
3567*5113495bSYour Name #ifdef CONFIG_MLO_SINGLE_DEV
3568*5113495bSYour Name static inline
dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops * arch_ops)3569*5113495bSYour Name void dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops *arch_ops)
3570*5113495bSYour Name {
3571*5113495bSYour Name 	arch_ops->dp_tx_mlo_mcast_send = dp_tx_mlo_mcast_send_be;
3572*5113495bSYour Name }
3573*5113495bSYour Name #else
3574*5113495bSYour Name static inline
dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops * arch_ops)3575*5113495bSYour Name void dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops *arch_ops)
3576*5113495bSYour Name {
3577*5113495bSYour Name }
3578*5113495bSYour Name #endif
3579*5113495bSYour Name 
3580*5113495bSYour Name #ifdef IPA_OFFLOAD
dp_ipa_get_bank_id_be(struct dp_soc * soc)3581*5113495bSYour Name static int8_t dp_ipa_get_bank_id_be(struct dp_soc *soc)
3582*5113495bSYour Name {
3583*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3584*5113495bSYour Name 
3585*5113495bSYour Name 	return be_soc->ipa_bank_id;
3586*5113495bSYour Name }
3587*5113495bSYour Name 
3588*5113495bSYour Name #ifdef QCA_IPA_LL_TX_FLOW_CONTROL
dp_ipa_get_wdi_version_be(uint8_t * wdi_ver)3589*5113495bSYour Name static void dp_ipa_get_wdi_version_be(uint8_t *wdi_ver)
3590*5113495bSYour Name {
3591*5113495bSYour Name 	*wdi_ver = IPA_WDI_4;
3592*5113495bSYour Name }
3593*5113495bSYour Name #else
dp_ipa_get_wdi_version_be(uint8_t * wdi_ver)3594*5113495bSYour Name static inline void dp_ipa_get_wdi_version_be(uint8_t *wdi_ver)
3595*5113495bSYour Name {
3596*5113495bSYour Name }
3597*5113495bSYour Name #endif
3598*5113495bSYour Name 
dp_initialize_arch_ops_be_ipa(struct dp_arch_ops * arch_ops)3599*5113495bSYour Name static inline void dp_initialize_arch_ops_be_ipa(struct dp_arch_ops *arch_ops)
3600*5113495bSYour Name {
3601*5113495bSYour Name 	arch_ops->ipa_get_bank_id = dp_ipa_get_bank_id_be;
3602*5113495bSYour Name 	arch_ops->ipa_get_wdi_ver = dp_ipa_get_wdi_version_be;
3603*5113495bSYour Name }
3604*5113495bSYour Name #else /* !IPA_OFFLOAD */
dp_initialize_arch_ops_be_ipa(struct dp_arch_ops * arch_ops)3605*5113495bSYour Name static inline void dp_initialize_arch_ops_be_ipa(struct dp_arch_ops *arch_ops)
3606*5113495bSYour Name {
3607*5113495bSYour Name }
3608*5113495bSYour Name #endif /* IPA_OFFLOAD */
3609*5113495bSYour Name 
dp_initialize_arch_ops_be(struct dp_arch_ops * arch_ops)3610*5113495bSYour Name void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
3611*5113495bSYour Name {
3612*5113495bSYour Name #ifndef QCA_HOST_MODE_WIFI_DISABLED
3613*5113495bSYour Name 	arch_ops->tx_hw_enqueue = dp_tx_hw_enqueue_be;
3614*5113495bSYour Name 	arch_ops->dp_rx_process = dp_rx_process_be;
3615*5113495bSYour Name 	arch_ops->dp_tx_send_fast = dp_tx_fast_send_be;
3616*5113495bSYour Name 	arch_ops->tx_comp_get_params_from_hal_desc =
3617*5113495bSYour Name 		dp_tx_comp_get_params_from_hal_desc_be;
3618*5113495bSYour Name 	arch_ops->dp_tx_process_htt_completion =
3619*5113495bSYour Name 				dp_tx_process_htt_completion_be;
3620*5113495bSYour Name 	arch_ops->dp_tx_desc_pool_alloc = dp_tx_desc_pool_alloc_be;
3621*5113495bSYour Name 	arch_ops->dp_tx_desc_pool_free = dp_tx_desc_pool_free_be;
3622*5113495bSYour Name 	arch_ops->dp_tx_desc_pool_init = dp_tx_desc_pool_init_be;
3623*5113495bSYour Name 	arch_ops->dp_tx_desc_pool_deinit = dp_tx_desc_pool_deinit_be;
3624*5113495bSYour Name 	arch_ops->dp_rx_desc_pool_init = dp_rx_desc_pool_init_be;
3625*5113495bSYour Name 	arch_ops->dp_rx_desc_pool_deinit = dp_rx_desc_pool_deinit_be;
3626*5113495bSYour Name 	arch_ops->dp_wbm_get_rx_desc_from_hal_desc =
3627*5113495bSYour Name 				dp_wbm_get_rx_desc_from_hal_desc_be;
3628*5113495bSYour Name 	arch_ops->dp_tx_compute_hw_delay = dp_tx_compute_tx_delay_be;
3629*5113495bSYour Name 	arch_ops->dp_rx_wbm_err_reap_desc = dp_rx_wbm_err_reap_desc_be;
3630*5113495bSYour Name 	arch_ops->dp_rx_null_q_desc_handle = dp_rx_null_q_desc_handle_be;
3631*5113495bSYour Name #endif
3632*5113495bSYour Name 	arch_ops->txrx_get_context_size = dp_get_context_size_be;
3633*5113495bSYour Name #ifdef WIFI_MONITOR_SUPPORT
3634*5113495bSYour Name 	arch_ops->txrx_get_mon_context_size = dp_mon_get_context_size_be;
3635*5113495bSYour Name #endif
3636*5113495bSYour Name 	arch_ops->dp_rx_desc_cookie_2_va =
3637*5113495bSYour Name 			dp_rx_desc_cookie_2_va_be;
3638*5113495bSYour Name 	arch_ops->dp_rx_intrabss_mcast_handler =
3639*5113495bSYour Name 				dp_rx_intrabss_mcast_handler_be;
3640*5113495bSYour Name 	arch_ops->dp_rx_word_mask_subscribe = dp_rx_word_mask_subscribe_be;
3641*5113495bSYour Name 
3642*5113495bSYour Name 	arch_ops->txrx_soc_attach = dp_soc_attach_be;
3643*5113495bSYour Name 	arch_ops->txrx_soc_detach = dp_soc_detach_be;
3644*5113495bSYour Name 	arch_ops->txrx_soc_init = dp_soc_init_be;
3645*5113495bSYour Name 	arch_ops->txrx_soc_deinit = dp_soc_deinit_be_wrapper;
3646*5113495bSYour Name 	arch_ops->txrx_soc_srng_alloc = dp_soc_srng_alloc_be;
3647*5113495bSYour Name 	arch_ops->txrx_soc_srng_init = dp_soc_srng_init_be;
3648*5113495bSYour Name 	arch_ops->txrx_soc_srng_deinit = dp_soc_srng_deinit_be;
3649*5113495bSYour Name 	arch_ops->txrx_soc_srng_free = dp_soc_srng_free_be;
3650*5113495bSYour Name 	arch_ops->txrx_pdev_attach = dp_pdev_attach_be;
3651*5113495bSYour Name 	arch_ops->txrx_pdev_detach = dp_pdev_detach_be;
3652*5113495bSYour Name 	arch_ops->txrx_vdev_attach = dp_vdev_attach_be;
3653*5113495bSYour Name 	arch_ops->txrx_vdev_detach = dp_vdev_detach_be;
3654*5113495bSYour Name 	arch_ops->txrx_peer_setup = dp_peer_setup_be;
3655*5113495bSYour Name 	arch_ops->txrx_peer_map_attach = dp_peer_map_attach_be;
3656*5113495bSYour Name 	arch_ops->txrx_peer_map_detach = dp_peer_map_detach_be;
3657*5113495bSYour Name 	arch_ops->dp_rxdma_ring_sel_cfg = dp_rxdma_ring_sel_cfg_be;
3658*5113495bSYour Name 	arch_ops->dp_rx_peer_metadata_peer_id_get =
3659*5113495bSYour Name 					dp_rx_peer_metadata_peer_id_get_be;
3660*5113495bSYour Name 	arch_ops->soc_cfg_attach = dp_soc_cfg_attach_be;
3661*5113495bSYour Name 	arch_ops->tx_implicit_rbm_set = dp_tx_implicit_rbm_set_be;
3662*5113495bSYour Name 	arch_ops->txrx_set_vdev_param = dp_txrx_set_vdev_param_be;
3663*5113495bSYour Name 	dp_initialize_arch_ops_be_mlo(arch_ops);
3664*5113495bSYour Name 	arch_ops->dp_soc_get_num_soc = dp_soc_get_num_soc_be;
3665*5113495bSYour Name 	arch_ops->dp_peer_rx_reorder_queue_setup =
3666*5113495bSYour Name 					dp_peer_rx_reorder_queue_setup_be;
3667*5113495bSYour Name 	arch_ops->dp_rx_peer_set_link_id = dp_rx_set_link_id_be;
3668*5113495bSYour Name 	arch_ops->txrx_print_peer_stats = dp_print_peer_txrx_stats_be;
3669*5113495bSYour Name #if defined(DP_UMAC_HW_HARD_RESET) && defined(DP_UMAC_HW_RESET_SUPPORT)
3670*5113495bSYour Name 	arch_ops->dp_bank_reconfig = dp_bank_reconfig_be;
3671*5113495bSYour Name 	arch_ops->dp_reconfig_tx_vdev_mcast_ctrl =
3672*5113495bSYour Name 					dp_reconfig_tx_vdev_mcast_ctrl_be;
3673*5113495bSYour Name 	arch_ops->dp_cc_reg_cfg_init = dp_cc_reg_cfg_init;
3674*5113495bSYour Name #endif
3675*5113495bSYour Name 
3676*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
3677*5113495bSYour Name 	arch_ops->ppeds_handle_attached = dp_ppeds_handle_attached;
3678*5113495bSYour Name 	arch_ops->dp_txrx_ppeds_rings_status = dp_ppeds_rings_status;
3679*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_start = dp_ppeds_start_soc_be;
3680*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_stop = dp_ppeds_stop_soc_be;
3681*5113495bSYour Name 	arch_ops->dp_register_ppeds_interrupts = dp_register_ppeds_interrupts;
3682*5113495bSYour Name 	arch_ops->dp_free_ppeds_interrupts = dp_free_ppeds_interrupts;
3683*5113495bSYour Name 	arch_ops->dp_tx_ppeds_inuse_desc = dp_ppeds_inuse_desc;
3684*5113495bSYour Name 	arch_ops->dp_ppeds_clear_stats = dp_ppeds_clear_stats;
3685*5113495bSYour Name 	arch_ops->dp_txrx_ppeds_rings_stats = dp_ppeds_rings_stats;
3686*5113495bSYour Name 	arch_ops->dp_txrx_ppeds_clear_rings_stats = dp_ppeds_clear_rings_stats;
3687*5113495bSYour Name 	arch_ops->dp_tx_ppeds_cfg_astidx_cache_mapping =
3688*5113495bSYour Name 				dp_tx_ppeds_cfg_astidx_cache_mapping;
3689*5113495bSYour Name #ifdef DP_UMAC_HW_RESET_SUPPORT
3690*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_interrupt_stop = dp_ppeds_interrupt_stop_be;
3691*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_interrupt_start = dp_ppeds_interrupt_start_be;
3692*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_service_status_update =
3693*5113495bSYour Name 					dp_ppeds_service_status_update_be;
3694*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_enabled_check = dp_ppeds_is_enabled_on_soc;
3695*5113495bSYour Name 	arch_ops->txrx_soc_ppeds_txdesc_pool_reset =
3696*5113495bSYour Name 					dp_ppeds_tx_desc_pool_reset;
3697*5113495bSYour Name #endif
3698*5113495bSYour Name #endif
3699*5113495bSYour Name 	dp_init_near_full_arch_ops_be(arch_ops);
3700*5113495bSYour Name 	arch_ops->get_reo_qdesc_addr = dp_rx_get_reo_qdesc_addr_be;
3701*5113495bSYour Name 	arch_ops->get_rx_hash_key = dp_get_rx_hash_key_be;
3702*5113495bSYour Name 	arch_ops->dp_set_rx_fst = dp_set_rx_fst_be;
3703*5113495bSYour Name 	arch_ops->dp_get_rx_fst = dp_get_rx_fst_be;
3704*5113495bSYour Name 	arch_ops->dp_rx_fst_deref = dp_rx_fst_release_ref_be;
3705*5113495bSYour Name 	arch_ops->dp_rx_fst_ref = dp_rx_fst_get_ref_be;
3706*5113495bSYour Name 	arch_ops->print_mlo_ast_stats = dp_print_mlo_ast_stats_be;
3707*5113495bSYour Name 	arch_ops->peer_get_reo_hash = dp_peer_get_reo_hash_be;
3708*5113495bSYour Name 	arch_ops->reo_remap_config = dp_reo_remap_config_be;
3709*5113495bSYour Name 	arch_ops->txrx_get_vdev_mcast_param = dp_txrx_get_vdev_mcast_param_be;
3710*5113495bSYour Name 	arch_ops->txrx_srng_init = dp_srng_init_be;
3711*5113495bSYour Name 	arch_ops->dp_get_vdev_stats_for_unmap_peer =
3712*5113495bSYour Name 					dp_get_vdev_stats_for_unmap_peer_be;
3713*5113495bSYour Name #if defined(DP_POWER_SAVE) || defined(FEATURE_RUNTIME_PM)
3714*5113495bSYour Name 	arch_ops->dp_update_ring_hptp = dp_update_ring_hptp;
3715*5113495bSYour Name #endif
3716*5113495bSYour Name 	arch_ops->dp_flush_tx_ring = dp_flush_tcl_ring;
3717*5113495bSYour Name 	arch_ops->dp_soc_interrupt_attach = dp_soc_interrupt_attach_be;
3718*5113495bSYour Name 	arch_ops->dp_soc_attach_poll = dp_soc_attach_poll_be;
3719*5113495bSYour Name 	arch_ops->dp_soc_interrupt_detach = dp_soc_interrupt_detach_be;
3720*5113495bSYour Name 	arch_ops->dp_service_srngs = dp_service_srngs_be;
3721*5113495bSYour Name 	dp_initialize_arch_ops_be_ipa(arch_ops);
3722*5113495bSYour Name 	dp_initialize_arch_ops_be_single_dev(arch_ops);
3723*5113495bSYour Name 	dp_initialize_arch_ops_be_fisa(arch_ops);
3724*5113495bSYour Name }
3725*5113495bSYour Name 
3726*5113495bSYour Name #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE
3727*5113495bSYour Name static void
dp_primary_link_migration(struct dp_soc * soc,void * cb_ctxt,union hal_reo_status * reo_status)3728*5113495bSYour Name dp_primary_link_migration(struct dp_soc *soc, void *cb_ctxt,
3729*5113495bSYour Name 			  union hal_reo_status *reo_status)
3730*5113495bSYour Name {
3731*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3732*5113495bSYour Name 	struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
3733*5113495bSYour Name 	struct dp_soc *pr_soc = NULL;
3734*5113495bSYour Name 	struct dp_peer_info *pr_peer_info = (struct dp_peer_info *)cb_ctxt;
3735*5113495bSYour Name 	struct dp_peer *new_primary_peer = NULL;
3736*5113495bSYour Name 	struct dp_peer *mld_peer = NULL;
3737*5113495bSYour Name 	uint8_t primary_vdev_id;
3738*5113495bSYour Name 	struct cdp_txrx_peer_params_update params = {0};
3739*5113495bSYour Name 	uint8_t tid;
3740*5113495bSYour Name 	uint8_t is_wds = 0;
3741*5113495bSYour Name 	uint16_t hw_peer_id;
3742*5113495bSYour Name 	uint16_t ast_hash;
3743*5113495bSYour Name 
3744*5113495bSYour Name 	pr_soc = dp_mlo_get_soc_ref_by_chip_id(dp_mlo, pr_peer_info->chip_id);
3745*5113495bSYour Name 	if (!pr_soc) {
3746*5113495bSYour Name 		dp_htt_err("Invalid soc");
3747*5113495bSYour Name 		qdf_mem_free(pr_peer_info);
3748*5113495bSYour Name 		return;
3749*5113495bSYour Name 	}
3750*5113495bSYour Name 
3751*5113495bSYour Name 	new_primary_peer = pr_soc->peer_id_to_obj_map[
3752*5113495bSYour Name 				pr_peer_info->primary_peer_id];
3753*5113495bSYour Name 	if (!new_primary_peer) {
3754*5113495bSYour Name 		dp_htt_err("New primary peer is NULL");
3755*5113495bSYour Name 		qdf_mem_free(pr_peer_info);
3756*5113495bSYour Name 		return;
3757*5113495bSYour Name 	}
3758*5113495bSYour Name 
3759*5113495bSYour Name 	mld_peer = DP_GET_MLD_PEER_FROM_PEER(new_primary_peer);
3760*5113495bSYour Name 	if (!mld_peer) {
3761*5113495bSYour Name 		dp_htt_err("MLD peer is NULL");
3762*5113495bSYour Name 		qdf_mem_free(pr_peer_info);
3763*5113495bSYour Name 		return;
3764*5113495bSYour Name 	}
3765*5113495bSYour Name 
3766*5113495bSYour Name 	new_primary_peer->primary_link = 1;
3767*5113495bSYour Name 
3768*5113495bSYour Name 	hw_peer_id = pr_peer_info->hw_peer_id;
3769*5113495bSYour Name 	ast_hash = pr_peer_info->ast_hash;
3770*5113495bSYour Name 	/* Add ast enteries for new primary peer */
3771*5113495bSYour Name 	if (pr_soc->ast_offload_support && pr_soc->host_ast_db_enable) {
3772*5113495bSYour Name 		dp_peer_host_add_map_ast(pr_soc, mld_peer->peer_id, mld_peer->mac_addr.raw,
3773*5113495bSYour Name 					 hw_peer_id, new_primary_peer->vdev->vdev_id,
3774*5113495bSYour Name 					 ast_hash, is_wds);
3775*5113495bSYour Name 	}
3776*5113495bSYour Name 
3777*5113495bSYour Name 	/*
3778*5113495bSYour Name 	 * Check if reo_qref_table_en is set and if
3779*5113495bSYour Name 	 * rx_tid qdesc for tid 0 is already setup and perform
3780*5113495bSYour Name 	 * qref write to LUT for Tid 0 and 16.
3781*5113495bSYour Name 	 *
3782*5113495bSYour Name 	 */
3783*5113495bSYour Name 	if (hal_reo_shared_qaddr_is_enable(pr_soc->hal_soc) &&
3784*5113495bSYour Name 	    mld_peer->rx_tid[0].hw_qdesc_vaddr_unaligned) {
3785*5113495bSYour Name 		for (tid = 0; tid < DP_MAX_TIDS; tid++)
3786*5113495bSYour Name 			hal_reo_shared_qaddr_write(pr_soc->hal_soc,
3787*5113495bSYour Name 						   mld_peer->peer_id,
3788*5113495bSYour Name 						   tid,
3789*5113495bSYour Name 						   mld_peer->rx_tid[tid].hw_qdesc_paddr);
3790*5113495bSYour Name 	}
3791*5113495bSYour Name 
3792*5113495bSYour Name 	if (pr_soc && pr_soc->cdp_soc.ol_ops->update_primary_link)
3793*5113495bSYour Name 		pr_soc->cdp_soc.ol_ops->update_primary_link(pr_soc->ctrl_psoc,
3794*5113495bSYour Name 						new_primary_peer->mac_addr.raw);
3795*5113495bSYour Name 
3796*5113495bSYour Name 	primary_vdev_id = new_primary_peer->vdev->vdev_id;
3797*5113495bSYour Name 
3798*5113495bSYour Name 	dp_vdev_unref_delete(soc, mld_peer->vdev, DP_MOD_ID_CHILD);
3799*5113495bSYour Name 	mld_peer->vdev = dp_vdev_get_ref_by_id(pr_soc, primary_vdev_id,
3800*5113495bSYour Name 			 DP_MOD_ID_CHILD);
3801*5113495bSYour Name 	mld_peer->txrx_peer->vdev = mld_peer->vdev;
3802*5113495bSYour Name 
3803*5113495bSYour Name 	params.vdev_id = new_primary_peer->vdev->vdev_id;
3804*5113495bSYour Name 	params.peer_mac = mld_peer->mac_addr.raw;
3805*5113495bSYour Name 	params.chip_id = pr_peer_info->chip_id;
3806*5113495bSYour Name 	params.pdev_id = new_primary_peer->vdev->pdev->pdev_id;
3807*5113495bSYour Name 
3808*5113495bSYour Name 	if (new_primary_peer->vdev->opmode == wlan_op_mode_sta) {
3809*5113495bSYour Name 		dp_wdi_event_handler(
3810*5113495bSYour Name 				WDI_EVENT_STA_PRIMARY_UMAC_UPDATE,
3811*5113495bSYour Name 				pr_soc, (void *)&params,
3812*5113495bSYour Name 				new_primary_peer->peer_id,
3813*5113495bSYour Name 				WDI_NO_VAL, params.pdev_id);
3814*5113495bSYour Name 	} else {
3815*5113495bSYour Name 		dp_wdi_event_handler(
3816*5113495bSYour Name 				WDI_EVENT_PEER_PRIMARY_UMAC_UPDATE,
3817*5113495bSYour Name 				pr_soc, (void *)&params,
3818*5113495bSYour Name 				new_primary_peer->peer_id,
3819*5113495bSYour Name 				WDI_NO_VAL, params.pdev_id);
3820*5113495bSYour Name 	}
3821*5113495bSYour Name 	qdf_mem_free(pr_peer_info);
3822*5113495bSYour Name }
3823*5113495bSYour Name 
3824*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
dp_get_ppe_info_for_vap(struct dp_soc * pr_soc,struct dp_peer * pr_peer,uint16_t * src_info)3825*5113495bSYour Name static QDF_STATUS dp_get_ppe_info_for_vap(struct dp_soc *pr_soc,
3826*5113495bSYour Name 					  struct dp_peer *pr_peer,
3827*5113495bSYour Name 					  uint16_t *src_info)
3828*5113495bSYour Name {
3829*5113495bSYour Name 	struct dp_soc_be *be_soc_mld = NULL;
3830*5113495bSYour Name 	struct cdp_ds_vp_params vp_params = {0};
3831*5113495bSYour Name 	struct dp_ppe_vp_profile *ppe_vp_profile;
3832*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
3833*5113495bSYour Name 	struct cdp_soc_t *cdp_soc = &pr_soc->cdp_soc;
3834*5113495bSYour Name 
3835*5113495bSYour Name 	/*
3836*5113495bSYour Name 	 * Extract the VP profile from the VAP
3837*5113495bSYour Name 	 */
3838*5113495bSYour Name 	if (!cdp_soc->ol_ops->get_ppeds_profile_info_for_vap) {
3839*5113495bSYour Name 		dp_err("%pK: Register get ppeds profile info first", cdp_soc);
3840*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3841*5113495bSYour Name 	}
3842*5113495bSYour Name 
3843*5113495bSYour Name 	/*
3844*5113495bSYour Name 	 * Check if PPE DS routing is enabled on the associated vap.
3845*5113495bSYour Name 	 */
3846*5113495bSYour Name 	qdf_status = cdp_soc->ol_ops->get_ppeds_profile_info_for_vap(
3847*5113495bSYour Name 							pr_soc->ctrl_psoc,
3848*5113495bSYour Name 							pr_peer->vdev->vdev_id,
3849*5113495bSYour Name 							&vp_params);
3850*5113495bSYour Name 
3851*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3852*5113495bSYour Name 		dp_err("Could not find ppeds profile info");
3853*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
3854*5113495bSYour Name 	}
3855*5113495bSYour Name 
3856*5113495bSYour Name 	/* Check if PPE DS routing is enabled on
3857*5113495bSYour Name 	 * the associated vap.
3858*5113495bSYour Name 	 */
3859*5113495bSYour Name 	if (vp_params.ppe_vp_type != PPE_VP_USER_TYPE_DS)
3860*5113495bSYour Name 		return qdf_status;
3861*5113495bSYour Name 
3862*5113495bSYour Name 	be_soc_mld = dp_get_be_soc_from_dp_soc(pr_soc);
3863*5113495bSYour Name 	ppe_vp_profile = &be_soc_mld->ppe_vp_profile[
3864*5113495bSYour Name 				vp_params.ppe_vp_profile_idx];
3865*5113495bSYour Name 	*src_info = ppe_vp_profile->vp_num;
3866*5113495bSYour Name 
3867*5113495bSYour Name 	return qdf_status;
3868*5113495bSYour Name }
3869*5113495bSYour Name #else
dp_get_ppe_info_for_vap(struct dp_soc * pr_soc,struct dp_peer * pr_peer,uint16_t * src_info)3870*5113495bSYour Name static QDF_STATUS dp_get_ppe_info_for_vap(struct dp_soc *pr_soc,
3871*5113495bSYour Name 					  struct dp_peer *pr_peer,
3872*5113495bSYour Name 					  uint16_t *src_info)
3873*5113495bSYour Name {
3874*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
3875*5113495bSYour Name }
3876*5113495bSYour Name #endif
3877*5113495bSYour Name 
dp_htt_reo_migration(struct dp_soc * soc,uint16_t peer_id,uint16_t ml_peer_id,uint16_t vdev_id,uint8_t pdev_id,uint8_t chip_id)3878*5113495bSYour Name QDF_STATUS dp_htt_reo_migration(struct dp_soc *soc, uint16_t peer_id,
3879*5113495bSYour Name 				uint16_t ml_peer_id, uint16_t vdev_id,
3880*5113495bSYour Name 				uint8_t pdev_id, uint8_t chip_id)
3881*5113495bSYour Name {
3882*5113495bSYour Name 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
3883*5113495bSYour Name 	struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
3884*5113495bSYour Name 	uint16_t mld_peer_id = dp_gen_ml_peer_id(soc, ml_peer_id);
3885*5113495bSYour Name 	struct dp_soc *pr_soc = NULL;
3886*5113495bSYour Name 	struct dp_soc *current_pr_soc = NULL;
3887*5113495bSYour Name 	struct hal_reo_cmd_params params;
3888*5113495bSYour Name 	struct dp_rx_tid *rx_tid;
3889*5113495bSYour Name 	struct dp_peer *pr_peer = NULL;
3890*5113495bSYour Name 	struct dp_peer *mld_peer = NULL;
3891*5113495bSYour Name 	struct dp_soc *mld_soc = NULL;
3892*5113495bSYour Name 	struct dp_peer *current_pr_peer = NULL;
3893*5113495bSYour Name 	struct dp_peer_info *peer_info;
3894*5113495bSYour Name 	struct dp_vdev_be *be_vdev;
3895*5113495bSYour Name 	uint16_t src_info = 0;
3896*5113495bSYour Name 	QDF_STATUS status;
3897*5113495bSYour Name 	struct dp_ast_entry *ast_entry;
3898*5113495bSYour Name 	uint16_t hw_peer_id;
3899*5113495bSYour Name 	uint16_t ast_hash;
3900*5113495bSYour Name 	int i = 0;
3901*5113495bSYour Name 
3902*5113495bSYour Name 	if (!dp_mlo) {
3903*5113495bSYour Name 		dp_htt_err("Invalid dp_mlo ctxt");
3904*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3905*5113495bSYour Name 	}
3906*5113495bSYour Name 
3907*5113495bSYour Name 	pr_soc = dp_mlo_get_soc_ref_by_chip_id(dp_mlo, chip_id);
3908*5113495bSYour Name 	if (!pr_soc) {
3909*5113495bSYour Name 		dp_htt_err("Invalid soc");
3910*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3911*5113495bSYour Name 	}
3912*5113495bSYour Name 
3913*5113495bSYour Name 	pr_peer = pr_soc->peer_id_to_obj_map[peer_id];
3914*5113495bSYour Name 	if (!pr_peer || !(IS_MLO_DP_LINK_PEER(pr_peer))) {
3915*5113495bSYour Name 		dp_htt_err("Invalid peer");
3916*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3917*5113495bSYour Name 	}
3918*5113495bSYour Name 
3919*5113495bSYour Name 	mld_peer = DP_GET_MLD_PEER_FROM_PEER(pr_peer);
3920*5113495bSYour Name 
3921*5113495bSYour Name 	if (!mld_peer || (mld_peer->peer_id != mld_peer_id)) {
3922*5113495bSYour Name 		dp_htt_err("Invalid mld peer");
3923*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3924*5113495bSYour Name 	}
3925*5113495bSYour Name 
3926*5113495bSYour Name 	be_vdev = dp_get_be_vdev_from_dp_vdev(pr_peer->vdev);
3927*5113495bSYour Name 	if (!be_vdev) {
3928*5113495bSYour Name 		dp_htt_err("Invalid be vdev");
3929*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3930*5113495bSYour Name 	}
3931*5113495bSYour Name 
3932*5113495bSYour Name 	mld_soc = mld_peer->vdev->pdev->soc;
3933*5113495bSYour Name 	status = dp_get_ppe_info_for_vap(pr_soc, pr_peer, &src_info);
3934*5113495bSYour Name 	if (status == QDF_STATUS_E_NULL_VALUE) {
3935*5113495bSYour Name 		dp_htt_err("Invalid ppe info for the vdev");
3936*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3937*5113495bSYour Name 	}
3938*5113495bSYour Name 
3939*5113495bSYour Name 	current_pr_peer = dp_get_primary_link_peer_by_id(
3940*5113495bSYour Name 						pr_soc,
3941*5113495bSYour Name 						mld_peer->peer_id,
3942*5113495bSYour Name 						DP_MOD_ID_HTT);
3943*5113495bSYour Name 	/* Making existing primary peer as non primary */
3944*5113495bSYour Name 	if (current_pr_peer) {
3945*5113495bSYour Name 		current_pr_peer->primary_link = 0;
3946*5113495bSYour Name 		dp_peer_unref_delete(current_pr_peer, DP_MOD_ID_HTT);
3947*5113495bSYour Name 	}
3948*5113495bSYour Name 
3949*5113495bSYour Name 	current_pr_soc = mld_peer->vdev->pdev->soc;
3950*5113495bSYour Name 	dp_peer_rx_reo_shared_qaddr_delete(current_pr_soc, mld_peer);
3951*5113495bSYour Name 
3952*5113495bSYour Name 	/* delete ast entry for current primary peer */
3953*5113495bSYour Name 	qdf_spin_lock_bh(&current_pr_soc->ast_lock);
3954*5113495bSYour Name 	ast_entry = dp_peer_ast_hash_find_soc_by_type(
3955*5113495bSYour Name 				current_pr_soc,
3956*5113495bSYour Name 				mld_peer->mac_addr.raw,
3957*5113495bSYour Name 				CDP_TXRX_AST_TYPE_MLD);
3958*5113495bSYour Name 	if (!ast_entry) {
3959*5113495bSYour Name 		dp_htt_err("Invalid ast entry");
3960*5113495bSYour Name 		qdf_spin_unlock_bh(&current_pr_soc->ast_lock);
3961*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3962*5113495bSYour Name 	}
3963*5113495bSYour Name 
3964*5113495bSYour Name 	hw_peer_id = ast_entry->ast_idx;
3965*5113495bSYour Name 	ast_hash = ast_entry->ast_hash_value;
3966*5113495bSYour Name 	dp_peer_unlink_ast_entry(current_pr_soc, ast_entry, mld_peer);
3967*5113495bSYour Name 
3968*5113495bSYour Name 	if (ast_entry->is_mapped)
3969*5113495bSYour Name 		current_pr_soc->ast_table[ast_entry->ast_idx] = NULL;
3970*5113495bSYour Name 
3971*5113495bSYour Name 	dp_peer_free_ast_entry(current_pr_soc, ast_entry);
3972*5113495bSYour Name 
3973*5113495bSYour Name 	mld_peer->self_ast_entry = NULL;
3974*5113495bSYour Name 	qdf_spin_unlock_bh(&current_pr_soc->ast_lock);
3975*5113495bSYour Name 
3976*5113495bSYour Name 	peer_info = qdf_mem_malloc(sizeof(struct dp_peer_info));
3977*5113495bSYour Name 	if (!peer_info) {
3978*5113495bSYour Name 		dp_htt_err("Malloc failed");
3979*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3980*5113495bSYour Name 	}
3981*5113495bSYour Name 
3982*5113495bSYour Name 	peer_info->primary_peer_id = peer_id;
3983*5113495bSYour Name 	peer_info->chip_id = chip_id;
3984*5113495bSYour Name 	peer_info->hw_peer_id = hw_peer_id;
3985*5113495bSYour Name 	peer_info->ast_hash = ast_hash;
3986*5113495bSYour Name 
3987*5113495bSYour Name 
3988*5113495bSYour Name 	for (i = 0; i < DP_MAX_TIDS; i++) {
3989*5113495bSYour Name 		rx_tid = &mld_peer->rx_tid[i];
3990*5113495bSYour Name 		if (!rx_tid)
3991*5113495bSYour Name 			continue;
3992*5113495bSYour Name 
3993*5113495bSYour Name 		qdf_mem_zero(&params, sizeof(params));
3994*5113495bSYour Name 		params.std.need_status = 1;
3995*5113495bSYour Name 		params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
3996*5113495bSYour Name 		params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
3997*5113495bSYour Name 
3998*5113495bSYour Name 		status = dp_reo_send_cmd(current_pr_soc, CMD_FLUSH_QUEUE, &params,
3999*5113495bSYour Name 					 NULL,NULL);
4000*5113495bSYour Name 	}
4001*5113495bSYour Name 
4002*5113495bSYour Name 	qdf_mem_zero(&params, sizeof(params));
4003*5113495bSYour Name 
4004*5113495bSYour Name 	rx_tid = &mld_peer->rx_tid[0];
4005*5113495bSYour Name 	params.std.need_status = 1;
4006*5113495bSYour Name 	params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
4007*5113495bSYour Name 	params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
4008*5113495bSYour Name 	params.u.fl_cache_params.flush_no_inval = 0;
4009*5113495bSYour Name 	params.u.fl_cache_params.flush_entire_cache = 1;
4010*5113495bSYour Name 	status = dp_reo_send_cmd(current_pr_soc, CMD_FLUSH_CACHE, &params,
4011*5113495bSYour Name 				 dp_primary_link_migration,
4012*5113495bSYour Name 				 (void *)peer_info);
4013*5113495bSYour Name 
4014*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
4015*5113495bSYour Name 		dp_htt_err("Reo flush failed");
4016*5113495bSYour Name 		qdf_mem_free(peer_info);
4017*5113495bSYour Name 		dp_h2t_ptqm_migration_msg_send(pr_soc, vdev_id, pdev_id,
4018*5113495bSYour Name 					       chip_id, peer_id, ml_peer_id,
4019*5113495bSYour Name 					       src_info, QDF_STATUS_E_FAILURE);
4020*5113495bSYour Name 	}
4021*5113495bSYour Name 
4022*5113495bSYour Name 	qdf_mem_zero(&params, sizeof(params));
4023*5113495bSYour Name 	params.std.need_status = 0;
4024*5113495bSYour Name 	params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
4025*5113495bSYour Name 	params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
4026*5113495bSYour Name 	params.u.unblk_cache_params.type = UNBLOCK_CACHE;
4027*5113495bSYour Name 	dp_reo_send_cmd(current_pr_soc, CMD_UNBLOCK_CACHE, &params, NULL, NULL);
4028*5113495bSYour Name 
4029*5113495bSYour Name 	dp_h2t_ptqm_migration_msg_send(pr_soc, vdev_id, pdev_id,
4030*5113495bSYour Name 				       chip_id, peer_id, ml_peer_id,
4031*5113495bSYour Name 				       src_info, QDF_STATUS_SUCCESS);
4032*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4033*5113495bSYour Name }
4034*5113495bSYour Name #endif
4035