1  /*
2   * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for
6   * any purpose with or without fee is hereby granted, provided that the
7   * above copyright notice and this permission notice appear in all
8   * copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17   * PERFORMANCE OF THIS SOFTWARE.
18   */
19  
20  #include <wlan_ipa_obj_mgmt_api.h>
21  #include <qdf_types.h>
22  #include <qdf_lock.h>
23  #include <qdf_net_types.h>
24  #include <qdf_lro.h>
25  #include <qdf_module.h>
26  #include <hal_hw_headers.h>
27  #include <hal_api.h>
28  #include <hif.h>
29  #include <htt.h>
30  #include <wdi_event.h>
31  #include <queue.h>
32  #include "dp_types.h"
33  #include "dp_rings.h"
34  #include "dp_internal.h"
35  #include "dp_tx.h"
36  #include "dp_tx_desc.h"
37  #include "dp_rx.h"
38  #ifdef DP_RATETABLE_SUPPORT
39  #include "dp_ratetable.h"
40  #endif
41  #include <cdp_txrx_handle.h>
42  #include <wlan_cfg.h>
43  #include <wlan_utility.h>
44  #include "cdp_txrx_cmn_struct.h"
45  #include "cdp_txrx_stats_struct.h"
46  #include "cdp_txrx_cmn_reg.h"
47  #include <qdf_util.h>
48  #include "dp_peer.h"
49  #include "htt_stats.h"
50  #include "dp_htt.h"
51  #ifdef WLAN_SUPPORT_RX_FISA
52  #include <wlan_dp_fisa_rx.h>
53  #endif
54  #include "htt_ppdu_stats.h"
55  #include "qdf_mem.h"   /* qdf_mem_malloc,free */
56  #include "cfg_ucfg_api.h"
57  #include <wlan_module_ids.h>
58  #ifdef QCA_MULTIPASS_SUPPORT
59  #include <enet.h>
60  #endif
61  
62  #ifdef QCA_LL_TX_FLOW_CONTROL_V2
63  #include "cdp_txrx_flow_ctrl_v2.h"
64  #else
65  
66  static inline void
cdp_dump_flow_pool_info(struct cdp_soc_t * soc)67  cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
68  {
69  	return;
70  }
71  #endif
72  #ifdef WIFI_MONITOR_SUPPORT
73  #include <dp_mon.h>
74  #endif
75  #include "dp_ipa.h"
76  #ifdef FEATURE_WDS
77  #include "dp_txrx_wds.h"
78  #endif
79  #ifdef WLAN_SUPPORT_MSCS
80  #include "dp_mscs.h"
81  #endif
82  #ifdef WLAN_SUPPORT_MESH_LATENCY
83  #include "dp_mesh_latency.h"
84  #endif
85  #ifdef WLAN_SUPPORT_SCS
86  #include "dp_scs.h"
87  #endif
88  #ifdef ATH_SUPPORT_IQUE
89  #include "dp_txrx_me.h"
90  #endif
91  #if defined(DP_CON_MON)
92  #ifndef REMOVE_PKT_LOG
93  #include <pktlog_ac_api.h>
94  #include <pktlog_ac.h>
95  #endif
96  #endif
97  #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
98  #include <wlan_dp_swlm.h>
99  #endif
100  #ifdef WLAN_DP_PROFILE_SUPPORT
101  #include <wlan_dp_main.h>
102  #endif
103  #ifdef CONFIG_SAWF_DEF_QUEUES
104  #include "dp_sawf.h"
105  #endif
106  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
107  #include "dp_rx_tag.h"
108  #endif
109  #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
110  #include <target_if_dp.h>
111  #endif
112  #include "qdf_ssr_driver_dump.h"
113  
114  #ifdef WLAN_SUPPORT_DPDK
115  #include <dp_dpdk.h>
116  #endif
117  
118  #ifdef QCA_DP_ENABLE_TX_COMP_RING4
119  #define TXCOMP_RING4_NUM 3
120  #else
121  #define TXCOMP_RING4_NUM WBM2SW_TXCOMP_RING4_NUM
122  #endif
123  
124  #if defined(DP_PEER_EXTENDED_API) || defined(WLAN_DP_PENDING_MEM_FLUSH)
125  #define SET_PEER_REF_CNT_ONE(_peer) \
126  	qdf_atomic_set(&(_peer)->ref_cnt, 1)
127  #else
128  #define SET_PEER_REF_CNT_ONE(_peer)
129  #endif
130  
131  #ifdef WLAN_SYSFS_DP_STATS
132  /* sysfs event wait time for firmware stat request unit milliseconds */
133  #define WLAN_SYSFS_STAT_REQ_WAIT_MS 3000
134  #endif
135  
136  #ifdef QCA_DP_TX_FW_METADATA_V2
137  #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val) \
138  		HTT_TX_TCL_METADATA_V2_PDEV_ID_SET(_var, _val)
139  #else
140  #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val) \
141  		HTT_TX_TCL_METADATA_PDEV_ID_SET(_var, _val)
142  #endif
143  #define MLD_MODE_INVALID 0xFF
144  
145  QDF_COMPILE_TIME_ASSERT(max_rx_rings_check,
146  			MAX_REO_DEST_RINGS == CDP_MAX_RX_RINGS);
147  
148  QDF_COMPILE_TIME_ASSERT(max_tx_rings_check,
149  			MAX_TCL_DATA_RINGS == CDP_MAX_TX_COMP_RINGS);
150  
151  void dp_configure_arch_ops(struct dp_soc *soc);
152  qdf_size_t dp_get_soc_context_size(uint16_t device_id);
153  
154  /*
155   * The max size of cdp_peer_stats_param_t is limited to 16 bytes.
156   * If the buffer size is exceeding this size limit,
157   * dp_txrx_get_peer_stats is to be used instead.
158   */
159  QDF_COMPILE_TIME_ASSERT(cdp_peer_stats_param_t_max_size,
160  			(sizeof(cdp_peer_stats_param_t) <= 16));
161  
162  #ifdef WLAN_FEATURE_DP_EVENT_HISTORY
163  /*
164   * If WLAN_CFG_INT_NUM_CONTEXTS is changed, HIF_NUM_INT_CONTEXTS
165   * also should be updated accordingly
166   */
167  QDF_COMPILE_TIME_ASSERT(num_intr_grps,
168  			HIF_NUM_INT_CONTEXTS == WLAN_CFG_INT_NUM_CONTEXTS);
169  
170  /*
171   * HIF_EVENT_HIST_MAX should always be power of 2
172   */
173  QDF_COMPILE_TIME_ASSERT(hif_event_history_size,
174  			(HIF_EVENT_HIST_MAX & (HIF_EVENT_HIST_MAX - 1)) == 0);
175  #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */
176  
177  /*
178   * If WLAN_CFG_INT_NUM_CONTEXTS is changed,
179   * WLAN_CFG_INT_NUM_CONTEXTS_MAX should also be updated
180   */
181  QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs,
182  			WLAN_CFG_INT_NUM_CONTEXTS_MAX >=
183  			WLAN_CFG_INT_NUM_CONTEXTS);
184  
185  static void dp_soc_unset_qref_debug_list(struct dp_soc *soc);
186  static QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl);
187  static QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl);
188  
189  static void dp_pdev_srng_deinit(struct dp_pdev *pdev);
190  static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev);
191  static void dp_pdev_srng_free(struct dp_pdev *pdev);
192  static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev);
193  
194  static inline
195  QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
196  				struct cdp_pdev_attach_params *params);
197  
198  static int dp_pdev_post_attach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id);
199  
200  static QDF_STATUS
201  dp_pdev_init_wifi3(struct cdp_soc_t *txrx_soc,
202  		   HTC_HANDLE htc_handle,
203  		   qdf_device_t qdf_osdev,
204  		   uint8_t pdev_id);
205  
206  static QDF_STATUS
207  dp_pdev_deinit_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id, int force);
208  
209  static void dp_soc_detach_wifi3(struct cdp_soc_t *txrx_soc);
210  static void dp_soc_deinit_wifi3(struct cdp_soc_t *txrx_soc);
211  
212  static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force);
213  static QDF_STATUS dp_pdev_detach_wifi3(struct cdp_soc_t *psoc,
214  				       uint8_t pdev_id,
215  				       int force);
216  static struct dp_soc *
217  dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
218  	      struct cdp_soc_attach_params *params);
219  static inline QDF_STATUS dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl,
220  					      uint8_t vdev_id,
221  					      uint8_t *peer_mac_addr,
222  					      enum cdp_peer_type peer_type);
223  static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
224  				       uint8_t vdev_id,
225  				       uint8_t *peer_mac, uint32_t bitmap,
226  				       enum cdp_peer_type peer_type);
227  static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle,
228  				bool unmap_only,
229  				bool mlo_peers_only);
230  #ifdef ENABLE_VERBOSE_DEBUG
231  bool is_dp_verbose_debug_enabled;
232  #endif
233  
234  #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
235  static bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
236  static void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
237  			   bool enable);
238  static inline void
239  dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
240  		     struct cdp_cfr_rcc_stats *cfr_rcc_stats);
241  static inline void
242  dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
243  #endif
244  
245  #ifdef DP_UMAC_HW_RESET_SUPPORT
246  static QDF_STATUS dp_umac_reset_action_trigger_recovery(struct dp_soc *soc);
247  static QDF_STATUS dp_umac_reset_handle_pre_reset(struct dp_soc *soc);
248  static QDF_STATUS dp_umac_reset_handle_post_reset(struct dp_soc *soc);
249  static QDF_STATUS dp_umac_reset_handle_post_reset_complete(struct dp_soc *soc);
250  #endif
251  
252  #define MON_VDEV_TIMER_INIT 0x1
253  #define MON_VDEV_TIMER_RUNNING 0x2
254  
255  #define DP_MCS_LENGTH (6*MAX_MCS)
256  
257  #define DP_CURR_FW_STATS_AVAIL 19
258  #define DP_HTT_DBG_EXT_STATS_MAX 256
259  #define DP_MAX_SLEEP_TIME 100
260  #ifndef QCA_WIFI_3_0_EMU
261  #define SUSPEND_DRAIN_WAIT 500
262  #else
263  #define SUSPEND_DRAIN_WAIT 3000
264  #endif
265  
266  #ifdef IPA_OFFLOAD
267  /* Exclude IPA rings from the interrupt context */
268  #define TX_RING_MASK_VAL	0xb
269  #define RX_RING_MASK_VAL	0x7
270  #else
271  #define TX_RING_MASK_VAL	0xF
272  #define RX_RING_MASK_VAL	0xF
273  #endif
274  
275  #define STR_MAXLEN	64
276  
277  #define RNG_ERR		"SRNG setup failed for"
278  
279  /**
280   * enum dp_stats_type - Select the type of statistics
281   * @STATS_FW: Firmware-based statistic
282   * @STATS_HOST: Host-based statistic
283   * @STATS_TYPE_MAX: maximum enumeration
284   */
285  enum dp_stats_type {
286  	STATS_FW = 0,
287  	STATS_HOST = 1,
288  	STATS_TYPE_MAX = 2,
289  };
290  
291  /**
292   * enum dp_fw_stats - General Firmware statistics options
293   * @TXRX_FW_STATS_INVALID: statistic is not available
294   */
295  enum dp_fw_stats {
296  	TXRX_FW_STATS_INVALID	= -1,
297  };
298  
299  /*
300   * dp_stats_mapping_table - Firmware and Host statistics
301   * currently supported
302   */
303  #ifndef WLAN_SOFTUMAC_SUPPORT
304  const int dp_stats_mapping_table[][STATS_TYPE_MAX] = {
305  	{HTT_DBG_EXT_STATS_RESET, TXRX_HOST_STATS_INVALID},
306  	{HTT_DBG_EXT_STATS_PDEV_TX, TXRX_HOST_STATS_INVALID},
307  	{HTT_DBG_EXT_STATS_PDEV_RX, TXRX_HOST_STATS_INVALID},
308  	{HTT_DBG_EXT_STATS_PDEV_TX_HWQ, TXRX_HOST_STATS_INVALID},
309  	{HTT_DBG_EXT_STATS_PDEV_TX_SCHED, TXRX_HOST_STATS_INVALID},
310  	{HTT_DBG_EXT_STATS_PDEV_ERROR, TXRX_HOST_STATS_INVALID},
311  	{HTT_DBG_EXT_STATS_PDEV_TQM, TXRX_HOST_STATS_INVALID},
312  	{HTT_DBG_EXT_STATS_TQM_CMDQ, TXRX_HOST_STATS_INVALID},
313  	{HTT_DBG_EXT_STATS_TX_DE_INFO, TXRX_HOST_STATS_INVALID},
314  	{HTT_DBG_EXT_STATS_PDEV_TX_RATE, TXRX_HOST_STATS_INVALID},
315  	{HTT_DBG_EXT_STATS_PDEV_RX_RATE, TXRX_HOST_STATS_INVALID},
316  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
317  	{HTT_DBG_EXT_STATS_TX_SELFGEN_INFO, TXRX_HOST_STATS_INVALID},
318  	{HTT_DBG_EXT_STATS_TX_MU_HWQ, TXRX_HOST_STATS_INVALID},
319  	{HTT_DBG_EXT_STATS_RING_IF_INFO, TXRX_HOST_STATS_INVALID},
320  	{HTT_DBG_EXT_STATS_SRNG_INFO, TXRX_HOST_STATS_INVALID},
321  	{HTT_DBG_EXT_STATS_SFM_INFO, TXRX_HOST_STATS_INVALID},
322  	{HTT_DBG_EXT_STATS_PDEV_TX_MU, TXRX_HOST_STATS_INVALID},
323  	{HTT_DBG_EXT_STATS_ACTIVE_PEERS_LIST, TXRX_HOST_STATS_INVALID},
324  	/* Last ENUM for HTT FW STATS */
325  	{DP_HTT_DBG_EXT_STATS_MAX, TXRX_HOST_STATS_INVALID},
326  	{TXRX_FW_STATS_INVALID, TXRX_CLEAR_STATS},
327  	{TXRX_FW_STATS_INVALID, TXRX_RX_RATE_STATS},
328  	{TXRX_FW_STATS_INVALID, TXRX_TX_RATE_STATS},
329  	{TXRX_FW_STATS_INVALID, TXRX_TX_HOST_STATS},
330  	{TXRX_FW_STATS_INVALID, TXRX_RX_HOST_STATS},
331  	{TXRX_FW_STATS_INVALID, TXRX_AST_STATS},
332  	{TXRX_FW_STATS_INVALID, TXRX_SRNG_PTR_STATS},
333  	{TXRX_FW_STATS_INVALID, TXRX_RX_MON_STATS},
334  	{TXRX_FW_STATS_INVALID, TXRX_REO_QUEUE_STATS},
335  	{TXRX_FW_STATS_INVALID, TXRX_SOC_CFG_PARAMS},
336  	{TXRX_FW_STATS_INVALID, TXRX_PDEV_CFG_PARAMS},
337  	{TXRX_FW_STATS_INVALID, TXRX_NAPI_STATS},
338  	{TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS},
339  	{TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS},
340  	{TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS},
341  	{TXRX_FW_STATS_INVALID, TXRX_SOC_REO_HW_DESC_DUMP},
342  	{TXRX_FW_STATS_INVALID, TXRX_SOC_WBM_IDLE_HPTP_DUMP},
343  	{TXRX_FW_STATS_INVALID, TXRX_SRNG_USAGE_WM_STATS},
344  	{HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, TXRX_HOST_STATS_INVALID},
345  	{HTT_DBG_EXT_STATS_TX_SOUNDING_INFO, TXRX_HOST_STATS_INVALID},
346  	{TXRX_FW_STATS_INVALID, TXRX_PEER_STATS},
347  };
348  #else
349  const int dp_stats_mapping_table[][STATS_TYPE_MAX] = {
350  	{HTT_DBG_EXT_STATS_RESET, TXRX_HOST_STATS_INVALID},
351  	{HTT_DBG_EXT_STATS_PDEV_TX, TXRX_HOST_STATS_INVALID},
352  	{HTT_DBG_EXT_STATS_PDEV_RX, TXRX_HOST_STATS_INVALID},
353  	{HTT_DBG_EXT_STATS_PDEV_TX_HWQ, TXRX_HOST_STATS_INVALID},
354  	{HTT_DBG_EXT_STATS_PDEV_TX_SCHED, TXRX_HOST_STATS_INVALID},
355  	{HTT_DBG_EXT_STATS_PDEV_ERROR, TXRX_HOST_STATS_INVALID},
356  	{HTT_DBG_EXT_STATS_PDEV_TQM, TXRX_HOST_STATS_INVALID},
357  	{HTT_DBG_EXT_STATS_TQM_CMDQ, TXRX_HOST_STATS_INVALID},
358  	{HTT_DBG_EXT_STATS_TX_DE_INFO, TXRX_HOST_STATS_INVALID},
359  	{HTT_DBG_EXT_STATS_PDEV_TX_RATE, TXRX_HOST_STATS_INVALID},
360  	{HTT_DBG_EXT_STATS_PDEV_RX_RATE, TXRX_HOST_STATS_INVALID},
361  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
362  	{HTT_DBG_EXT_STATS_TX_SELFGEN_INFO, TXRX_HOST_STATS_INVALID},
363  	{HTT_DBG_EXT_STATS_TX_MU_HWQ, TXRX_HOST_STATS_INVALID},
364  	{HTT_DBG_EXT_STATS_RING_IF_INFO, TXRX_HOST_STATS_INVALID},
365  	{HTT_DBG_EXT_STATS_SRNG_INFO, TXRX_HOST_STATS_INVALID},
366  	{HTT_DBG_EXT_STATS_SFM_INFO, TXRX_HOST_STATS_INVALID},
367  	{HTT_DBG_EXT_STATS_PDEV_TX_MU, TXRX_HOST_STATS_INVALID},
368  	{HTT_DBG_EXT_STATS_ACTIVE_PEERS_LIST, TXRX_HOST_STATS_INVALID},
369  	/* Last ENUM for HTT FW STATS */
370  	{DP_HTT_DBG_EXT_STATS_MAX, TXRX_HOST_STATS_INVALID},
371  	{TXRX_FW_STATS_INVALID, TXRX_CLEAR_STATS},
372  	{TXRX_FW_STATS_INVALID, TXRX_RX_RATE_STATS},
373  	{TXRX_FW_STATS_INVALID, TXRX_TX_RATE_STATS},
374  	{TXRX_FW_STATS_INVALID, TXRX_TX_HOST_STATS},
375  	{TXRX_FW_STATS_INVALID, TXRX_RX_HOST_STATS},
376  	{TXRX_FW_STATS_INVALID, TXRX_AST_STATS},
377  	{TXRX_FW_STATS_INVALID, TXRX_SRNG_PTR_STATS},
378  	{TXRX_FW_STATS_INVALID, TXRX_RX_MON_STATS},
379  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
380  	{TXRX_FW_STATS_INVALID, TXRX_SOC_CFG_PARAMS},
381  	{TXRX_FW_STATS_INVALID, TXRX_PDEV_CFG_PARAMS},
382  	{TXRX_FW_STATS_INVALID, TXRX_NAPI_STATS},
383  	{TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS},
384  	{TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS},
385  	{TXRX_FW_STATS_INVALID, TXRX_HAL_REG_WRITE_STATS},
386  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
387  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
388  	{TXRX_FW_STATS_INVALID, TXRX_HOST_STATS_INVALID},
389  	{HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, TXRX_HOST_STATS_INVALID},
390  	{HTT_DBG_EXT_STATS_TX_SOUNDING_INFO, TXRX_HOST_STATS_INVALID}
391  };
392  #endif
393  
394  /* MCL specific functions */
395  #if defined(DP_CON_MON)
396  
397  #ifdef IPA_OFFLOAD
398  /**
399   * dp_get_num_rx_contexts() - get number of RX contexts
400   * @soc_hdl: cdp opaque soc handle
401   *
402   * Return: number of RX contexts
403   */
dp_get_num_rx_contexts(struct cdp_soc_t * soc_hdl)404  static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl)
405  {
406  	int num_rx_contexts;
407  	uint32_t reo_ring_map;
408  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
409  
410  	reo_ring_map = wlan_cfg_get_reo_rings_mapping(soc->wlan_cfg_ctx);
411  
412  	switch (soc->arch_id) {
413  	case CDP_ARCH_TYPE_BE:
414  		/* 2 REO rings are used for IPA */
415  		reo_ring_map &=  ~(BIT(3) | BIT(7));
416  
417  		break;
418  	case CDP_ARCH_TYPE_LI:
419  		/* 1 REO ring is used for IPA */
420  		reo_ring_map &=  ~BIT(3);
421  		break;
422  	default:
423  		dp_err("unknown arch_id 0x%x", soc->arch_id);
424  		QDF_BUG(0);
425  	}
426  	/*
427  	 * qdf_get_hweight32 prefer over qdf_get_hweight8 in case map is scaled
428  	 * in future
429  	 */
430  	num_rx_contexts = qdf_get_hweight32(reo_ring_map);
431  
432  	return num_rx_contexts;
433  }
434  #else
435  #ifdef WLAN_SOFTUMAC_SUPPORT
dp_get_num_rx_contexts(struct cdp_soc_t * soc_hdl)436  static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl)
437  {
438  	uint32_t rx_rings_config;
439  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
440  
441  	rx_rings_config = wlan_cfg_get_rx_rings_mapping(soc->wlan_cfg_ctx);
442  	/*
443  	 * qdf_get_hweight32 prefer over qdf_get_hweight8 in case map is scaled
444  	 * in future
445  	 */
446  	return qdf_get_hweight32(rx_rings_config);
447  }
448  #else
dp_get_num_rx_contexts(struct cdp_soc_t * soc_hdl)449  static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl)
450  {
451  	int num_rx_contexts;
452  	uint32_t reo_config;
453  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
454  
455  	reo_config = wlan_cfg_get_reo_rings_mapping(soc->wlan_cfg_ctx);
456  	/*
457  	 * qdf_get_hweight32 prefer over qdf_get_hweight8 in case map is scaled
458  	 * in future
459  	 */
460  	num_rx_contexts = qdf_get_hweight32(reo_config);
461  
462  	return num_rx_contexts;
463  }
464  #endif /* WLAN_SOFTUMAC_SUPPORT */
465  #endif
466  
467  #endif
468  
469  #ifdef FEATURE_MEC
dp_peer_mec_flush_entries(struct dp_soc * soc)470  void dp_peer_mec_flush_entries(struct dp_soc *soc)
471  {
472  	unsigned int index;
473  	struct dp_mec_entry *mecentry, *mecentry_next;
474  
475  	TAILQ_HEAD(, dp_mec_entry) free_list;
476  	TAILQ_INIT(&free_list);
477  
478  	if (!soc->mec_hash.mask)
479  		return;
480  
481  	if (!soc->mec_hash.bins)
482  		return;
483  
484  	if (!qdf_atomic_read(&soc->mec_cnt))
485  		return;
486  
487  	qdf_spin_lock_bh(&soc->mec_lock);
488  	for (index = 0; index <= soc->mec_hash.mask; index++) {
489  		if (!TAILQ_EMPTY(&soc->mec_hash.bins[index])) {
490  			TAILQ_FOREACH_SAFE(mecentry, &soc->mec_hash.bins[index],
491  					   hash_list_elem, mecentry_next) {
492  			    dp_peer_mec_detach_entry(soc, mecentry, &free_list);
493  			}
494  		}
495  	}
496  	qdf_spin_unlock_bh(&soc->mec_lock);
497  
498  	dp_peer_mec_free_list(soc, &free_list);
499  }
500  
501  /**
502   * dp_print_mec_stats() - Dump MEC entries in table
503   * @soc: Datapath soc handle
504   *
505   * Return: none
506   */
dp_print_mec_stats(struct dp_soc * soc)507  static void dp_print_mec_stats(struct dp_soc *soc)
508  {
509  	int i;
510  	uint32_t index;
511  	struct dp_mec_entry *mecentry = NULL, *mec_list;
512  	uint32_t num_entries = 0;
513  
514  	DP_PRINT_STATS("MEC Stats:");
515  	DP_PRINT_STATS("   Entries Added   = %d", soc->stats.mec.added);
516  	DP_PRINT_STATS("   Entries Deleted = %d", soc->stats.mec.deleted);
517  
518  	if (!qdf_atomic_read(&soc->mec_cnt))
519  		return;
520  
521  	mec_list = qdf_mem_malloc(sizeof(*mecentry) * DP_PEER_MAX_MEC_ENTRY);
522  	if (!mec_list) {
523  		dp_peer_warn("%pK: failed to allocate mec_list", soc);
524  		return;
525  	}
526  
527  	DP_PRINT_STATS("MEC Table:");
528  	for (index = 0; index <= soc->mec_hash.mask; index++) {
529  		qdf_spin_lock_bh(&soc->mec_lock);
530  		if (TAILQ_EMPTY(&soc->mec_hash.bins[index])) {
531  			qdf_spin_unlock_bh(&soc->mec_lock);
532  			continue;
533  		}
534  
535  		TAILQ_FOREACH(mecentry, &soc->mec_hash.bins[index],
536  			      hash_list_elem) {
537  			qdf_mem_copy(&mec_list[num_entries], mecentry,
538  				     sizeof(*mecentry));
539  			num_entries++;
540  		}
541  		qdf_spin_unlock_bh(&soc->mec_lock);
542  	}
543  
544  	if (!num_entries) {
545  		qdf_mem_free(mec_list);
546  		return;
547  	}
548  
549  	for (i = 0; i < num_entries; i++) {
550  		DP_PRINT_STATS("%6d mac_addr = " QDF_MAC_ADDR_FMT
551  			       " is_active = %d pdev_id = %d vdev_id = %d",
552  			       i,
553  			       QDF_MAC_ADDR_REF(mec_list[i].mac_addr.raw),
554  			       mec_list[i].is_active,
555  			       mec_list[i].pdev_id,
556  			       mec_list[i].vdev_id);
557  	}
558  	qdf_mem_free(mec_list);
559  }
560  #else
dp_print_mec_stats(struct dp_soc * soc)561  static void dp_print_mec_stats(struct dp_soc *soc)
562  {
563  }
564  #endif
565  
dp_peer_add_ast_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,uint8_t * mac_addr,enum cdp_txrx_ast_entry_type type,uint32_t flags)566  static int dp_peer_add_ast_wifi3(struct cdp_soc_t *soc_hdl,
567  				 uint8_t vdev_id,
568  				 uint8_t *peer_mac,
569  				 uint8_t *mac_addr,
570  				 enum cdp_txrx_ast_entry_type type,
571  				 uint32_t flags)
572  {
573  	int ret = -1;
574  	QDF_STATUS status = QDF_STATUS_SUCCESS;
575  	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl,
576  						       peer_mac, 0, vdev_id,
577  						       DP_MOD_ID_CDP);
578  
579  	if (!peer) {
580  		dp_peer_debug("Peer is NULL!");
581  		return ret;
582  	}
583  
584  	status = dp_peer_add_ast((struct dp_soc *)soc_hdl,
585  				 peer,
586  				 mac_addr,
587  				 type,
588  				 flags);
589  	if ((status == QDF_STATUS_SUCCESS) ||
590  	    (status == QDF_STATUS_E_ALREADY) ||
591  	    (status == QDF_STATUS_E_AGAIN))
592  		ret = 0;
593  
594  	dp_hmwds_ast_add_notify(peer, mac_addr,
595  				type, status, false);
596  
597  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
598  
599  	return ret;
600  }
601  
dp_peer_update_ast_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,uint8_t * wds_macaddr,uint32_t flags)602  static int dp_peer_update_ast_wifi3(struct cdp_soc_t *soc_hdl,
603  						uint8_t vdev_id,
604  						uint8_t *peer_mac,
605  						uint8_t *wds_macaddr,
606  						uint32_t flags)
607  {
608  	int status = -1;
609  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
610  	struct dp_ast_entry  *ast_entry = NULL;
611  	struct dp_peer *peer;
612  
613  	if (soc->ast_offload_support)
614  		return status;
615  
616  	peer = dp_peer_find_hash_find((struct dp_soc *)soc_hdl,
617  				      peer_mac, 0, vdev_id,
618  				      DP_MOD_ID_CDP);
619  
620  	if (!peer) {
621  		dp_peer_debug("Peer is NULL!");
622  		return status;
623  	}
624  
625  	qdf_spin_lock_bh(&soc->ast_lock);
626  	ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr,
627  						    peer->vdev->pdev->pdev_id);
628  
629  	if (ast_entry) {
630  		status = dp_peer_update_ast(soc,
631  					    peer,
632  					    ast_entry, flags);
633  	}
634  	qdf_spin_unlock_bh(&soc->ast_lock);
635  
636  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
637  
638  	return status;
639  }
640  
641  /**
642   * dp_peer_reset_ast_entries() - Deletes all HMWDS entries for a peer
643   * @soc:		Datapath SOC handle
644   * @peer:		DP peer
645   * @arg:		callback argument
646   *
647   * Return: None
648   */
649  static void
dp_peer_reset_ast_entries(struct dp_soc * soc,struct dp_peer * peer,void * arg)650  dp_peer_reset_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg)
651  {
652  	struct dp_ast_entry *ast_entry = NULL;
653  	struct dp_ast_entry *tmp_ast_entry;
654  
655  	DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, tmp_ast_entry) {
656  		if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) ||
657  		    (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC))
658  			dp_peer_del_ast(soc, ast_entry);
659  	}
660  }
661  
662  /**
663   * dp_wds_reset_ast_wifi3() - Reset the is_active param for ast entry
664   * @soc_hdl:		Datapath SOC handle
665   * @wds_macaddr:	WDS entry MAC Address
666   * @peer_mac_addr:	WDS entry MAC Address
667   * @vdev_id:		id of vdev handle
668   *
669   * Return: QDF_STATUS
670   */
dp_wds_reset_ast_wifi3(struct cdp_soc_t * soc_hdl,uint8_t * wds_macaddr,uint8_t * peer_mac_addr,uint8_t vdev_id)671  static QDF_STATUS dp_wds_reset_ast_wifi3(struct cdp_soc_t *soc_hdl,
672  					 uint8_t *wds_macaddr,
673  					 uint8_t *peer_mac_addr,
674  					 uint8_t vdev_id)
675  {
676  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
677  	struct dp_ast_entry *ast_entry = NULL;
678  	struct dp_peer *peer;
679  	struct dp_pdev *pdev;
680  	struct dp_vdev *vdev;
681  
682  	if (soc->ast_offload_support)
683  		return QDF_STATUS_E_FAILURE;
684  
685  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
686  
687  	if (!vdev)
688  		return QDF_STATUS_E_FAILURE;
689  
690  	pdev = vdev->pdev;
691  
692  	if (peer_mac_addr) {
693  		peer = dp_peer_find_hash_find(soc, peer_mac_addr,
694  					      0, vdev->vdev_id,
695  					      DP_MOD_ID_CDP);
696  		if (!peer) {
697  			dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
698  			return QDF_STATUS_E_FAILURE;
699  		}
700  
701  		qdf_spin_lock_bh(&soc->ast_lock);
702  		dp_peer_reset_ast_entries(soc, peer, NULL);
703  		qdf_spin_unlock_bh(&soc->ast_lock);
704  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
705  	} else if (wds_macaddr) {
706  		qdf_spin_lock_bh(&soc->ast_lock);
707  		ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, wds_macaddr,
708  							    pdev->pdev_id);
709  
710  		if (ast_entry) {
711  			if ((ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM) ||
712  			    (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC))
713  				dp_peer_del_ast(soc, ast_entry);
714  		}
715  		qdf_spin_unlock_bh(&soc->ast_lock);
716  	}
717  
718  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
719  	return QDF_STATUS_SUCCESS;
720  }
721  
722  /**
723   * dp_wds_reset_ast_table_wifi3() - Reset the is_active param for all ast entry
724   * @soc_hdl:		Datapath SOC handle
725   * @vdev_id:		id of vdev object
726   *
727   * Return: QDF_STATUS
728   */
729  static QDF_STATUS
dp_wds_reset_ast_table_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)730  dp_wds_reset_ast_table_wifi3(struct cdp_soc_t  *soc_hdl,
731  			     uint8_t vdev_id)
732  {
733  	struct dp_soc *soc = (struct dp_soc *) soc_hdl;
734  
735  	if (soc->ast_offload_support)
736  		return QDF_STATUS_SUCCESS;
737  
738  	qdf_spin_lock_bh(&soc->ast_lock);
739  
740  	dp_soc_iterate_peer(soc, dp_peer_reset_ast_entries, NULL,
741  			    DP_MOD_ID_CDP);
742  	qdf_spin_unlock_bh(&soc->ast_lock);
743  
744  	return QDF_STATUS_SUCCESS;
745  }
746  
747  /**
748   * dp_peer_flush_ast_entries() - Delete all wds and hmwds ast entries of a peer
749   * @soc:		Datapath SOC
750   * @peer:		Datapath peer
751   * @arg:		arg to callback
752   *
753   * Return: None
754   */
755  static void
dp_peer_flush_ast_entries(struct dp_soc * soc,struct dp_peer * peer,void * arg)756  dp_peer_flush_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg)
757  {
758  	struct dp_ast_entry *ase = NULL;
759  	struct dp_ast_entry *temp_ase;
760  
761  	DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) {
762  		if ((ase->type ==
763  			CDP_TXRX_AST_TYPE_STATIC) ||
764  			(ase->type ==
765  			 CDP_TXRX_AST_TYPE_SELF) ||
766  			(ase->type ==
767  			 CDP_TXRX_AST_TYPE_STA_BSS))
768  			continue;
769  		dp_peer_del_ast(soc, ase);
770  	}
771  }
772  
773  /**
774   * dp_wds_flush_ast_table_wifi3() - Delete all wds and hmwds ast entry
775   * @soc_hdl:		Datapath SOC handle
776   *
777   * Return: None
778   */
dp_wds_flush_ast_table_wifi3(struct cdp_soc_t * soc_hdl)779  static void dp_wds_flush_ast_table_wifi3(struct cdp_soc_t  *soc_hdl)
780  {
781  	struct dp_soc *soc = (struct dp_soc *) soc_hdl;
782  
783  	qdf_spin_lock_bh(&soc->ast_lock);
784  
785  	dp_soc_iterate_peer(soc, dp_peer_flush_ast_entries, NULL,
786  			    DP_MOD_ID_CDP);
787  
788  	qdf_spin_unlock_bh(&soc->ast_lock);
789  	dp_peer_mec_flush_entries(soc);
790  }
791  
792  #if defined(IPA_WDS_EASYMESH_FEATURE) && defined(FEATURE_AST)
793  /**
794   * dp_peer_send_wds_disconnect() - Send Disconnect event to IPA for each peer
795   * @soc: Datapath SOC
796   * @peer: Datapath peer
797   *
798   * Return: None
799   */
800  static void
dp_peer_send_wds_disconnect(struct dp_soc * soc,struct dp_peer * peer)801  dp_peer_send_wds_disconnect(struct dp_soc *soc, struct dp_peer *peer)
802  {
803  	struct dp_ast_entry *ase = NULL;
804  	struct dp_ast_entry *temp_ase;
805  
806  	DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) {
807  		if (ase->type == CDP_TXRX_AST_TYPE_WDS) {
808  			soc->cdp_soc.ol_ops->peer_send_wds_disconnect(soc->ctrl_psoc,
809  								      ase->mac_addr.raw,
810  								      ase->vdev_id);
811  		}
812  	}
813  }
814  #elif defined(FEATURE_AST)
815  static void
dp_peer_send_wds_disconnect(struct dp_soc * soc,struct dp_peer * peer)816  dp_peer_send_wds_disconnect(struct dp_soc *soc, struct dp_peer *peer)
817  {
818  }
819  #endif
820  
821  /**
822   * dp_peer_check_ast_offload() - check ast offload support is enable or not
823   * @soc: soc handle
824   *
825   * Return: false in case of IPA and true/false in IPQ case
826   *
827   */
828  #if defined(IPA_OFFLOAD) && defined(QCA_WIFI_QCN9224)
dp_peer_check_ast_offload(struct dp_soc * soc)829  static inline bool dp_peer_check_ast_offload(struct dp_soc *soc)
830  {
831  	return false;
832  }
833  #else
dp_peer_check_ast_offload(struct dp_soc * soc)834  static inline bool dp_peer_check_ast_offload(struct dp_soc *soc)
835  {
836  	if (soc->ast_offload_support)
837  		return true;
838  
839  	return false;
840  }
841  #endif
842  
843  /**
844   * dp_peer_get_ast_info_by_soc_wifi3() - search the soc AST hash table
845   *                                       and return ast entry information
846   *                                       of first ast entry found in the
847   *                                       table with given mac address
848   * @soc_hdl: data path soc handle
849   * @ast_mac_addr: AST entry mac address
850   * @ast_entry_info: ast entry information
851   *
852   * Return: true if ast entry found with ast_mac_addr
853   *          false if ast entry not found
854   */
dp_peer_get_ast_info_by_soc_wifi3(struct cdp_soc_t * soc_hdl,uint8_t * ast_mac_addr,struct cdp_ast_entry_info * ast_entry_info)855  static bool dp_peer_get_ast_info_by_soc_wifi3
856  	(struct cdp_soc_t *soc_hdl,
857  	 uint8_t *ast_mac_addr,
858  	 struct cdp_ast_entry_info *ast_entry_info)
859  {
860  	struct dp_ast_entry *ast_entry = NULL;
861  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
862  	struct dp_peer *peer = NULL;
863  
864  	if (dp_peer_check_ast_offload(soc))
865  		return false;
866  
867  	qdf_spin_lock_bh(&soc->ast_lock);
868  
869  	ast_entry = dp_peer_ast_hash_find_soc(soc, ast_mac_addr);
870  	if ((!ast_entry) ||
871  	    (ast_entry->delete_in_progress && !ast_entry->callback)) {
872  		qdf_spin_unlock_bh(&soc->ast_lock);
873  		return false;
874  	}
875  
876  	peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
877  				     DP_MOD_ID_AST);
878  	if (!peer) {
879  		qdf_spin_unlock_bh(&soc->ast_lock);
880  		return false;
881  	}
882  
883  	ast_entry_info->type = ast_entry->type;
884  	ast_entry_info->pdev_id = ast_entry->pdev_id;
885  	ast_entry_info->vdev_id = ast_entry->vdev_id;
886  	ast_entry_info->peer_id = ast_entry->peer_id;
887  	qdf_mem_copy(&ast_entry_info->peer_mac_addr[0],
888  		     &peer->mac_addr.raw[0],
889  		     QDF_MAC_ADDR_SIZE);
890  	dp_peer_unref_delete(peer, DP_MOD_ID_AST);
891  	qdf_spin_unlock_bh(&soc->ast_lock);
892  	return true;
893  }
894  
895  /**
896   * dp_peer_get_ast_info_by_pdevid_wifi3() - search the soc AST hash table
897   *                                          and return ast entry information
898   *                                          if mac address and pdev_id matches
899   * @soc_hdl: data path soc handle
900   * @ast_mac_addr: AST entry mac address
901   * @pdev_id: pdev_id
902   * @ast_entry_info: ast entry information
903   *
904   * Return: true if ast entry found with ast_mac_addr
905   *          false if ast entry not found
906   */
dp_peer_get_ast_info_by_pdevid_wifi3(struct cdp_soc_t * soc_hdl,uint8_t * ast_mac_addr,uint8_t pdev_id,struct cdp_ast_entry_info * ast_entry_info)907  static bool dp_peer_get_ast_info_by_pdevid_wifi3
908  		(struct cdp_soc_t *soc_hdl,
909  		 uint8_t *ast_mac_addr,
910  		 uint8_t pdev_id,
911  		 struct cdp_ast_entry_info *ast_entry_info)
912  {
913  	struct dp_ast_entry *ast_entry;
914  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
915  	struct dp_peer *peer = NULL;
916  
917  	if (soc->ast_offload_support)
918  		return false;
919  
920  	qdf_spin_lock_bh(&soc->ast_lock);
921  
922  	ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, ast_mac_addr,
923  						    pdev_id);
924  
925  	if ((!ast_entry) ||
926  	    (ast_entry->delete_in_progress && !ast_entry->callback)) {
927  		qdf_spin_unlock_bh(&soc->ast_lock);
928  		return false;
929  	}
930  
931  	peer = dp_peer_get_ref_by_id(soc, ast_entry->peer_id,
932  				     DP_MOD_ID_AST);
933  	if (!peer) {
934  		qdf_spin_unlock_bh(&soc->ast_lock);
935  		return false;
936  	}
937  
938  	ast_entry_info->type = ast_entry->type;
939  	ast_entry_info->pdev_id = ast_entry->pdev_id;
940  	ast_entry_info->vdev_id = ast_entry->vdev_id;
941  	ast_entry_info->peer_id = ast_entry->peer_id;
942  	qdf_mem_copy(&ast_entry_info->peer_mac_addr[0],
943  		     &peer->mac_addr.raw[0],
944  		     QDF_MAC_ADDR_SIZE);
945  	dp_peer_unref_delete(peer, DP_MOD_ID_AST);
946  	qdf_spin_unlock_bh(&soc->ast_lock);
947  	return true;
948  }
949  
950  /**
951   * dp_peer_ast_entry_del_by_soc() - delete the ast entry from soc AST hash table
952   *                            with given mac address
953   * @soc_handle: data path soc handle
954   * @mac_addr: AST entry mac address
955   * @callback: callback function to called on ast delete response from FW
956   * @cookie: argument to be passed to callback
957   *
958   * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete
959   *          is sent
960   *          QDF_STATUS_E_INVAL false if ast entry not found
961   */
dp_peer_ast_entry_del_by_soc(struct cdp_soc_t * soc_handle,uint8_t * mac_addr,txrx_ast_free_cb callback,void * cookie)962  static QDF_STATUS dp_peer_ast_entry_del_by_soc(struct cdp_soc_t *soc_handle,
963  					       uint8_t *mac_addr,
964  					       txrx_ast_free_cb callback,
965  					       void *cookie)
966  
967  {
968  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
969  	struct dp_ast_entry *ast_entry = NULL;
970  	txrx_ast_free_cb cb = NULL;
971  	void *arg = NULL;
972  
973  	if (soc->ast_offload_support)
974  		return -QDF_STATUS_E_INVAL;
975  
976  	qdf_spin_lock_bh(&soc->ast_lock);
977  	ast_entry = dp_peer_ast_hash_find_soc(soc, mac_addr);
978  	if (!ast_entry) {
979  		qdf_spin_unlock_bh(&soc->ast_lock);
980  		return -QDF_STATUS_E_INVAL;
981  	}
982  
983  	if (ast_entry->callback) {
984  		cb = ast_entry->callback;
985  		arg = ast_entry->cookie;
986  	}
987  
988  	ast_entry->callback = callback;
989  	ast_entry->cookie = cookie;
990  
991  	/*
992  	 * if delete_in_progress is set AST delete is sent to target
993  	 * and host is waiting for response should not send delete
994  	 * again
995  	 */
996  	if (!ast_entry->delete_in_progress)
997  		dp_peer_del_ast(soc, ast_entry);
998  
999  	qdf_spin_unlock_bh(&soc->ast_lock);
1000  	if (cb) {
1001  		cb(soc->ctrl_psoc,
1002  		   dp_soc_to_cdp_soc(soc),
1003  		   arg,
1004  		   CDP_TXRX_AST_DELETE_IN_PROGRESS);
1005  	}
1006  	return QDF_STATUS_SUCCESS;
1007  }
1008  
1009  /**
1010   * dp_peer_ast_entry_del_by_pdev() - delete the ast entry from soc AST hash
1011   *                                   table if mac address and pdev_id matches
1012   * @soc_handle: data path soc handle
1013   * @mac_addr: AST entry mac address
1014   * @pdev_id: pdev id
1015   * @callback: callback function to called on ast delete response from FW
1016   * @cookie: argument to be passed to callback
1017   *
1018   * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete
1019   *          is sent
1020   *          QDF_STATUS_E_INVAL false if ast entry not found
1021   */
1022  
dp_peer_ast_entry_del_by_pdev(struct cdp_soc_t * soc_handle,uint8_t * mac_addr,uint8_t pdev_id,txrx_ast_free_cb callback,void * cookie)1023  static QDF_STATUS dp_peer_ast_entry_del_by_pdev(struct cdp_soc_t *soc_handle,
1024  						uint8_t *mac_addr,
1025  						uint8_t pdev_id,
1026  						txrx_ast_free_cb callback,
1027  						void *cookie)
1028  
1029  {
1030  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
1031  	struct dp_ast_entry *ast_entry;
1032  	txrx_ast_free_cb cb = NULL;
1033  	void *arg = NULL;
1034  
1035  	if (soc->ast_offload_support)
1036  		return -QDF_STATUS_E_INVAL;
1037  
1038  	qdf_spin_lock_bh(&soc->ast_lock);
1039  	ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, mac_addr, pdev_id);
1040  
1041  	if (!ast_entry) {
1042  		qdf_spin_unlock_bh(&soc->ast_lock);
1043  		return -QDF_STATUS_E_INVAL;
1044  	}
1045  
1046  	if (ast_entry->callback) {
1047  		cb = ast_entry->callback;
1048  		arg = ast_entry->cookie;
1049  	}
1050  
1051  	ast_entry->callback = callback;
1052  	ast_entry->cookie = cookie;
1053  
1054  	/*
1055  	 * if delete_in_progress is set AST delete is sent to target
1056  	 * and host is waiting for response should not sent delete
1057  	 * again
1058  	 */
1059  	if (!ast_entry->delete_in_progress)
1060  		dp_peer_del_ast(soc, ast_entry);
1061  
1062  	qdf_spin_unlock_bh(&soc->ast_lock);
1063  
1064  	if (cb) {
1065  		cb(soc->ctrl_psoc,
1066  		   dp_soc_to_cdp_soc(soc),
1067  		   arg,
1068  		   CDP_TXRX_AST_DELETE_IN_PROGRESS);
1069  	}
1070  	return QDF_STATUS_SUCCESS;
1071  }
1072  
1073  /**
1074   * dp_peer_HMWDS_ast_entry_del() - delete the ast entry from soc AST hash
1075   *                                 table if HMWDS rem-addr command is issued
1076   *
1077   * @soc_handle: data path soc handle
1078   * @vdev_id: vdev id
1079   * @wds_macaddr: AST entry mac address to delete
1080   * @type: cdp_txrx_ast_entry_type to send to FW
1081   * @delete_in_fw: flag to indicate AST entry deletion in FW
1082   *
1083   * Return: QDF_STATUS_SUCCESS if ast entry found with ast_mac_addr and delete
1084   *         is sent
1085   *         QDF_STATUS_E_INVAL false if ast entry not found
1086   */
dp_peer_HMWDS_ast_entry_del(struct cdp_soc_t * soc_handle,uint8_t vdev_id,uint8_t * wds_macaddr,uint8_t type,uint8_t delete_in_fw)1087  static QDF_STATUS dp_peer_HMWDS_ast_entry_del(struct cdp_soc_t *soc_handle,
1088  					      uint8_t vdev_id,
1089  					      uint8_t *wds_macaddr,
1090  					      uint8_t type,
1091  					      uint8_t delete_in_fw)
1092  {
1093  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
1094  
1095  	if (soc->ast_offload_support) {
1096  		dp_del_wds_entry_wrapper(soc, vdev_id, wds_macaddr, type,
1097  					 delete_in_fw);
1098  		return QDF_STATUS_SUCCESS;
1099  	}
1100  
1101  	return -QDF_STATUS_E_INVAL;
1102  }
1103  
1104  #ifdef FEATURE_AST
1105  /**
1106   * dp_print_mlo_ast_stats() - Print AST stats for MLO peers
1107   *
1108   * @soc: core DP soc context
1109   *
1110   * Return: void
1111   */
dp_print_mlo_ast_stats(struct dp_soc * soc)1112  static void dp_print_mlo_ast_stats(struct dp_soc *soc)
1113  {
1114  	if (soc->arch_ops.print_mlo_ast_stats)
1115  		soc->arch_ops.print_mlo_ast_stats(soc);
1116  }
1117  
1118  void
dp_print_peer_ast_entries(struct dp_soc * soc,struct dp_peer * peer,void * arg)1119  dp_print_peer_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg)
1120  {
1121  	struct dp_ast_entry *ase, *tmp_ase;
1122  	uint32_t num_entries = 0;
1123  	char type[CDP_TXRX_AST_TYPE_MAX][10] = {
1124  			"NONE", "STATIC", "SELF", "WDS", "HMWDS", "BSS",
1125  			"DA", "HMWDS_SEC", "MLD"};
1126  
1127  	DP_PEER_ITERATE_ASE_LIST(peer, ase, tmp_ase) {
1128  	    DP_PRINT_STATS("%6d mac_addr = "QDF_MAC_ADDR_FMT
1129  		    " peer_mac_addr = "QDF_MAC_ADDR_FMT
1130  		    " peer_id = %u"
1131  		    " type = %s"
1132  		    " next_hop = %d"
1133  		    " is_active = %d"
1134  		    " ast_idx = %d"
1135  		    " ast_hash = %d"
1136  		    " delete_in_progress = %d"
1137  		    " pdev_id = %d"
1138  		    " vdev_id = %d",
1139  		    ++num_entries,
1140  		    QDF_MAC_ADDR_REF(ase->mac_addr.raw),
1141  		    QDF_MAC_ADDR_REF(peer->mac_addr.raw),
1142  		    ase->peer_id,
1143  		    type[ase->type],
1144  		    ase->next_hop,
1145  		    ase->is_active,
1146  		    ase->ast_idx,
1147  		    ase->ast_hash_value,
1148  		    ase->delete_in_progress,
1149  		    ase->pdev_id,
1150  		    ase->vdev_id);
1151  	}
1152  }
1153  
dp_print_ast_stats(struct dp_soc * soc)1154  void dp_print_ast_stats(struct dp_soc *soc)
1155  {
1156  	DP_PRINT_STATS("AST Stats:");
1157  	DP_PRINT_STATS("	Entries Added   = %d", soc->stats.ast.added);
1158  	DP_PRINT_STATS("	Entries Deleted = %d", soc->stats.ast.deleted);
1159  	DP_PRINT_STATS("	Entries Agedout = %d", soc->stats.ast.aged_out);
1160  	DP_PRINT_STATS("	Entries MAP ERR  = %d", soc->stats.ast.map_err);
1161  	DP_PRINT_STATS("	Entries Mismatch ERR  = %d",
1162  		       soc->stats.ast.ast_mismatch);
1163  
1164  	DP_PRINT_STATS("AST Table:");
1165  
1166  	qdf_spin_lock_bh(&soc->ast_lock);
1167  
1168  	dp_soc_iterate_peer(soc, dp_print_peer_ast_entries, NULL,
1169  			    DP_MOD_ID_GENERIC_STATS);
1170  
1171  	qdf_spin_unlock_bh(&soc->ast_lock);
1172  
1173  	dp_print_mlo_ast_stats(soc);
1174  }
1175  #else
dp_print_ast_stats(struct dp_soc * soc)1176  void dp_print_ast_stats(struct dp_soc *soc)
1177  {
1178  	DP_PRINT_STATS("AST Stats not available.Enable FEATURE_AST");
1179  	return;
1180  }
1181  #endif
1182  
1183  /**
1184   * dp_print_peer_info() - Dump peer info
1185   * @soc: Datapath soc handle
1186   * @peer: Datapath peer handle
1187   * @arg: argument to iter function
1188   *
1189   * Return: void
1190   */
1191  static void
dp_print_peer_info(struct dp_soc * soc,struct dp_peer * peer,void * arg)1192  dp_print_peer_info(struct dp_soc *soc, struct dp_peer *peer, void *arg)
1193  {
1194  	struct dp_txrx_peer *txrx_peer = NULL;
1195  
1196  	txrx_peer = dp_get_txrx_peer(peer);
1197  	if (!txrx_peer)
1198  		return;
1199  
1200  	DP_PRINT_STATS(" peer id = %d"
1201  		       " peer_mac_addr = "QDF_MAC_ADDR_FMT
1202  		       " nawds_enabled = %d"
1203  		       " bss_peer = %d"
1204  		       " wds_enabled = %d"
1205  		       " tx_cap_enabled = %d"
1206  		       " rx_cap_enabled = %d",
1207  		       peer->peer_id,
1208  		       QDF_MAC_ADDR_REF(peer->mac_addr.raw),
1209  		       txrx_peer->nawds_enabled,
1210  		       txrx_peer->bss_peer,
1211  		       txrx_peer->wds_enabled,
1212  		       dp_monitor_is_tx_cap_enabled(peer),
1213  		       dp_monitor_is_rx_cap_enabled(peer));
1214  }
1215  
1216  /**
1217   * dp_print_peer_table() - Dump all Peer stats
1218   * @vdev: Datapath Vdev handle
1219   *
1220   * Return: void
1221   */
dp_print_peer_table(struct dp_vdev * vdev)1222  static void dp_print_peer_table(struct dp_vdev *vdev)
1223  {
1224  	DP_PRINT_STATS("Dumping Peer Table  Stats:");
1225  	dp_vdev_iterate_peer(vdev, dp_print_peer_info, NULL,
1226  			     DP_MOD_ID_GENERIC_STATS);
1227  }
1228  
1229  #ifdef DP_MEM_PRE_ALLOC
1230  
dp_context_alloc_mem(struct dp_soc * soc,enum dp_ctxt_type ctxt_type,size_t ctxt_size)1231  void *dp_context_alloc_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type,
1232  			   size_t ctxt_size)
1233  {
1234  	void *ctxt_mem;
1235  
1236  	if (!soc->cdp_soc.ol_ops->dp_prealloc_get_context) {
1237  		dp_warn("dp_prealloc_get_context null!");
1238  		goto dynamic_alloc;
1239  	}
1240  
1241  	ctxt_mem = soc->cdp_soc.ol_ops->dp_prealloc_get_context(ctxt_type,
1242  								ctxt_size);
1243  
1244  	if (ctxt_mem)
1245  		goto end;
1246  
1247  dynamic_alloc:
1248  	dp_info("switch to dynamic-alloc for type %d, size %zu",
1249  		ctxt_type, ctxt_size);
1250  	ctxt_mem = qdf_mem_malloc(ctxt_size);
1251  end:
1252  	return ctxt_mem;
1253  }
1254  
dp_context_free_mem(struct dp_soc * soc,enum dp_ctxt_type ctxt_type,void * vaddr)1255  void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type,
1256  			 void *vaddr)
1257  {
1258  	QDF_STATUS status;
1259  
1260  	if (soc->cdp_soc.ol_ops->dp_prealloc_put_context) {
1261  		status = soc->cdp_soc.ol_ops->dp_prealloc_put_context(
1262  								ctxt_type,
1263  								vaddr);
1264  	} else {
1265  		dp_warn("dp_prealloc_put_context null!");
1266  		status = QDF_STATUS_E_NOSUPPORT;
1267  	}
1268  
1269  	if (QDF_IS_STATUS_ERROR(status)) {
1270  		dp_info("Context type %d not pre-allocated", ctxt_type);
1271  		qdf_mem_free(vaddr);
1272  	}
1273  }
1274  
1275  static inline
dp_srng_aligned_mem_alloc_consistent(struct dp_soc * soc,struct dp_srng * srng,uint32_t ring_type)1276  void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc,
1277  					   struct dp_srng *srng,
1278  					   uint32_t ring_type)
1279  {
1280  	void *mem;
1281  
1282  	qdf_assert(!srng->is_mem_prealloc);
1283  
1284  	if (!soc->cdp_soc.ol_ops->dp_prealloc_get_consistent) {
1285  		dp_warn("dp_prealloc_get_consistent is null!");
1286  		goto qdf;
1287  	}
1288  
1289  	mem =
1290  		soc->cdp_soc.ol_ops->dp_prealloc_get_consistent
1291  						(&srng->alloc_size,
1292  						 &srng->base_vaddr_unaligned,
1293  						 &srng->base_paddr_unaligned,
1294  						 &srng->base_paddr_aligned,
1295  						 DP_RING_BASE_ALIGN, ring_type);
1296  
1297  	if (mem) {
1298  		srng->is_mem_prealloc = true;
1299  		goto end;
1300  	}
1301  qdf:
1302  	mem =  qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size,
1303  						&srng->base_vaddr_unaligned,
1304  						&srng->base_paddr_unaligned,
1305  						&srng->base_paddr_aligned,
1306  						DP_RING_BASE_ALIGN);
1307  end:
1308  	dp_info("%s memory %pK dp_srng %pK ring_type %d alloc_size %d num_entries %d",
1309  		srng->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc", mem,
1310  		srng, ring_type, srng->alloc_size, srng->num_entries);
1311  	return mem;
1312  }
1313  
dp_srng_mem_free_consistent(struct dp_soc * soc,struct dp_srng * srng)1314  static inline void dp_srng_mem_free_consistent(struct dp_soc *soc,
1315  					       struct dp_srng *srng)
1316  {
1317  	if (srng->is_mem_prealloc) {
1318  		if (!soc->cdp_soc.ol_ops->dp_prealloc_put_consistent) {
1319  			dp_warn("dp_prealloc_put_consistent is null!");
1320  			QDF_BUG(0);
1321  			return;
1322  		}
1323  		soc->cdp_soc.ol_ops->dp_prealloc_put_consistent
1324  						(srng->alloc_size,
1325  						 srng->base_vaddr_unaligned,
1326  						 srng->base_paddr_unaligned);
1327  
1328  	} else {
1329  		qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
1330  					srng->alloc_size,
1331  					srng->base_vaddr_unaligned,
1332  					srng->base_paddr_unaligned, 0);
1333  	}
1334  }
1335  
dp_desc_multi_pages_mem_alloc(struct dp_soc * soc,enum qdf_dp_desc_type desc_type,struct qdf_mem_multi_page_t * pages,size_t element_size,uint32_t element_num,qdf_dma_context_t memctxt,bool cacheable)1336  void dp_desc_multi_pages_mem_alloc(struct dp_soc *soc,
1337  				   enum qdf_dp_desc_type desc_type,
1338  				   struct qdf_mem_multi_page_t *pages,
1339  				   size_t element_size,
1340  				   uint32_t element_num,
1341  				   qdf_dma_context_t memctxt,
1342  				   bool cacheable)
1343  {
1344  	if (!soc->cdp_soc.ol_ops->dp_get_multi_pages) {
1345  		dp_warn("dp_get_multi_pages is null!");
1346  		goto qdf;
1347  	}
1348  
1349  	pages->num_pages = 0;
1350  	pages->is_mem_prealloc = 0;
1351  	soc->cdp_soc.ol_ops->dp_get_multi_pages(desc_type,
1352  						element_size,
1353  						element_num,
1354  						pages,
1355  						cacheable);
1356  	if (pages->num_pages)
1357  		goto end;
1358  
1359  qdf:
1360  	qdf_mem_multi_pages_alloc(soc->osdev, pages, element_size,
1361  				  element_num, memctxt, cacheable);
1362  end:
1363  	dp_info("%s desc_type %d element_size %d element_num %d cacheable %d",
1364  		pages->is_mem_prealloc ? "pre-alloc" : "dynamic-alloc",
1365  		desc_type, (int)element_size, element_num, cacheable);
1366  }
1367  
dp_desc_multi_pages_mem_free(struct dp_soc * soc,enum qdf_dp_desc_type desc_type,struct qdf_mem_multi_page_t * pages,qdf_dma_context_t memctxt,bool cacheable)1368  void dp_desc_multi_pages_mem_free(struct dp_soc *soc,
1369  				  enum qdf_dp_desc_type desc_type,
1370  				  struct qdf_mem_multi_page_t *pages,
1371  				  qdf_dma_context_t memctxt,
1372  				  bool cacheable)
1373  {
1374  	if (pages->is_mem_prealloc) {
1375  		if (!soc->cdp_soc.ol_ops->dp_put_multi_pages) {
1376  			dp_warn("dp_put_multi_pages is null!");
1377  			QDF_BUG(0);
1378  			return;
1379  		}
1380  
1381  		soc->cdp_soc.ol_ops->dp_put_multi_pages(desc_type, pages);
1382  		qdf_mem_zero(pages, sizeof(*pages));
1383  	} else {
1384  		qdf_mem_multi_pages_free(soc->osdev, pages,
1385  					 memctxt, cacheable);
1386  	}
1387  }
1388  
1389  #else
1390  
1391  static inline
dp_srng_aligned_mem_alloc_consistent(struct dp_soc * soc,struct dp_srng * srng,uint32_t ring_type)1392  void *dp_srng_aligned_mem_alloc_consistent(struct dp_soc *soc,
1393  					   struct dp_srng *srng,
1394  					   uint32_t ring_type)
1395  
1396  {
1397  	void *mem;
1398  
1399  	mem = qdf_aligned_mem_alloc_consistent(soc->osdev, &srng->alloc_size,
1400  					       &srng->base_vaddr_unaligned,
1401  					       &srng->base_paddr_unaligned,
1402  					       &srng->base_paddr_aligned,
1403  					       DP_RING_BASE_ALIGN);
1404  	if (mem)
1405  		qdf_mem_set(srng->base_vaddr_unaligned, 0, srng->alloc_size);
1406  
1407  	return mem;
1408  }
1409  
dp_srng_mem_free_consistent(struct dp_soc * soc,struct dp_srng * srng)1410  static inline void dp_srng_mem_free_consistent(struct dp_soc *soc,
1411  					       struct dp_srng *srng)
1412  {
1413  	qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
1414  				srng->alloc_size,
1415  				srng->base_vaddr_unaligned,
1416  				srng->base_paddr_unaligned, 0);
1417  }
1418  
1419  #endif /* DP_MEM_PRE_ALLOC */
1420  
1421  #ifdef QCA_SUPPORT_WDS_EXTENDED
dp_vdev_is_wds_ext_enabled(struct dp_vdev * vdev)1422  bool dp_vdev_is_wds_ext_enabled(struct dp_vdev *vdev)
1423  {
1424  	return vdev->wds_ext_enabled;
1425  }
1426  #else
dp_vdev_is_wds_ext_enabled(struct dp_vdev * vdev)1427  bool dp_vdev_is_wds_ext_enabled(struct dp_vdev *vdev)
1428  {
1429  	return false;
1430  }
1431  #endif
1432  
dp_pdev_update_fast_rx_flag(struct dp_soc * soc,struct dp_pdev * pdev)1433  void dp_pdev_update_fast_rx_flag(struct dp_soc *soc, struct dp_pdev *pdev)
1434  {
1435  	struct dp_vdev *vdev = NULL;
1436  	uint8_t rx_fast_flag = true;
1437  
1438  	/* Check if protocol tagging enable */
1439  	if (pdev->is_rx_protocol_tagging_enabled) {
1440  		rx_fast_flag = false;
1441  		goto update_flag;
1442  	}
1443  
1444  	qdf_spin_lock_bh(&pdev->vdev_list_lock);
1445  	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
1446  		/* Check if any VDEV has NAWDS enabled */
1447  		if (vdev->nawds_enabled) {
1448  			rx_fast_flag = false;
1449  			break;
1450  		}
1451  
1452  		/* Check if any VDEV has multipass enabled */
1453  		if (vdev->multipass_en) {
1454  			rx_fast_flag = false;
1455  			break;
1456  		}
1457  
1458  		/* Check if any VDEV has mesh enabled */
1459  		if (vdev->mesh_vdev) {
1460  			rx_fast_flag = false;
1461  			break;
1462  		}
1463  	}
1464  	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
1465  
1466  update_flag:
1467  	dp_init_info("Updated Rx fast flag to %u", rx_fast_flag);
1468  	pdev->rx_fast_flag = rx_fast_flag;
1469  }
1470  
dp_soc_set_interrupt_mode(struct dp_soc * soc)1471  void dp_soc_set_interrupt_mode(struct dp_soc *soc)
1472  {
1473  	uint32_t msi_base_data, msi_vector_start;
1474  	int msi_vector_count, ret;
1475  
1476  	soc->intr_mode = DP_INTR_INTEGRATED;
1477  
1478  	if (!(soc->wlan_cfg_ctx->napi_enabled) ||
1479  	    (dp_is_monitor_mode_using_poll(soc) &&
1480  	     soc->cdp_soc.ol_ops->get_con_mode &&
1481  	     soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE)) {
1482  		soc->intr_mode = DP_INTR_POLL;
1483  	} else {
1484  		ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP",
1485  						  &msi_vector_count,
1486  						  &msi_base_data,
1487  						  &msi_vector_start);
1488  		if (ret)
1489  			return;
1490  
1491  		soc->intr_mode = DP_INTR_MSI;
1492  	}
1493  }
1494  
dp_srng_calculate_msi_group(struct dp_soc * soc,enum hal_ring_type ring_type,int ring_num,int * reg_msi_grp_num,bool nf_irq_support,int * nf_msi_grp_num)1495  static int dp_srng_calculate_msi_group(struct dp_soc *soc,
1496  				       enum hal_ring_type ring_type,
1497  				       int ring_num,
1498  				       int *reg_msi_grp_num,
1499  				       bool nf_irq_support,
1500  				       int *nf_msi_grp_num)
1501  {
1502  	struct wlan_cfg_dp_soc_ctxt *cfg_ctx = soc->wlan_cfg_ctx;
1503  	uint8_t *grp_mask, *nf_irq_mask = NULL;
1504  	bool nf_irq_enabled = false;
1505  	uint8_t wbm2_sw_rx_rel_ring_id;
1506  
1507  	switch (ring_type) {
1508  	case WBM2SW_RELEASE:
1509  		wbm2_sw_rx_rel_ring_id =
1510  			wlan_cfg_get_rx_rel_ring_id(cfg_ctx);
1511  		if (ring_num == wbm2_sw_rx_rel_ring_id) {
1512  			/* dp_rx_wbm_err_process - soc->rx_rel_ring */
1513  			grp_mask = &cfg_ctx->int_rx_wbm_rel_ring_mask[0];
1514  			ring_num = 0;
1515  		} else if (ring_num == WBM2_SW_PPE_REL_RING_ID) {
1516  			grp_mask = &cfg_ctx->int_ppeds_wbm_release_ring_mask[0];
1517  			ring_num = 0;
1518  		}  else { /* dp_tx_comp_handler - soc->tx_comp_ring */
1519  			grp_mask = &soc->wlan_cfg_ctx->int_tx_ring_mask[0];
1520  			nf_irq_mask = dp_srng_get_near_full_irq_mask(soc,
1521  								     ring_type,
1522  								     ring_num);
1523  			if (nf_irq_mask)
1524  				nf_irq_enabled = true;
1525  
1526  			/*
1527  			 * Using ring 4 as 4th tx completion ring since ring 3
1528  			 * is Rx error ring
1529  			 */
1530  			if (ring_num == WBM2SW_TXCOMP_RING4_NUM)
1531  				ring_num = TXCOMP_RING4_NUM;
1532  		}
1533  	break;
1534  
1535  	case REO_EXCEPTION:
1536  		/* dp_rx_err_process - &soc->reo_exception_ring */
1537  		grp_mask = &soc->wlan_cfg_ctx->int_rx_err_ring_mask[0];
1538  	break;
1539  
1540  	case REO_DST:
1541  		/* dp_rx_process - soc->reo_dest_ring */
1542  		grp_mask = &soc->wlan_cfg_ctx->int_rx_ring_mask[0];
1543  		nf_irq_mask = dp_srng_get_near_full_irq_mask(soc, ring_type,
1544  							     ring_num);
1545  		if (nf_irq_mask)
1546  			nf_irq_enabled = true;
1547  	break;
1548  
1549  	case REO_STATUS:
1550  		/* dp_reo_status_ring_handler - soc->reo_status_ring */
1551  		grp_mask = &soc->wlan_cfg_ctx->int_reo_status_ring_mask[0];
1552  	break;
1553  
1554  	/* dp_rx_mon_status_srng_process - pdev->rxdma_mon_status_ring*/
1555  	case RXDMA_MONITOR_STATUS:
1556  	/* dp_rx_mon_dest_process - pdev->rxdma_mon_dst_ring */
1557  	case RXDMA_MONITOR_DST:
1558  		/* dp_mon_process */
1559  		grp_mask = &soc->wlan_cfg_ctx->int_rx_mon_ring_mask[0];
1560  	break;
1561  	case TX_MONITOR_DST:
1562  		/* dp_tx_mon_process */
1563  		grp_mask = &soc->wlan_cfg_ctx->int_tx_mon_ring_mask[0];
1564  	break;
1565  	case RXDMA_DST:
1566  		/* dp_rxdma_err_process */
1567  		grp_mask = &soc->wlan_cfg_ctx->int_rxdma2host_ring_mask[0];
1568  	break;
1569  
1570  	case RXDMA_BUF:
1571  		grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_ring_mask[0];
1572  	break;
1573  
1574  	case RXDMA_MONITOR_BUF:
1575  		grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_mon_ring_mask[0];
1576  	break;
1577  
1578  	case TX_MONITOR_BUF:
1579  		grp_mask = &soc->wlan_cfg_ctx->int_host2txmon_ring_mask[0];
1580  	break;
1581  
1582  	case REO2PPE:
1583  		grp_mask = &soc->wlan_cfg_ctx->int_reo2ppe_ring_mask[0];
1584  	break;
1585  
1586  	case PPE2TCL:
1587  		grp_mask = &soc->wlan_cfg_ctx->int_ppe2tcl_ring_mask[0];
1588  	break;
1589  
1590  	case TCL_DATA:
1591  	/* CMD_CREDIT_RING is used as command in 8074 and credit in 9000 */
1592  	case TCL_CMD_CREDIT:
1593  	case REO_CMD:
1594  	case SW2WBM_RELEASE:
1595  	case WBM_IDLE_LINK:
1596  		/* normally empty SW_TO_HW rings */
1597  		return -QDF_STATUS_E_NOENT;
1598  	break;
1599  
1600  	case TCL_STATUS:
1601  	case REO_REINJECT:
1602  		/* misc unused rings */
1603  		return -QDF_STATUS_E_NOENT;
1604  	break;
1605  
1606  	case CE_SRC:
1607  	case CE_DST:
1608  	case CE_DST_STATUS:
1609  		/* CE_rings - currently handled by hif */
1610  	default:
1611  		return -QDF_STATUS_E_NOENT;
1612  	break;
1613  	}
1614  
1615  	*reg_msi_grp_num = dp_srng_find_ring_in_mask(ring_num, grp_mask);
1616  
1617  	if (nf_irq_support && nf_irq_enabled) {
1618  		*nf_msi_grp_num = dp_srng_find_ring_in_mask(ring_num,
1619  							    nf_irq_mask);
1620  	}
1621  
1622  	return QDF_STATUS_SUCCESS;
1623  }
1624  
1625  #if defined(IPA_OFFLOAD) && defined(IPA_WDI3_VLAN_SUPPORT)
1626  static void
dp_ipa_vlan_srng_msi_setup(struct hal_srng_params * ring_params,int ring_type,int ring_num)1627  dp_ipa_vlan_srng_msi_setup(struct hal_srng_params *ring_params, int ring_type,
1628  			   int ring_num)
1629  {
1630  	if (wlan_ipa_is_vlan_enabled()) {
1631  		if ((ring_type == REO_DST) &&
1632  		    (ring_num == IPA_ALT_REO_DEST_RING_IDX)) {
1633  			ring_params->msi_addr = 0;
1634  			ring_params->msi_data = 0;
1635  			ring_params->flags &= ~HAL_SRNG_MSI_INTR;
1636  		}
1637  	}
1638  }
1639  #else
1640  static inline void
dp_ipa_vlan_srng_msi_setup(struct hal_srng_params * ring_params,int ring_type,int ring_num)1641  dp_ipa_vlan_srng_msi_setup(struct hal_srng_params *ring_params, int ring_type,
1642  			   int ring_num)
1643  {
1644  }
1645  #endif
1646  
dp_srng_msi_setup(struct dp_soc * soc,struct dp_srng * srng,struct hal_srng_params * ring_params,int ring_type,int ring_num)1647  void dp_srng_msi_setup(struct dp_soc *soc, struct dp_srng *srng,
1648  		       struct hal_srng_params *ring_params,
1649  		       int ring_type, int ring_num)
1650  {
1651  	int reg_msi_grp_num;
1652  	/*
1653  	 * nf_msi_grp_num needs to be initialized with negative value,
1654  	 * to avoid configuring near-full msi for WBM2SW3 ring
1655  	 */
1656  	int nf_msi_grp_num = -1;
1657  	int msi_data_count;
1658  	int ret;
1659  	uint32_t msi_data_start, msi_irq_start, addr_low, addr_high;
1660  	bool nf_irq_support;
1661  	int vector;
1662  
1663  	ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP",
1664  					  &msi_data_count, &msi_data_start,
1665  					  &msi_irq_start);
1666  
1667  	if (ret)
1668  		return;
1669  
1670  	nf_irq_support = hal_srng_is_near_full_irq_supported(soc->hal_soc,
1671  							     ring_type,
1672  							     ring_num);
1673  	ret = dp_srng_calculate_msi_group(soc, ring_type, ring_num,
1674  					  &reg_msi_grp_num,
1675  					  nf_irq_support,
1676  					  &nf_msi_grp_num);
1677  	if (ret < 0) {
1678  		dp_init_info("%pK: ring not part of an ext_group; ring_type: %d,ring_num %d",
1679  			     soc, ring_type, ring_num);
1680  		ring_params->msi_addr = 0;
1681  		ring_params->msi_data = 0;
1682  		dp_srng_set_msi2_ring_params(soc, ring_params, 0, 0);
1683  		return;
1684  	}
1685  
1686  	if (reg_msi_grp_num < 0) {
1687  		dp_init_info("%pK: ring not part of an ext_group; ring_type: %d,ring_num %d",
1688  			     soc, ring_type, ring_num);
1689  		ring_params->msi_addr = 0;
1690  		ring_params->msi_data = 0;
1691  		goto configure_msi2;
1692  	}
1693  
1694  	if (dp_is_msi_group_number_invalid(soc, reg_msi_grp_num,
1695  					   msi_data_count)) {
1696  		dp_init_warn("%pK: 2 msi_groups will share an msi; msi_group_num %d",
1697  			     soc, reg_msi_grp_num);
1698  		QDF_ASSERT(0);
1699  	}
1700  
1701  	pld_get_msi_address(soc->osdev->dev, &addr_low, &addr_high);
1702  
1703  	ring_params->msi_addr = addr_low;
1704  	ring_params->msi_addr |= (qdf_dma_addr_t)(((uint64_t)addr_high) << 32);
1705  	ring_params->msi_data = (reg_msi_grp_num % msi_data_count)
1706  		+ msi_data_start;
1707  	ring_params->flags |= HAL_SRNG_MSI_INTR;
1708  
1709  	dp_ipa_vlan_srng_msi_setup(ring_params, ring_type, ring_num);
1710  
1711  	dp_debug("ring type %u ring_num %u msi->data %u msi_addr %llx",
1712  		 ring_type, ring_num, ring_params->msi_data,
1713  		 (uint64_t)ring_params->msi_addr);
1714  
1715  	vector = msi_irq_start + (reg_msi_grp_num % msi_data_count);
1716  
1717  	/*
1718  	 * During umac reset ppeds interrupts free is not called.
1719  	 * Avoid registering interrupts again.
1720  	 *
1721  	 */
1722  	if (dp_check_umac_reset_in_progress(soc))
1723  		goto configure_msi2;
1724  
1725  	if (soc->arch_ops.dp_register_ppeds_interrupts)
1726  		if (soc->arch_ops.dp_register_ppeds_interrupts(soc, srng,
1727  							       vector,
1728  							       ring_type,
1729  							       ring_num))
1730  			return;
1731  
1732  configure_msi2:
1733  	if (!nf_irq_support) {
1734  		dp_srng_set_msi2_ring_params(soc, ring_params, 0, 0);
1735  		return;
1736  	}
1737  
1738  	dp_srng_msi2_setup(soc, ring_params, ring_type, ring_num,
1739  			   nf_msi_grp_num);
1740  }
1741  
1742  #ifdef WLAN_DP_PER_RING_TYPE_CONFIG
1743  /**
1744   * dp_srng_configure_interrupt_thresholds() - Retrieve interrupt
1745   * threshold values from the wlan_srng_cfg table for each ring type
1746   * @soc: device handle
1747   * @ring_params: per ring specific parameters
1748   * @ring_type: Ring type
1749   * @ring_num: Ring number for a given ring type
1750   * @num_entries: number of entries to fill
1751   *
1752   * Fill the ring params with the interrupt threshold
1753   * configuration parameters available in the per ring type wlan_srng_cfg
1754   * table.
1755   *
1756   * Return: None
1757   */
1758  void
dp_srng_configure_interrupt_thresholds(struct dp_soc * soc,struct hal_srng_params * ring_params,int ring_type,int ring_num,int num_entries)1759  dp_srng_configure_interrupt_thresholds(struct dp_soc *soc,
1760  				       struct hal_srng_params *ring_params,
1761  				       int ring_type, int ring_num,
1762  				       int num_entries)
1763  {
1764  	uint8_t wbm2_sw_rx_rel_ring_id;
1765  
1766  	wbm2_sw_rx_rel_ring_id = wlan_cfg_get_rx_rel_ring_id(soc->wlan_cfg_ctx);
1767  
1768  	if (ring_type == REO_DST) {
1769  		ring_params->intr_timer_thres_us =
1770  			wlan_cfg_get_int_timer_threshold_rx(soc->wlan_cfg_ctx);
1771  		ring_params->intr_batch_cntr_thres_entries =
1772  			wlan_cfg_get_int_batch_threshold_rx(soc->wlan_cfg_ctx);
1773  	} else if (ring_type == WBM2SW_RELEASE &&
1774  		   (ring_num == wbm2_sw_rx_rel_ring_id)) {
1775  		ring_params->intr_timer_thres_us =
1776  				wlan_cfg_get_int_timer_threshold_other(soc->wlan_cfg_ctx);
1777  		ring_params->intr_batch_cntr_thres_entries =
1778  				wlan_cfg_get_int_batch_threshold_other(soc->wlan_cfg_ctx);
1779  	} else {
1780  		ring_params->intr_timer_thres_us =
1781  				soc->wlan_srng_cfg[ring_type].timer_threshold;
1782  		ring_params->intr_batch_cntr_thres_entries =
1783  				soc->wlan_srng_cfg[ring_type].batch_count_threshold;
1784  	}
1785  	ring_params->low_threshold =
1786  			soc->wlan_srng_cfg[ring_type].low_threshold;
1787  	if (ring_params->low_threshold)
1788  		ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
1789  
1790  	dp_srng_configure_nf_interrupt_thresholds(soc, ring_params, ring_type);
1791  }
1792  #else
1793  void
dp_srng_configure_interrupt_thresholds(struct dp_soc * soc,struct hal_srng_params * ring_params,int ring_type,int ring_num,int num_entries)1794  dp_srng_configure_interrupt_thresholds(struct dp_soc *soc,
1795  				       struct hal_srng_params *ring_params,
1796  				       int ring_type, int ring_num,
1797  				       int num_entries)
1798  {
1799  	uint8_t wbm2_sw_rx_rel_ring_id;
1800  	bool rx_refill_lt_disable;
1801  
1802  	wbm2_sw_rx_rel_ring_id = wlan_cfg_get_rx_rel_ring_id(soc->wlan_cfg_ctx);
1803  
1804  	if (ring_type == REO_DST || ring_type == REO2PPE) {
1805  		ring_params->intr_timer_thres_us =
1806  			wlan_cfg_get_int_timer_threshold_rx(soc->wlan_cfg_ctx);
1807  		ring_params->intr_batch_cntr_thres_entries =
1808  			wlan_cfg_get_int_batch_threshold_rx(soc->wlan_cfg_ctx);
1809  	} else if (ring_type == WBM2SW_RELEASE &&
1810  		   (ring_num < wbm2_sw_rx_rel_ring_id ||
1811  		   ring_num == WBM2SW_TXCOMP_RING4_NUM ||
1812  		   ring_num == WBM2_SW_PPE_REL_RING_ID)) {
1813  		ring_params->intr_timer_thres_us =
1814  			wlan_cfg_get_int_timer_threshold_tx(soc->wlan_cfg_ctx);
1815  		ring_params->intr_batch_cntr_thres_entries =
1816  			wlan_cfg_get_int_batch_threshold_tx(soc->wlan_cfg_ctx);
1817  	} else if (ring_type == RXDMA_BUF) {
1818  		rx_refill_lt_disable =
1819  			wlan_cfg_get_dp_soc_rxdma_refill_lt_disable
1820  							(soc->wlan_cfg_ctx);
1821  		ring_params->intr_timer_thres_us =
1822  			wlan_cfg_get_int_timer_threshold_rx(soc->wlan_cfg_ctx);
1823  
1824  		if (!rx_refill_lt_disable) {
1825  			ring_params->low_threshold = num_entries >> 3;
1826  			ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
1827  			ring_params->intr_batch_cntr_thres_entries = 0;
1828  		}
1829  	} else {
1830  		ring_params->intr_timer_thres_us =
1831  			wlan_cfg_get_int_timer_threshold_other(soc->wlan_cfg_ctx);
1832  		ring_params->intr_batch_cntr_thres_entries =
1833  			wlan_cfg_get_int_batch_threshold_other(soc->wlan_cfg_ctx);
1834  	}
1835  
1836  	/* These rings donot require interrupt to host. Make them zero */
1837  	switch (ring_type) {
1838  	case REO_REINJECT:
1839  	case REO_CMD:
1840  	case TCL_DATA:
1841  	case TCL_CMD_CREDIT:
1842  	case TCL_STATUS:
1843  	case WBM_IDLE_LINK:
1844  	case SW2WBM_RELEASE:
1845  	case SW2RXDMA_NEW:
1846  		ring_params->intr_timer_thres_us = 0;
1847  		ring_params->intr_batch_cntr_thres_entries = 0;
1848  		break;
1849  	case PPE2TCL:
1850  		ring_params->intr_timer_thres_us =
1851  			wlan_cfg_get_int_timer_threshold_ppe2tcl(soc->wlan_cfg_ctx);
1852  		ring_params->intr_batch_cntr_thres_entries =
1853  			wlan_cfg_get_int_batch_threshold_ppe2tcl(soc->wlan_cfg_ctx);
1854  		break;
1855  	case RXDMA_MONITOR_DST:
1856  		ring_params->intr_timer_thres_us =
1857  		  wlan_cfg_get_int_timer_threshold_mon_dest(soc->wlan_cfg_ctx);
1858  		ring_params->intr_batch_cntr_thres_entries =
1859  		  wlan_cfg_get_int_batch_threshold_mon_dest(soc->wlan_cfg_ctx);
1860  		break;
1861  	}
1862  
1863  	/* Enable low threshold interrupts for rx buffer rings (regular and
1864  	 * monitor buffer rings.
1865  	 * TODO: See if this is required for any other ring
1866  	 */
1867  	if ((ring_type == RXDMA_MONITOR_BUF) ||
1868  	    (ring_type == RXDMA_MONITOR_STATUS ||
1869  	    (ring_type == TX_MONITOR_BUF))) {
1870  		/* TODO: Setting low threshold to 1/8th of ring size
1871  		 * see if this needs to be configurable
1872  		 */
1873  		ring_params->low_threshold = num_entries >> 3;
1874  		ring_params->intr_timer_thres_us =
1875  			wlan_cfg_get_int_timer_threshold_rx(soc->wlan_cfg_ctx);
1876  		ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
1877  		ring_params->intr_batch_cntr_thres_entries = 0;
1878  	}
1879  
1880  	/* During initialisation monitor rings are only filled with
1881  	 * MON_BUF_MIN_ENTRIES entries. So low threshold needs to be set to
1882  	 * a value less than that. Low threshold value is reconfigured again
1883  	 * to 1/8th of the ring size when monitor vap is created.
1884  	 */
1885  	if (ring_type == RXDMA_MONITOR_BUF)
1886  		ring_params->low_threshold = MON_BUF_MIN_ENTRIES >> 1;
1887  
1888  	/* In case of PCI chipsets, we dont have PPDU end interrupts,
1889  	 * so MONITOR STATUS ring is reaped by receiving MSI from srng.
1890  	 * Keep batch threshold as 8 so that interrupt is received for
1891  	 * every 4 packets in MONITOR_STATUS ring
1892  	 */
1893  	if ((ring_type == RXDMA_MONITOR_STATUS) &&
1894  	    (soc->intr_mode == DP_INTR_MSI))
1895  		ring_params->intr_batch_cntr_thres_entries = 4;
1896  }
1897  #endif
1898  
dp_process_rxdma_dst_ring(struct dp_soc * soc,struct dp_intr * int_ctx,int mac_for_pdev,int total_budget)1899  static int dp_process_rxdma_dst_ring(struct dp_soc *soc,
1900  				     struct dp_intr *int_ctx,
1901  				     int mac_for_pdev,
1902  				     int total_budget)
1903  {
1904  	uint32_t target_type;
1905  
1906  	target_type = hal_get_target_type(soc->hal_soc);
1907  	if (target_type == TARGET_TYPE_QCN9160)
1908  		return dp_monitor_process(soc, int_ctx,
1909  					  mac_for_pdev, total_budget);
1910  	else
1911  		return dp_rxdma_err_process(int_ctx, soc, mac_for_pdev,
1912  					    total_budget);
1913  }
1914  
1915  /**
1916   * dp_process_lmac_rings() - Process LMAC rings
1917   * @int_ctx: interrupt context
1918   * @total_budget: budget of work which can be done
1919   *
1920   * Return: work done
1921   */
dp_process_lmac_rings(struct dp_intr * int_ctx,int total_budget)1922  int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget)
1923  {
1924  	struct dp_intr_stats *intr_stats = &int_ctx->intr_stats;
1925  	struct dp_soc *soc = int_ctx->soc;
1926  	uint32_t remaining_quota = total_budget;
1927  	struct dp_pdev *pdev = NULL;
1928  	uint32_t work_done  = 0;
1929  	int budget = total_budget;
1930  	int ring = 0;
1931  	bool rx_refill_lt_disable;
1932  
1933  	rx_refill_lt_disable =
1934  		wlan_cfg_get_dp_soc_rxdma_refill_lt_disable(soc->wlan_cfg_ctx);
1935  
1936  	/* Process LMAC interrupts */
1937  	for  (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
1938  		int mac_for_pdev = ring;
1939  
1940  		pdev = dp_get_pdev_for_lmac_id(soc, mac_for_pdev);
1941  		if (!pdev)
1942  			continue;
1943  		if (int_ctx->rx_mon_ring_mask & (1 << mac_for_pdev)) {
1944  			work_done = dp_monitor_process(soc, int_ctx,
1945  						       mac_for_pdev,
1946  						       remaining_quota);
1947  			if (work_done)
1948  				intr_stats->num_rx_mon_ring_masks++;
1949  			budget -= work_done;
1950  			if (budget <= 0)
1951  				goto budget_done;
1952  			remaining_quota = budget;
1953  		}
1954  
1955  		if (int_ctx->tx_mon_ring_mask & (1 << mac_for_pdev)) {
1956  			work_done = dp_tx_mon_process(soc, int_ctx,
1957  						      mac_for_pdev,
1958  						      remaining_quota);
1959  			if (work_done)
1960  				intr_stats->num_tx_mon_ring_masks++;
1961  			budget -= work_done;
1962  			if (budget <= 0)
1963  				goto budget_done;
1964  			remaining_quota = budget;
1965  		}
1966  
1967  		if (int_ctx->rxdma2host_ring_mask &
1968  				(1 << mac_for_pdev)) {
1969  			work_done = dp_process_rxdma_dst_ring(soc, int_ctx,
1970  							      mac_for_pdev,
1971  							      remaining_quota);
1972  			if (work_done)
1973  				intr_stats->num_rxdma2host_ring_masks++;
1974  			budget -=  work_done;
1975  			if (budget <= 0)
1976  				goto budget_done;
1977  			remaining_quota = budget;
1978  		}
1979  
1980  		if (int_ctx->host2rxdma_ring_mask & (1 << mac_for_pdev)) {
1981  			struct dp_srng *rx_refill_buf_ring;
1982  			struct rx_desc_pool *rx_desc_pool;
1983  
1984  			rx_desc_pool = &soc->rx_desc_buf[mac_for_pdev];
1985  			if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx))
1986  				rx_refill_buf_ring =
1987  					&soc->rx_refill_buf_ring[mac_for_pdev];
1988  			else
1989  				rx_refill_buf_ring =
1990  					&soc->rx_refill_buf_ring[pdev->lmac_id];
1991  
1992  			intr_stats->num_host2rxdma_ring_masks++;
1993  
1994  			if (!rx_refill_lt_disable)
1995  				dp_rx_buffers_lt_replenish_simple
1996  							(soc, mac_for_pdev,
1997  							 rx_refill_buf_ring,
1998  							 rx_desc_pool,
1999  							 false);
2000  		}
2001  	}
2002  
2003  	if (int_ctx->host2rxdma_mon_ring_mask)
2004  		dp_rx_mon_buf_refill(int_ctx);
2005  
2006  	if (int_ctx->host2txmon_ring_mask)
2007  		dp_tx_mon_buf_refill(int_ctx);
2008  
2009  budget_done:
2010  	return total_budget - budget;
2011  }
2012  
dp_service_srngs_wrapper(void * dp_ctx,uint32_t dp_budget,int cpu)2013  uint32_t dp_service_srngs_wrapper(void *dp_ctx, uint32_t dp_budget, int cpu)
2014  {
2015  	struct dp_intr *int_ctx = (struct dp_intr *)dp_ctx;
2016  	struct dp_soc *soc = int_ctx->soc;
2017  
2018  	return soc->arch_ops.dp_service_srngs(dp_ctx, dp_budget, cpu);
2019  }
2020  
2021  #ifdef QCA_SUPPORT_LEGACY_INTERRUPTS
2022  /**
2023   * dp_soc_interrupt_map_calculate_wifi3_pci_legacy() -
2024   * Calculate interrupt map for legacy interrupts
2025   * @soc: DP soc handle
2026   * @intr_ctx_num: Interrupt context number
2027   * @irq_id_map: IRQ map
2028   * @num_irq_r: Number of interrupts assigned for this context
2029   *
2030   * Return: void
2031   */
dp_soc_interrupt_map_calculate_wifi3_pci_legacy(struct dp_soc * soc,int intr_ctx_num,int * irq_id_map,int * num_irq_r)2032  static void dp_soc_interrupt_map_calculate_wifi3_pci_legacy(struct dp_soc *soc,
2033  							    int intr_ctx_num,
2034  							    int *irq_id_map,
2035  							    int *num_irq_r)
2036  {
2037  	int j;
2038  	int num_irq = 0;
2039  	int tx_mask = wlan_cfg_get_tx_ring_mask(
2040  					soc->wlan_cfg_ctx, intr_ctx_num);
2041  	int rx_mask = wlan_cfg_get_rx_ring_mask(
2042  					soc->wlan_cfg_ctx, intr_ctx_num);
2043  	int rx_mon_mask = wlan_cfg_get_rx_mon_ring_mask(
2044  					soc->wlan_cfg_ctx, intr_ctx_num);
2045  	int rx_err_ring_mask = wlan_cfg_get_rx_err_ring_mask(
2046  					soc->wlan_cfg_ctx, intr_ctx_num);
2047  	int rx_wbm_rel_ring_mask = wlan_cfg_get_rx_wbm_rel_ring_mask(
2048  					soc->wlan_cfg_ctx, intr_ctx_num);
2049  	int reo_status_ring_mask = wlan_cfg_get_reo_status_ring_mask(
2050  					soc->wlan_cfg_ctx, intr_ctx_num);
2051  	int rxdma2host_ring_mask = wlan_cfg_get_rxdma2host_ring_mask(
2052  					soc->wlan_cfg_ctx, intr_ctx_num);
2053  	int host2rxdma_ring_mask = wlan_cfg_get_host2rxdma_ring_mask(
2054  					soc->wlan_cfg_ctx, intr_ctx_num);
2055  	int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask(
2056  					soc->wlan_cfg_ctx, intr_ctx_num);
2057  	int host2txmon_ring_mask = wlan_cfg_get_host2txmon_ring_mask(
2058  					soc->wlan_cfg_ctx, intr_ctx_num);
2059  	int txmon2host_mon_ring_mask = wlan_cfg_get_tx_mon_ring_mask(
2060  					soc->wlan_cfg_ctx, intr_ctx_num);
2061  	soc->intr_mode = DP_INTR_LEGACY_VIRTUAL_IRQ;
2062  	for (j = 0; j < HIF_MAX_GRP_IRQ; j++) {
2063  		if (tx_mask & (1 << j))
2064  			irq_id_map[num_irq++] = (wbm2sw0_release - j);
2065  		if (rx_mask & (1 << j))
2066  			irq_id_map[num_irq++] = (reo2sw1_intr - j);
2067  		if (rx_mon_mask & (1 << j))
2068  			irq_id_map[num_irq++] = (rxmon2sw_p0_dest0 - j);
2069  		if (rx_err_ring_mask & (1 << j))
2070  			irq_id_map[num_irq++] = (reo2sw0_intr - j);
2071  		if (rx_wbm_rel_ring_mask & (1 << j))
2072  			irq_id_map[num_irq++] = (wbm2sw5_release - j);
2073  		if (reo_status_ring_mask & (1 << j))
2074  			irq_id_map[num_irq++] = (reo_status - j);
2075  		if (rxdma2host_ring_mask & (1 << j))
2076  			irq_id_map[num_irq++] = (rxdma2sw_dst_ring0 - j);
2077  		if (host2rxdma_ring_mask & (1 << j))
2078  			irq_id_map[num_irq++] = (sw2rxdma_0 - j);
2079  		if (host2rxdma_mon_ring_mask & (1 << j))
2080  			irq_id_map[num_irq++] = (sw2rxmon_src_ring - j);
2081  		if (host2txmon_ring_mask & (1 << j))
2082  			irq_id_map[num_irq++] = sw2txmon_src_ring;
2083  		if (txmon2host_mon_ring_mask & (1 << j))
2084  			irq_id_map[num_irq++] = (txmon2sw_p0_dest0 - j);
2085  	}
2086  	*num_irq_r = num_irq;
2087  }
2088  #else
dp_soc_interrupt_map_calculate_wifi3_pci_legacy(struct dp_soc * soc,int intr_ctx_num,int * irq_id_map,int * num_irq_r)2089  static void dp_soc_interrupt_map_calculate_wifi3_pci_legacy(struct dp_soc *soc,
2090  							    int intr_ctx_num,
2091  							    int *irq_id_map,
2092  							    int *num_irq_r)
2093  {
2094  }
2095  #endif
2096  
2097  static void
dp_soc_interrupt_map_calculate_integrated(struct dp_soc * soc,int intr_ctx_num,int * irq_id_map,int * num_irq_r)2098  dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc, int intr_ctx_num,
2099  					  int *irq_id_map, int *num_irq_r)
2100  {
2101  	int j;
2102  	int num_irq = 0;
2103  
2104  	int tx_mask =
2105  		wlan_cfg_get_tx_ring_mask(soc->wlan_cfg_ctx, intr_ctx_num);
2106  	int rx_mask =
2107  		wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, intr_ctx_num);
2108  	int rx_mon_mask =
2109  		wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, intr_ctx_num);
2110  	int rx_err_ring_mask = wlan_cfg_get_rx_err_ring_mask(
2111  					soc->wlan_cfg_ctx, intr_ctx_num);
2112  	int rx_wbm_rel_ring_mask = wlan_cfg_get_rx_wbm_rel_ring_mask(
2113  					soc->wlan_cfg_ctx, intr_ctx_num);
2114  	int reo_status_ring_mask = wlan_cfg_get_reo_status_ring_mask(
2115  					soc->wlan_cfg_ctx, intr_ctx_num);
2116  	int rxdma2host_ring_mask = wlan_cfg_get_rxdma2host_ring_mask(
2117  					soc->wlan_cfg_ctx, intr_ctx_num);
2118  	int host2rxdma_ring_mask = wlan_cfg_get_host2rxdma_ring_mask(
2119  					soc->wlan_cfg_ctx, intr_ctx_num);
2120  	int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask(
2121  					soc->wlan_cfg_ctx, intr_ctx_num);
2122  	int host2txmon_ring_mask = wlan_cfg_get_host2txmon_ring_mask(
2123  					soc->wlan_cfg_ctx, intr_ctx_num);
2124  	int txmon2host_mon_ring_mask = wlan_cfg_get_tx_mon_ring_mask(
2125  					soc->wlan_cfg_ctx, intr_ctx_num);
2126  
2127  	soc->intr_mode = DP_INTR_INTEGRATED;
2128  
2129  	for (j = 0; j < HIF_MAX_GRP_IRQ; j++) {
2130  		if (tx_mask & (1 << j)) {
2131  			irq_id_map[num_irq++] =
2132  				(wbm2host_tx_completions_ring1 - j);
2133  		}
2134  
2135  		if (rx_mask & (1 << j)) {
2136  			irq_id_map[num_irq++] =
2137  				(reo2host_destination_ring1 - j);
2138  		}
2139  
2140  		if (rxdma2host_ring_mask & (1 << j)) {
2141  			irq_id_map[num_irq++] =
2142  				rxdma2host_destination_ring_mac1 - j;
2143  		}
2144  
2145  		if (host2rxdma_ring_mask & (1 << j)) {
2146  			irq_id_map[num_irq++] =
2147  				host2rxdma_host_buf_ring_mac1 -	j;
2148  		}
2149  
2150  		if (host2rxdma_mon_ring_mask & (1 << j)) {
2151  			irq_id_map[num_irq++] =
2152  				host2rxdma_monitor_ring1 - j;
2153  		}
2154  
2155  		if (rx_mon_mask & (1 << j)) {
2156  			irq_id_map[num_irq++] =
2157  				ppdu_end_interrupts_mac1 - j;
2158  			irq_id_map[num_irq++] =
2159  				rxdma2host_monitor_status_ring_mac1 - j;
2160  			irq_id_map[num_irq++] =
2161  				rxdma2host_monitor_destination_mac1 - j;
2162  		}
2163  
2164  		if (rx_wbm_rel_ring_mask & (1 << j))
2165  			irq_id_map[num_irq++] = wbm2host_rx_release;
2166  
2167  		if (rx_err_ring_mask & (1 << j))
2168  			irq_id_map[num_irq++] = reo2host_exception;
2169  
2170  		if (reo_status_ring_mask & (1 << j))
2171  			irq_id_map[num_irq++] = reo2host_status;
2172  
2173  		if (host2txmon_ring_mask & (1 << j))
2174  			irq_id_map[num_irq++] = host2tx_monitor_ring1;
2175  
2176  		if (txmon2host_mon_ring_mask & (1 << j)) {
2177  			irq_id_map[num_irq++] =
2178  				(txmon2host_monitor_destination_mac1 - j);
2179  		}
2180  	}
2181  	*num_irq_r = num_irq;
2182  }
2183  
2184  static void
dp_soc_interrupt_map_calculate_msi(struct dp_soc * soc,int intr_ctx_num,int * irq_id_map,int * num_irq_r,int msi_vector_count,int msi_vector_start)2185  dp_soc_interrupt_map_calculate_msi(struct dp_soc *soc, int intr_ctx_num,
2186  				   int *irq_id_map, int *num_irq_r,
2187  				   int msi_vector_count, int msi_vector_start)
2188  {
2189  	int tx_mask = wlan_cfg_get_tx_ring_mask(
2190  					soc->wlan_cfg_ctx, intr_ctx_num);
2191  	int rx_mask = wlan_cfg_get_rx_ring_mask(
2192  					soc->wlan_cfg_ctx, intr_ctx_num);
2193  	int rx_mon_mask = wlan_cfg_get_rx_mon_ring_mask(
2194  					soc->wlan_cfg_ctx, intr_ctx_num);
2195  	int tx_mon_mask = wlan_cfg_get_tx_mon_ring_mask(
2196  					soc->wlan_cfg_ctx, intr_ctx_num);
2197  	int rx_err_ring_mask = wlan_cfg_get_rx_err_ring_mask(
2198  					soc->wlan_cfg_ctx, intr_ctx_num);
2199  	int rx_wbm_rel_ring_mask = wlan_cfg_get_rx_wbm_rel_ring_mask(
2200  					soc->wlan_cfg_ctx, intr_ctx_num);
2201  	int reo_status_ring_mask = wlan_cfg_get_reo_status_ring_mask(
2202  					soc->wlan_cfg_ctx, intr_ctx_num);
2203  	int rxdma2host_ring_mask = wlan_cfg_get_rxdma2host_ring_mask(
2204  					soc->wlan_cfg_ctx, intr_ctx_num);
2205  	int host2rxdma_ring_mask = wlan_cfg_get_host2rxdma_ring_mask(
2206  					soc->wlan_cfg_ctx, intr_ctx_num);
2207  	int host2rxdma_mon_ring_mask = wlan_cfg_get_host2rxdma_mon_ring_mask(
2208  					soc->wlan_cfg_ctx, intr_ctx_num);
2209  	int rx_near_full_grp_1_mask =
2210  		wlan_cfg_get_rx_near_full_grp_1_mask(soc->wlan_cfg_ctx,
2211  						     intr_ctx_num);
2212  	int rx_near_full_grp_2_mask =
2213  		wlan_cfg_get_rx_near_full_grp_2_mask(soc->wlan_cfg_ctx,
2214  						     intr_ctx_num);
2215  	int tx_ring_near_full_mask =
2216  		wlan_cfg_get_tx_ring_near_full_mask(soc->wlan_cfg_ctx,
2217  						    intr_ctx_num);
2218  
2219  	int host2txmon_ring_mask =
2220  		wlan_cfg_get_host2txmon_ring_mask(soc->wlan_cfg_ctx,
2221  						  intr_ctx_num);
2222  	unsigned int vector =
2223  		(intr_ctx_num % msi_vector_count) + msi_vector_start;
2224  	int num_irq = 0;
2225  
2226  	soc->intr_mode = DP_INTR_MSI;
2227  
2228  	if (tx_mask | rx_mask | rx_mon_mask | tx_mon_mask | rx_err_ring_mask |
2229  	    rx_wbm_rel_ring_mask | reo_status_ring_mask | rxdma2host_ring_mask |
2230  	    host2rxdma_ring_mask | host2rxdma_mon_ring_mask |
2231  	    rx_near_full_grp_1_mask | rx_near_full_grp_2_mask |
2232  	    tx_ring_near_full_mask | host2txmon_ring_mask)
2233  		irq_id_map[num_irq++] =
2234  			pld_get_msi_irq(soc->osdev->dev, vector);
2235  
2236  	*num_irq_r = num_irq;
2237  }
2238  
dp_soc_interrupt_map_calculate(struct dp_soc * soc,int intr_ctx_num,int * irq_id_map,int * num_irq)2239  void dp_soc_interrupt_map_calculate(struct dp_soc *soc, int intr_ctx_num,
2240  				    int *irq_id_map, int *num_irq)
2241  {
2242  	int msi_vector_count, ret;
2243  	uint32_t msi_base_data, msi_vector_start;
2244  
2245  	if (pld_get_enable_intx(soc->osdev->dev)) {
2246  		return dp_soc_interrupt_map_calculate_wifi3_pci_legacy(soc,
2247  				intr_ctx_num, irq_id_map, num_irq);
2248  	}
2249  
2250  	ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP",
2251  					  &msi_vector_count,
2252  					  &msi_base_data,
2253  					  &msi_vector_start);
2254  	if (ret)
2255  		return dp_soc_interrupt_map_calculate_integrated(soc,
2256  				intr_ctx_num, irq_id_map, num_irq);
2257  
2258  	else
2259  		dp_soc_interrupt_map_calculate_msi(soc,
2260  				intr_ctx_num, irq_id_map, num_irq,
2261  				msi_vector_count, msi_vector_start);
2262  }
2263  
dp_srng_free(struct dp_soc * soc,struct dp_srng * srng)2264  void dp_srng_free(struct dp_soc *soc, struct dp_srng *srng)
2265  {
2266  	if (srng->alloc_size && srng->base_vaddr_unaligned) {
2267  		if (!srng->cached) {
2268  			dp_srng_mem_free_consistent(soc, srng);
2269  		} else {
2270  			qdf_mem_free(srng->base_vaddr_unaligned);
2271  		}
2272  		srng->alloc_size = 0;
2273  		srng->base_vaddr_unaligned = NULL;
2274  	}
2275  	srng->hal_srng = NULL;
2276  }
2277  
2278  qdf_export_symbol(dp_srng_free);
2279  
dp_srng_init(struct dp_soc * soc,struct dp_srng * srng,int ring_type,int ring_num,int mac_id)2280  QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng, int ring_type,
2281  			int ring_num, int mac_id)
2282  {
2283  	return soc->arch_ops.txrx_srng_init(soc, srng, ring_type,
2284  					    ring_num, mac_id);
2285  }
2286  
2287  qdf_export_symbol(dp_srng_init);
2288  
dp_srng_alloc(struct dp_soc * soc,struct dp_srng * srng,int ring_type,uint32_t num_entries,bool cached)2289  QDF_STATUS dp_srng_alloc(struct dp_soc *soc, struct dp_srng *srng,
2290  			 int ring_type, uint32_t num_entries,
2291  			 bool cached)
2292  {
2293  	hal_soc_handle_t hal_soc = soc->hal_soc;
2294  	uint32_t entry_size = hal_srng_get_entrysize(hal_soc, ring_type);
2295  	uint32_t max_entries = hal_srng_max_entries(hal_soc, ring_type);
2296  
2297  	if (srng->base_vaddr_unaligned) {
2298  		dp_init_err("%pK: Ring type: %d, is already allocated",
2299  			    soc, ring_type);
2300  		return QDF_STATUS_SUCCESS;
2301  	}
2302  
2303  	num_entries = (num_entries > max_entries) ? max_entries : num_entries;
2304  	srng->hal_srng = NULL;
2305  	srng->alloc_size = num_entries * entry_size;
2306  	srng->num_entries = num_entries;
2307  	srng->cached = cached;
2308  
2309  	if (!cached) {
2310  		srng->base_vaddr_aligned =
2311  		    dp_srng_aligned_mem_alloc_consistent(soc,
2312  							 srng,
2313  							 ring_type);
2314  	} else {
2315  		srng->base_vaddr_aligned = qdf_aligned_malloc(
2316  					&srng->alloc_size,
2317  					&srng->base_vaddr_unaligned,
2318  					&srng->base_paddr_unaligned,
2319  					&srng->base_paddr_aligned,
2320  					DP_RING_BASE_ALIGN);
2321  	}
2322  
2323  	if (!srng->base_vaddr_aligned)
2324  		return QDF_STATUS_E_NOMEM;
2325  
2326  	return QDF_STATUS_SUCCESS;
2327  }
2328  
2329  qdf_export_symbol(dp_srng_alloc);
2330  
dp_srng_deinit(struct dp_soc * soc,struct dp_srng * srng,int ring_type,int ring_num)2331  void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
2332  		    int ring_type, int ring_num)
2333  {
2334  	if (!srng->hal_srng) {
2335  		dp_init_err("%pK: Ring type: %d, num:%d not setup",
2336  			    soc, ring_type, ring_num);
2337  		return;
2338  	}
2339  
2340  	if (dp_check_umac_reset_in_progress(soc))
2341  		goto srng_cleanup;
2342  
2343  	if (soc->arch_ops.dp_free_ppeds_interrupts)
2344  		soc->arch_ops.dp_free_ppeds_interrupts(soc, srng, ring_type,
2345  						       ring_num);
2346  
2347  srng_cleanup:
2348  	hal_srng_cleanup(soc->hal_soc, srng->hal_srng,
2349  			 dp_check_umac_reset_in_progress(soc));
2350  	srng->hal_srng = NULL;
2351  }
2352  
2353  qdf_export_symbol(dp_srng_deinit);
2354  
2355  /* TODO: Need this interface from HIF */
2356  void *hif_get_hal_handle(struct hif_opaque_softc *hif_handle);
2357  
2358  #ifdef WLAN_FEATURE_DP_EVENT_HISTORY
dp_srng_access_start(struct dp_intr * int_ctx,struct dp_soc * dp_soc,hal_ring_handle_t hal_ring_hdl)2359  int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
2360  			 hal_ring_handle_t hal_ring_hdl)
2361  {
2362  	hal_soc_handle_t hal_soc = dp_soc->hal_soc;
2363  	uint32_t hp, tp;
2364  	uint8_t ring_id;
2365  
2366  	if (!int_ctx)
2367  		return dp_hal_srng_access_start(hal_soc, hal_ring_hdl);
2368  
2369  	hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp);
2370  	ring_id = hal_srng_ring_id_get(hal_ring_hdl);
2371  
2372  	hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id,
2373  			 ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_START);
2374  
2375  	return dp_hal_srng_access_start(hal_soc, hal_ring_hdl);
2376  }
2377  
dp_srng_access_end(struct dp_intr * int_ctx,struct dp_soc * dp_soc,hal_ring_handle_t hal_ring_hdl)2378  void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
2379  			hal_ring_handle_t hal_ring_hdl)
2380  {
2381  	hal_soc_handle_t hal_soc = dp_soc->hal_soc;
2382  	uint32_t hp, tp;
2383  	uint8_t ring_id;
2384  
2385  	if (!int_ctx)
2386  		return dp_hal_srng_access_end(hal_soc, hal_ring_hdl);
2387  
2388  	hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp);
2389  	ring_id = hal_srng_ring_id_get(hal_ring_hdl);
2390  
2391  	hif_record_event(dp_soc->hif_handle, int_ctx->dp_intr_id,
2392  			 ring_id, hp, tp, HIF_EVENT_SRNG_ACCESS_END);
2393  
2394  	return dp_hal_srng_access_end(hal_soc, hal_ring_hdl);
2395  }
2396  
dp_srng_record_timer_entry(struct dp_soc * dp_soc,uint8_t hist_group_id)2397  static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc,
2398  					      uint8_t hist_group_id)
2399  {
2400  	hif_record_event(dp_soc->hif_handle, hist_group_id,
2401  			 0, 0, 0, HIF_EVENT_TIMER_ENTRY);
2402  }
2403  
dp_srng_record_timer_exit(struct dp_soc * dp_soc,uint8_t hist_group_id)2404  static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
2405  					     uint8_t hist_group_id)
2406  {
2407  	hif_record_event(dp_soc->hif_handle, hist_group_id,
2408  			 0, 0, 0, HIF_EVENT_TIMER_EXIT);
2409  }
2410  #else
2411  
dp_srng_record_timer_entry(struct dp_soc * dp_soc,uint8_t hist_group_id)2412  static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc,
2413  					      uint8_t hist_group_id)
2414  {
2415  }
2416  
dp_srng_record_timer_exit(struct dp_soc * dp_soc,uint8_t hist_group_id)2417  static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
2418  					     uint8_t hist_group_id)
2419  {
2420  }
2421  
2422  #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */
2423  
2424  enum timer_yield_status
dp_should_timer_irq_yield(struct dp_soc * soc,uint32_t work_done,uint64_t start_time)2425  dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
2426  			  uint64_t start_time)
2427  {
2428  	uint64_t cur_time = qdf_get_log_timestamp();
2429  
2430  	if (!work_done)
2431  		return DP_TIMER_WORK_DONE;
2432  
2433  	if (cur_time - start_time > DP_MAX_TIMER_EXEC_TIME_TICKS)
2434  		return DP_TIMER_TIME_EXHAUST;
2435  
2436  	return DP_TIMER_NO_YIELD;
2437  }
2438  
2439  qdf_export_symbol(dp_should_timer_irq_yield);
2440  
dp_interrupt_timer(void * arg)2441  void dp_interrupt_timer(void *arg)
2442  {
2443  	struct dp_soc *soc = (struct dp_soc *) arg;
2444  	struct dp_pdev *pdev = soc->pdev_list[0];
2445  	enum timer_yield_status yield = DP_TIMER_NO_YIELD;
2446  	uint32_t work_done  = 0, total_work_done = 0;
2447  	int budget = 0xffff, i;
2448  	uint32_t remaining_quota = budget;
2449  	uint64_t start_time;
2450  	uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
2451  	uint8_t dp_intr_id = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx);
2452  	uint32_t lmac_iter;
2453  	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
2454  	enum reg_wifi_band mon_band;
2455  	int cpu = dp_srng_get_cpu();
2456  
2457  	/*
2458  	 * this logic makes all data path interfacing rings (UMAC/LMAC)
2459  	 * and Monitor rings polling mode when NSS offload is disabled
2460  	 */
2461  	if (wlan_cfg_is_poll_mode_enabled(soc->wlan_cfg_ctx) &&
2462  	    !wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) {
2463  		if (qdf_atomic_read(&soc->cmn_init_done)) {
2464  			for (i = 0; i < wlan_cfg_get_num_contexts(
2465  						soc->wlan_cfg_ctx); i++)
2466  				soc->arch_ops.dp_service_srngs(&soc->intr_ctx[i], 0xffff,
2467  							       cpu);
2468  
2469  			qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
2470  		}
2471  		return;
2472  	}
2473  
2474  	if (!qdf_atomic_read(&soc->cmn_init_done))
2475  		return;
2476  
2477  	if (dp_monitor_is_chan_band_known(pdev)) {
2478  		mon_band = dp_monitor_get_chan_band(pdev);
2479  		lmac_id = pdev->ch_band_lmac_id_mapping[mon_band];
2480  		if (qdf_likely(lmac_id != DP_MON_INVALID_LMAC_ID)) {
2481  			dp_intr_id = soc->mon_intr_id_lmac_map[lmac_id];
2482  			dp_srng_record_timer_entry(soc, dp_intr_id);
2483  		}
2484  	}
2485  
2486  	start_time = qdf_get_log_timestamp();
2487  	dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings);
2488  
2489  	while (yield == DP_TIMER_NO_YIELD) {
2490  		for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
2491  			if (lmac_iter == lmac_id)
2492  				work_done = dp_monitor_process(soc,
2493  						&soc->intr_ctx[dp_intr_id],
2494  						lmac_iter, remaining_quota);
2495  			else
2496  				work_done =
2497  					dp_monitor_drop_packets_for_mac(pdev,
2498  							     lmac_iter,
2499  							     remaining_quota);
2500  			if (work_done) {
2501  				budget -=  work_done;
2502  				if (budget <= 0) {
2503  					yield = DP_TIMER_WORK_EXHAUST;
2504  					goto budget_done;
2505  				}
2506  				remaining_quota = budget;
2507  				total_work_done += work_done;
2508  			}
2509  		}
2510  
2511  		yield = dp_should_timer_irq_yield(soc, total_work_done,
2512  						  start_time);
2513  		total_work_done = 0;
2514  	}
2515  
2516  budget_done:
2517  	if (yield == DP_TIMER_WORK_EXHAUST ||
2518  	    yield == DP_TIMER_TIME_EXHAUST)
2519  		qdf_timer_mod(&soc->int_timer, 1);
2520  	else
2521  		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
2522  
2523  	if (lmac_id != DP_MON_INVALID_LMAC_ID)
2524  		dp_srng_record_timer_exit(soc, dp_intr_id);
2525  }
2526  
2527  /**
2528   * dp_soc_interrupt_detach_wrapper() - wrapper function for interrupt detach
2529   * @txrx_soc: DP SOC handle
2530   *
2531   * Return: None
2532   */
dp_soc_interrupt_detach_wrapper(struct cdp_soc_t * txrx_soc)2533  static void dp_soc_interrupt_detach_wrapper(struct cdp_soc_t *txrx_soc)
2534  {
2535  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
2536  
2537  	return soc->arch_ops.dp_soc_interrupt_detach(txrx_soc);
2538  }
2539  
2540  #if defined(DP_INTR_POLL_BOTH)
2541  /**
2542   * dp_soc_interrupt_attach_wrapper() - Register handlers for DP interrupts
2543   * @txrx_soc: DP SOC handle
2544   *
2545   * Call the appropriate attach function based on the mode of operation.
2546   * This is a WAR for enabling monitor mode.
2547   *
2548   * Return: 0 for success. nonzero for failure.
2549   */
dp_soc_interrupt_attach_wrapper(struct cdp_soc_t * txrx_soc)2550  static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc)
2551  {
2552  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
2553  
2554  	if (!(soc->wlan_cfg_ctx->napi_enabled) ||
2555  	    (dp_is_monitor_mode_using_poll(soc) &&
2556  	     soc->cdp_soc.ol_ops->get_con_mode &&
2557  	     soc->cdp_soc.ol_ops->get_con_mode() ==
2558  	     QDF_GLOBAL_MONITOR_MODE)) {
2559  		dp_info("Poll mode");
2560  		return soc->arch_ops.dp_soc_attach_poll(txrx_soc);
2561  	} else {
2562  		dp_info("Interrupt  mode");
2563  		return soc->arch_ops.dp_soc_interrupt_attach(txrx_soc);
2564  	}
2565  }
2566  #else
2567  #if defined(DP_INTR_POLL_BASED) && DP_INTR_POLL_BASED
dp_soc_interrupt_attach_wrapper(struct cdp_soc_t * txrx_soc)2568  static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc)
2569  {
2570  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
2571  
2572  	return soc->arch_ops.dp_soc_attach_poll(txrx_soc);
2573  }
2574  #else
dp_soc_interrupt_attach_wrapper(struct cdp_soc_t * txrx_soc)2575  static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc)
2576  {
2577  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
2578  
2579  	if (wlan_cfg_is_poll_mode_enabled(soc->wlan_cfg_ctx))
2580  		return soc->arch_ops.dp_soc_attach_poll(txrx_soc);
2581  	else
2582  		return soc->arch_ops.dp_soc_interrupt_attach(txrx_soc);
2583  }
2584  #endif
2585  #endif
2586  
dp_link_desc_ring_replenish(struct dp_soc * soc,uint32_t mac_id)2587  void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id)
2588  {
2589  	uint32_t cookie = 0;
2590  	uint32_t page_idx = 0;
2591  	struct qdf_mem_multi_page_t *pages;
2592  	struct qdf_mem_dma_page_t *dma_pages;
2593  	uint32_t offset = 0;
2594  	uint32_t count = 0;
2595  	uint32_t desc_id = 0;
2596  	void *desc_srng;
2597  	int link_desc_size = hal_get_link_desc_size(soc->hal_soc);
2598  	uint32_t *total_link_descs_addr;
2599  	uint32_t total_link_descs;
2600  	uint32_t scatter_buf_num;
2601  	uint32_t num_entries_per_buf = 0;
2602  	uint32_t rem_entries;
2603  	uint32_t num_descs_per_page;
2604  	uint32_t num_scatter_bufs = 0;
2605  	uint8_t *scatter_buf_ptr;
2606  	void *desc;
2607  
2608  	num_scatter_bufs = soc->num_scatter_bufs;
2609  
2610  	if (mac_id == WLAN_INVALID_PDEV_ID) {
2611  		pages = &soc->link_desc_pages;
2612  		total_link_descs = soc->total_link_descs;
2613  		desc_srng = soc->wbm_idle_link_ring.hal_srng;
2614  	} else {
2615  		pages = dp_monitor_get_link_desc_pages(soc, mac_id);
2616  		/* dp_monitor_get_link_desc_pages returns NULL only
2617  		 * if monitor SOC is  NULL
2618  		 */
2619  		if (!pages) {
2620  			dp_err("can not get link desc pages");
2621  			QDF_ASSERT(0);
2622  			return;
2623  		}
2624  		total_link_descs_addr =
2625  				dp_monitor_get_total_link_descs(soc, mac_id);
2626  		total_link_descs = *total_link_descs_addr;
2627  		desc_srng = dp_monitor_get_link_desc_ring(soc, mac_id);
2628  	}
2629  
2630  	dma_pages = pages->dma_pages;
2631  	do {
2632  		qdf_mem_zero(dma_pages[page_idx].page_v_addr_start,
2633  			     pages->page_size);
2634  		page_idx++;
2635  	} while (page_idx < pages->num_pages);
2636  
2637  	if (desc_srng) {
2638  		hal_srng_access_start_unlocked(soc->hal_soc, desc_srng);
2639  		page_idx = 0;
2640  		count = 0;
2641  		offset = 0;
2642  
2643  		qdf_assert(pages->num_element_per_page != 0);
2644  		while ((desc = hal_srng_src_get_next(soc->hal_soc,
2645  						     desc_srng)) &&
2646  			(count < total_link_descs)) {
2647  			page_idx = count / pages->num_element_per_page;
2648  			if (desc_id == pages->num_element_per_page)
2649  				desc_id = 0;
2650  
2651  			offset = count % pages->num_element_per_page;
2652  			cookie = LINK_DESC_COOKIE(desc_id, page_idx,
2653  						  soc->link_desc_id_start);
2654  
2655  			hal_set_link_desc_addr(soc->hal_soc, desc, cookie,
2656  					       dma_pages[page_idx].page_p_addr
2657  					       + (offset * link_desc_size),
2658  					       soc->idle_link_bm_id);
2659  			count++;
2660  			desc_id++;
2661  		}
2662  		hal_srng_access_end_unlocked(soc->hal_soc, desc_srng);
2663  	} else {
2664  		/* Populate idle list scatter buffers with link descriptor
2665  		 * pointers
2666  		 */
2667  		scatter_buf_num = 0;
2668  		num_entries_per_buf = hal_idle_scatter_buf_num_entries(
2669  					soc->hal_soc,
2670  					soc->wbm_idle_scatter_buf_size);
2671  
2672  		scatter_buf_ptr = (uint8_t *)(
2673  			soc->wbm_idle_scatter_buf_base_vaddr[scatter_buf_num]);
2674  		rem_entries = num_entries_per_buf;
2675  		page_idx = 0; count = 0;
2676  		offset = 0;
2677  		num_descs_per_page = pages->num_element_per_page;
2678  
2679  		qdf_assert(num_descs_per_page != 0);
2680  		while (count < total_link_descs) {
2681  			page_idx = count / num_descs_per_page;
2682  			offset = count % num_descs_per_page;
2683  			if (desc_id == pages->num_element_per_page)
2684  				desc_id = 0;
2685  
2686  			cookie = LINK_DESC_COOKIE(desc_id, page_idx,
2687  						  soc->link_desc_id_start);
2688  			hal_set_link_desc_addr(soc->hal_soc,
2689  					       (void *)scatter_buf_ptr,
2690  					       cookie,
2691  					       dma_pages[page_idx].page_p_addr +
2692  					       (offset * link_desc_size),
2693  					       soc->idle_link_bm_id);
2694  			rem_entries--;
2695  			if (rem_entries) {
2696  				scatter_buf_ptr += link_desc_size;
2697  			} else {
2698  				rem_entries = num_entries_per_buf;
2699  				scatter_buf_num++;
2700  				if (scatter_buf_num >= num_scatter_bufs) {
2701  					scatter_buf_num--;
2702  					break;
2703  				}
2704  
2705  				scatter_buf_ptr = (uint8_t *)
2706  					(soc->wbm_idle_scatter_buf_base_vaddr[
2707  					 scatter_buf_num]);
2708  			}
2709  			count++;
2710  			desc_id++;
2711  		}
2712  		/* Setup link descriptor idle list in HW */
2713  		hal_setup_link_idle_list(soc->hal_soc,
2714  			soc->wbm_idle_scatter_buf_base_paddr,
2715  			soc->wbm_idle_scatter_buf_base_vaddr,
2716  			num_scatter_bufs, soc->wbm_idle_scatter_buf_size,
2717  			(uint32_t)(scatter_buf_ptr -
2718  			(uint8_t *)(soc->wbm_idle_scatter_buf_base_vaddr[
2719  			scatter_buf_num])), total_link_descs);
2720  	}
2721  }
2722  
2723  qdf_export_symbol(dp_link_desc_ring_replenish);
2724  
2725  /**
2726   * dp_soc_ppeds_stop() - Stop PPE DS processing
2727   * @soc_handle: DP SOC handle
2728   *
2729   * Return: none
2730   */
dp_soc_ppeds_stop(struct cdp_soc_t * soc_handle)2731  static void dp_soc_ppeds_stop(struct cdp_soc_t *soc_handle)
2732  {
2733  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
2734  
2735  	if (soc->arch_ops.txrx_soc_ppeds_stop)
2736  		soc->arch_ops.txrx_soc_ppeds_stop(soc);
2737  }
2738  
2739  #ifdef ENABLE_VERBOSE_DEBUG
dp_enable_verbose_debug(struct dp_soc * soc)2740  void dp_enable_verbose_debug(struct dp_soc *soc)
2741  {
2742  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
2743  
2744  	soc_cfg_ctx = soc->wlan_cfg_ctx;
2745  
2746  	if (soc_cfg_ctx->per_pkt_trace & dp_verbose_debug_mask)
2747  		is_dp_verbose_debug_enabled = true;
2748  
2749  	if (soc_cfg_ctx->per_pkt_trace & hal_verbose_debug_mask)
2750  		hal_set_verbose_debug(true);
2751  	else
2752  		hal_set_verbose_debug(false);
2753  }
2754  #else
dp_enable_verbose_debug(struct dp_soc * soc)2755  void dp_enable_verbose_debug(struct dp_soc *soc)
2756  {
2757  }
2758  #endif
2759  
dp_lro_hash_setup(struct dp_soc * soc,struct dp_pdev * pdev)2760  static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev)
2761  {
2762  	struct cdp_lro_hash_config lro_hash;
2763  	QDF_STATUS status;
2764  
2765  	if (!wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) &&
2766  	    !wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx) &&
2767  	    !wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) {
2768  		dp_err("LRO, GRO and RX hash disabled");
2769  		return QDF_STATUS_E_FAILURE;
2770  	}
2771  
2772  	qdf_mem_zero(&lro_hash, sizeof(lro_hash));
2773  
2774  	if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) ||
2775  	    wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx)) {
2776  		lro_hash.lro_enable = 1;
2777  		lro_hash.tcp_flag = QDF_TCPHDR_ACK;
2778  		lro_hash.tcp_flag_mask = QDF_TCPHDR_FIN | QDF_TCPHDR_SYN |
2779  			 QDF_TCPHDR_RST | QDF_TCPHDR_ACK | QDF_TCPHDR_URG |
2780  			 QDF_TCPHDR_ECE | QDF_TCPHDR_CWR;
2781  	}
2782  
2783  	soc->arch_ops.get_rx_hash_key(soc, &lro_hash);
2784  
2785  	qdf_assert(soc->cdp_soc.ol_ops->lro_hash_config);
2786  
2787  	if (!soc->cdp_soc.ol_ops->lro_hash_config) {
2788  		QDF_BUG(0);
2789  		dp_err("lro_hash_config not configured");
2790  		return QDF_STATUS_E_FAILURE;
2791  	}
2792  
2793  	status = soc->cdp_soc.ol_ops->lro_hash_config(soc->ctrl_psoc,
2794  						      pdev->pdev_id,
2795  						      &lro_hash);
2796  	if (!QDF_IS_STATUS_SUCCESS(status)) {
2797  		dp_err("failed to send lro_hash_config to FW %u", status);
2798  		return status;
2799  	}
2800  
2801  	dp_info("LRO CMD config: lro_enable: 0x%x tcp_flag 0x%x tcp_flag_mask 0x%x",
2802  		lro_hash.lro_enable, lro_hash.tcp_flag,
2803  		lro_hash.tcp_flag_mask);
2804  
2805  	dp_info("toeplitz_hash_ipv4:");
2806  	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
2807  			   lro_hash.toeplitz_hash_ipv4,
2808  			   (sizeof(lro_hash.toeplitz_hash_ipv4[0]) *
2809  			   LRO_IPV4_SEED_ARR_SZ));
2810  
2811  	dp_info("toeplitz_hash_ipv6:");
2812  	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
2813  			   lro_hash.toeplitz_hash_ipv6,
2814  			   (sizeof(lro_hash.toeplitz_hash_ipv6[0]) *
2815  			   LRO_IPV6_SEED_ARR_SZ));
2816  
2817  	return status;
2818  }
2819  
2820  #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
2821  /**
2822   * dp_reap_timer_init() - initialize the reap timer
2823   * @soc: data path SoC handle
2824   *
2825   * Return: void
2826   */
dp_reap_timer_init(struct dp_soc * soc)2827  static void dp_reap_timer_init(struct dp_soc *soc)
2828  {
2829  	/*
2830  	 * Timer to reap rxdma status rings.
2831  	 * Needed until we enable ppdu end interrupts
2832  	 */
2833  	dp_monitor_reap_timer_init(soc);
2834  	dp_monitor_vdev_timer_init(soc);
2835  }
2836  
2837  /**
2838   * dp_reap_timer_deinit() - de-initialize the reap timer
2839   * @soc: data path SoC handle
2840   *
2841   * Return: void
2842   */
dp_reap_timer_deinit(struct dp_soc * soc)2843  static void dp_reap_timer_deinit(struct dp_soc *soc)
2844  {
2845  	dp_monitor_reap_timer_deinit(soc);
2846  }
2847  #else
2848  /* WIN use case */
dp_reap_timer_init(struct dp_soc * soc)2849  static void dp_reap_timer_init(struct dp_soc *soc)
2850  {
2851  	/* Configure LMAC rings in Polled mode */
2852  	if (soc->lmac_polled_mode) {
2853  		/*
2854  		 * Timer to reap lmac rings.
2855  		 */
2856  		qdf_timer_init(soc->osdev, &soc->lmac_reap_timer,
2857  			       dp_service_lmac_rings, (void *)soc,
2858  			       QDF_TIMER_TYPE_WAKE_APPS);
2859  		soc->lmac_timer_init = 1;
2860  		qdf_timer_mod(&soc->lmac_reap_timer, DP_INTR_POLL_TIMER_MS);
2861  	}
2862  }
2863  
dp_reap_timer_deinit(struct dp_soc * soc)2864  static void dp_reap_timer_deinit(struct dp_soc *soc)
2865  {
2866  	if (soc->lmac_timer_init) {
2867  		qdf_timer_stop(&soc->lmac_reap_timer);
2868  		qdf_timer_free(&soc->lmac_reap_timer);
2869  		soc->lmac_timer_init = 0;
2870  	}
2871  }
2872  #endif
2873  
2874  #ifdef QCA_HOST2FW_RXBUF_RING
2875  /**
2876   * dp_rxdma_ring_alloc() - allocate the RXDMA rings
2877   * @soc: data path SoC handle
2878   * @pdev: Physical device handle
2879   *
2880   * Return: 0 - success, > 0 - failure
2881   */
dp_rxdma_ring_alloc(struct dp_soc * soc,struct dp_pdev * pdev)2882  static int dp_rxdma_ring_alloc(struct dp_soc *soc, struct dp_pdev *pdev)
2883  {
2884  	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
2885  	int max_mac_rings;
2886  	int i;
2887  	int ring_size;
2888  
2889  	pdev_cfg_ctx = pdev->wlan_cfg_ctx;
2890  	max_mac_rings = wlan_cfg_get_num_mac_rings(pdev_cfg_ctx);
2891  	ring_size =  wlan_cfg_get_rx_dma_buf_ring_size(pdev_cfg_ctx);
2892  
2893  	for (i = 0; i < max_mac_rings; i++) {
2894  		dp_verbose_debug("pdev_id %d mac_id %d", pdev->pdev_id, i);
2895  		if (dp_srng_alloc(soc, &pdev->rx_mac_buf_ring[i],
2896  				  RXDMA_BUF, ring_size, 0)) {
2897  			dp_init_err("%pK: failed rx mac ring setup", soc);
2898  			return QDF_STATUS_E_FAILURE;
2899  		}
2900  	}
2901  	return QDF_STATUS_SUCCESS;
2902  }
2903  
2904  /**
2905   * dp_rxdma_ring_setup() - configure the RXDMA rings
2906   * @soc: data path SoC handle
2907   * @pdev: Physical device handle
2908   *
2909   * Return: 0 - success, > 0 - failure
2910   */
dp_rxdma_ring_setup(struct dp_soc * soc,struct dp_pdev * pdev)2911  static int dp_rxdma_ring_setup(struct dp_soc *soc, struct dp_pdev *pdev)
2912  {
2913  	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
2914  	int max_mac_rings;
2915  	int i;
2916  
2917  	pdev_cfg_ctx = pdev->wlan_cfg_ctx;
2918  	max_mac_rings = wlan_cfg_get_num_mac_rings(pdev_cfg_ctx);
2919  
2920  	for (i = 0; i < max_mac_rings; i++) {
2921  		dp_verbose_debug("pdev_id %d mac_id %d", pdev->pdev_id, i);
2922  		if (dp_srng_init(soc, &pdev->rx_mac_buf_ring[i],
2923  				 RXDMA_BUF, 1, i)) {
2924  			dp_init_err("%pK: failed rx mac ring setup", soc);
2925  			return QDF_STATUS_E_FAILURE;
2926  		}
2927  		dp_ssr_dump_srng_register("rx_mac_buf_ring",
2928  					  &pdev->rx_mac_buf_ring[i], i);
2929  	}
2930  	return QDF_STATUS_SUCCESS;
2931  }
2932  
2933  /**
2934   * dp_rxdma_ring_cleanup() - Deinit the RXDMA rings and reap timer
2935   * @soc: data path SoC handle
2936   * @pdev: Physical device handle
2937   *
2938   * Return: void
2939   */
dp_rxdma_ring_cleanup(struct dp_soc * soc,struct dp_pdev * pdev)2940  static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
2941  {
2942  	int i;
2943  
2944  	for (i = 0; i < MAX_RX_MAC_RINGS; i++) {
2945  		dp_ssr_dump_srng_unregister("rx_mac_buf_ring", i);
2946  		dp_srng_deinit(soc, &pdev->rx_mac_buf_ring[i], RXDMA_BUF, 1);
2947  	}
2948  
2949  	dp_reap_timer_deinit(soc);
2950  }
2951  
2952  /**
2953   * dp_rxdma_ring_free() - Free the RXDMA rings
2954   * @pdev: Physical device handle
2955   *
2956   * Return: void
2957   */
dp_rxdma_ring_free(struct dp_pdev * pdev)2958  static void dp_rxdma_ring_free(struct dp_pdev *pdev)
2959  {
2960  	int i;
2961  
2962  	for (i = 0; i < MAX_RX_MAC_RINGS; i++)
2963  		dp_srng_free(pdev->soc, &pdev->rx_mac_buf_ring[i]);
2964  }
2965  
2966  #else
dp_rxdma_ring_alloc(struct dp_soc * soc,struct dp_pdev * pdev)2967  static int dp_rxdma_ring_alloc(struct dp_soc *soc, struct dp_pdev *pdev)
2968  {
2969  	return QDF_STATUS_SUCCESS;
2970  }
2971  
dp_rxdma_ring_setup(struct dp_soc * soc,struct dp_pdev * pdev)2972  static int dp_rxdma_ring_setup(struct dp_soc *soc, struct dp_pdev *pdev)
2973  {
2974  	return QDF_STATUS_SUCCESS;
2975  }
2976  
dp_rxdma_ring_cleanup(struct dp_soc * soc,struct dp_pdev * pdev)2977  static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
2978  {
2979  	dp_reap_timer_deinit(soc);
2980  }
2981  
dp_rxdma_ring_free(struct dp_pdev * pdev)2982  static void dp_rxdma_ring_free(struct dp_pdev *pdev)
2983  {
2984  }
2985  #endif
2986  
2987  #ifdef IPA_OFFLOAD
2988  /**
2989   * dp_setup_ipa_rx_refill_buf_ring - Setup second Rx refill buffer ring
2990   * @soc: data path instance
2991   * @pdev: core txrx pdev context
2992   *
2993   * Return: QDF_STATUS_SUCCESS: success
2994   *         QDF_STATUS_E_RESOURCES: Error return
2995   */
dp_setup_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)2996  static int dp_setup_ipa_rx_refill_buf_ring(struct dp_soc *soc,
2997  					   struct dp_pdev *pdev)
2998  {
2999  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
3000  	int entries;
3001  
3002  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
3003  		soc_cfg_ctx = soc->wlan_cfg_ctx;
3004  		entries =
3005  			wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx);
3006  
3007  		/* Setup second Rx refill buffer ring */
3008  		if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF,
3009  				  entries, 0)) {
3010  			dp_init_err("%pK: dp_srng_alloc failed second"
3011  				    "rx refill ring", soc);
3012  			return QDF_STATUS_E_FAILURE;
3013  		}
3014  	}
3015  
3016  	return QDF_STATUS_SUCCESS;
3017  }
3018  
3019  #ifdef IPA_WDI3_VLAN_SUPPORT
dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3020  static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3021  					       struct dp_pdev *pdev)
3022  {
3023  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
3024  	int entries;
3025  
3026  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) &&
3027  	    wlan_ipa_is_vlan_enabled()) {
3028  		soc_cfg_ctx = soc->wlan_cfg_ctx;
3029  		entries =
3030  			wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx);
3031  
3032  		/* Setup second Rx refill buffer ring */
3033  		if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF,
3034  				  entries, 0)) {
3035  			dp_init_err("%pK: alloc failed for 3rd rx refill ring",
3036  				    soc);
3037  			return QDF_STATUS_E_FAILURE;
3038  		}
3039  	}
3040  
3041  	return QDF_STATUS_SUCCESS;
3042  }
3043  
dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3044  static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3045  					      struct dp_pdev *pdev)
3046  {
3047  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) &&
3048  	    wlan_ipa_is_vlan_enabled()) {
3049  		if (dp_srng_init(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF,
3050  				 IPA_RX_ALT_REFILL_BUF_RING_IDX,
3051  				 pdev->pdev_id)) {
3052  			dp_init_err("%pK: init failed for 3rd rx refill ring",
3053  				    soc);
3054  			return QDF_STATUS_E_FAILURE;
3055  		}
3056  	}
3057  
3058  	return QDF_STATUS_SUCCESS;
3059  }
3060  
dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3061  static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3062  						 struct dp_pdev *pdev)
3063  {
3064  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) &&
3065  	    wlan_ipa_is_vlan_enabled())
3066  		dp_srng_deinit(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, 0);
3067  }
3068  
dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3069  static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3070  					       struct dp_pdev *pdev)
3071  {
3072  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) &&
3073  	    wlan_ipa_is_vlan_enabled())
3074  		dp_srng_free(soc, &pdev->rx_refill_buf_ring3);
3075  }
3076  #else
dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3077  static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3078  					       struct dp_pdev *pdev)
3079  {
3080  	return QDF_STATUS_SUCCESS;
3081  }
3082  
dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3083  static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3084  					      struct dp_pdev *pdev)
3085  {
3086  	return QDF_STATUS_SUCCESS;
3087  }
3088  
dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3089  static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3090  						 struct dp_pdev *pdev)
3091  {
3092  }
3093  
dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3094  static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3095  					       struct dp_pdev *pdev)
3096  {
3097  }
3098  #endif
3099  
3100  /**
3101   * dp_deinit_ipa_rx_refill_buf_ring - deinit second Rx refill buffer ring
3102   * @soc: data path instance
3103   * @pdev: core txrx pdev context
3104   *
3105   * Return: void
3106   */
dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3107  static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3108  					     struct dp_pdev *pdev)
3109  {
3110  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
3111  		dp_srng_deinit(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 0);
3112  }
3113  
3114  /**
3115   * dp_init_ipa_rx_refill_buf_ring - Init second Rx refill buffer ring
3116   * @soc: data path instance
3117   * @pdev: core txrx pdev context
3118   *
3119   * Return: QDF_STATUS_SUCCESS: success
3120   *         QDF_STATUS_E_RESOURCES: Error return
3121   */
dp_init_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3122  static int dp_init_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3123  					  struct dp_pdev *pdev)
3124  {
3125  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
3126  		if (dp_srng_init(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF,
3127  				 IPA_RX_REFILL_BUF_RING_IDX, pdev->pdev_id)) {
3128  			dp_init_err("%pK: dp_srng_init failed second"
3129  				    "rx refill ring", soc);
3130  			return QDF_STATUS_E_FAILURE;
3131  		}
3132  	}
3133  
3134  	if (dp_init_ipa_rx_alt_refill_buf_ring(soc, pdev)) {
3135  		dp_deinit_ipa_rx_refill_buf_ring(soc, pdev);
3136  		return QDF_STATUS_E_FAILURE;
3137  	}
3138  
3139  	return QDF_STATUS_SUCCESS;
3140  }
3141  
3142  /**
3143   * dp_free_ipa_rx_refill_buf_ring - free second Rx refill buffer ring
3144   * @soc: data path instance
3145   * @pdev: core txrx pdev context
3146   *
3147   * Return: void
3148   */
dp_free_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3149  static void dp_free_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3150  					   struct dp_pdev *pdev)
3151  {
3152  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
3153  		dp_srng_free(soc, &pdev->rx_refill_buf_ring2);
3154  }
3155  #else
dp_setup_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3156  static int dp_setup_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3157  					   struct dp_pdev *pdev)
3158  {
3159  	return QDF_STATUS_SUCCESS;
3160  }
3161  
dp_init_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3162  static int dp_init_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3163  					  struct dp_pdev *pdev)
3164  {
3165  	return QDF_STATUS_SUCCESS;
3166  }
3167  
dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3168  static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3169  					     struct dp_pdev *pdev)
3170  {
3171  }
3172  
dp_free_ipa_rx_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3173  static void dp_free_ipa_rx_refill_buf_ring(struct dp_soc *soc,
3174  					   struct dp_pdev *pdev)
3175  {
3176  }
3177  
dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3178  static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3179  					       struct dp_pdev *pdev)
3180  {
3181  	return QDF_STATUS_SUCCESS;
3182  }
3183  
dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3184  static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3185  						 struct dp_pdev *pdev)
3186  {
3187  }
3188  
dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc * soc,struct dp_pdev * pdev)3189  static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc,
3190  					       struct dp_pdev *pdev)
3191  {
3192  }
3193  #endif
3194  
3195  #ifdef WLAN_FEATURE_DP_CFG_EVENT_HISTORY
3196  
3197  /**
3198   * dp_soc_cfg_history_attach() - Allocate and attach datapath config events
3199   *				 history
3200   * @soc: DP soc handle
3201   *
3202   * Return: None
3203   */
dp_soc_cfg_history_attach(struct dp_soc * soc)3204  static void dp_soc_cfg_history_attach(struct dp_soc *soc)
3205  {
3206  	dp_soc_frag_history_attach(soc, &soc->cfg_event_history,
3207  				   DP_CFG_EVT_HIST_MAX_SLOTS,
3208  				   DP_CFG_EVT_HIST_PER_SLOT_MAX,
3209  				   sizeof(struct dp_cfg_event),
3210  				   true, DP_CFG_EVENT_HIST_TYPE);
3211  }
3212  
3213  /**
3214   * dp_soc_cfg_history_detach() - Detach and free DP config events history
3215   * @soc: DP soc handle
3216   *
3217   * Return: none
3218   */
dp_soc_cfg_history_detach(struct dp_soc * soc)3219  static void dp_soc_cfg_history_detach(struct dp_soc *soc)
3220  {
3221  	dp_soc_frag_history_detach(soc, &soc->cfg_event_history,
3222  				   DP_CFG_EVT_HIST_MAX_SLOTS,
3223  				   true, DP_CFG_EVENT_HIST_TYPE);
3224  }
3225  
3226  #else
dp_soc_cfg_history_attach(struct dp_soc * soc)3227  static void dp_soc_cfg_history_attach(struct dp_soc *soc)
3228  {
3229  }
3230  
dp_soc_cfg_history_detach(struct dp_soc * soc)3231  static void dp_soc_cfg_history_detach(struct dp_soc *soc)
3232  {
3233  }
3234  #endif
3235  
3236  #ifdef DP_TX_HW_DESC_HISTORY
3237  /**
3238   * dp_soc_tx_hw_desc_history_attach - Attach TX HW descriptor history
3239   *
3240   * @soc: DP soc handle
3241   *
3242   * Return: None
3243   */
dp_soc_tx_hw_desc_history_attach(struct dp_soc * soc)3244  static void dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc)
3245  {
3246  	dp_soc_frag_history_attach(soc, &soc->tx_hw_desc_history,
3247  				   DP_TX_HW_DESC_HIST_MAX_SLOTS,
3248  				   DP_TX_HW_DESC_HIST_PER_SLOT_MAX,
3249  				   sizeof(struct dp_tx_hw_desc_evt),
3250  				   true, DP_TX_HW_DESC_HIST_TYPE);
3251  }
3252  
dp_soc_tx_hw_desc_history_detach(struct dp_soc * soc)3253  static void dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc)
3254  {
3255  	dp_soc_frag_history_detach(soc, &soc->tx_hw_desc_history,
3256  				   DP_TX_HW_DESC_HIST_MAX_SLOTS,
3257  				   true, DP_TX_HW_DESC_HIST_TYPE);
3258  }
3259  
3260  #else /* DP_TX_HW_DESC_HISTORY */
3261  static inline void
dp_soc_tx_hw_desc_history_attach(struct dp_soc * soc)3262  dp_soc_tx_hw_desc_history_attach(struct dp_soc *soc)
3263  {
3264  }
3265  
3266  static inline void
dp_soc_tx_hw_desc_history_detach(struct dp_soc * soc)3267  dp_soc_tx_hw_desc_history_detach(struct dp_soc *soc)
3268  {
3269  }
3270  #endif /* DP_TX_HW_DESC_HISTORY */
3271  
3272  #ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
3273  #ifndef RX_DEFRAG_DO_NOT_REINJECT
3274  /**
3275   * dp_soc_rx_reinject_ring_history_attach - Attach the reo reinject ring
3276   *					    history.
3277   * @soc: DP soc handle
3278   *
3279   * Return: None
3280   */
dp_soc_rx_reinject_ring_history_attach(struct dp_soc * soc)3281  static void dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc)
3282  {
3283  	soc->rx_reinject_ring_history =
3284  		dp_context_alloc_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE,
3285  				     sizeof(struct dp_rx_reinject_history));
3286  	if (soc->rx_reinject_ring_history)
3287  		qdf_atomic_init(&soc->rx_reinject_ring_history->index);
3288  }
3289  #else /* RX_DEFRAG_DO_NOT_REINJECT */
3290  static inline void
dp_soc_rx_reinject_ring_history_attach(struct dp_soc * soc)3291  dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc)
3292  {
3293  }
3294  #endif /* RX_DEFRAG_DO_NOT_REINJECT */
3295  
3296  /**
3297   * dp_soc_rx_history_attach() - Attach the ring history record buffers
3298   * @soc: DP soc structure
3299   *
3300   * This function allocates the memory for recording the rx ring, rx error
3301   * ring and the reinject ring entries. There is no error returned in case
3302   * of allocation failure since the record function checks if the history is
3303   * initialized or not. We do not want to fail the driver load in case of
3304   * failure to allocate memory for debug history.
3305   *
3306   * Return: None
3307   */
dp_soc_rx_history_attach(struct dp_soc * soc)3308  static void dp_soc_rx_history_attach(struct dp_soc *soc)
3309  {
3310  	int i;
3311  	uint32_t rx_ring_hist_size;
3312  	uint32_t rx_refill_ring_hist_size;
3313  
3314  	rx_ring_hist_size = sizeof(*soc->rx_ring_history[0]);
3315  	rx_refill_ring_hist_size = sizeof(*soc->rx_refill_ring_history[0]);
3316  
3317  	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
3318  		soc->rx_ring_history[i] = dp_context_alloc_mem(
3319  				soc, DP_RX_RING_HIST_TYPE, rx_ring_hist_size);
3320  		if (soc->rx_ring_history[i])
3321  			qdf_atomic_init(&soc->rx_ring_history[i]->index);
3322  	}
3323  
3324  	soc->rx_err_ring_history = dp_context_alloc_mem(
3325  			soc, DP_RX_ERR_RING_HIST_TYPE, rx_ring_hist_size);
3326  	if (soc->rx_err_ring_history)
3327  		qdf_atomic_init(&soc->rx_err_ring_history->index);
3328  
3329  	dp_soc_rx_reinject_ring_history_attach(soc);
3330  
3331  	for (i = 0; i < MAX_PDEV_CNT; i++) {
3332  		soc->rx_refill_ring_history[i] = dp_context_alloc_mem(
3333  						soc,
3334  						DP_RX_REFILL_RING_HIST_TYPE,
3335  						rx_refill_ring_hist_size);
3336  
3337  		if (soc->rx_refill_ring_history[i])
3338  			qdf_atomic_init(&soc->rx_refill_ring_history[i]->index);
3339  	}
3340  }
3341  
dp_soc_rx_history_detach(struct dp_soc * soc)3342  static void dp_soc_rx_history_detach(struct dp_soc *soc)
3343  {
3344  	int i;
3345  
3346  	for (i = 0; i < MAX_REO_DEST_RINGS; i++)
3347  		dp_context_free_mem(soc, DP_RX_RING_HIST_TYPE,
3348  				    soc->rx_ring_history[i]);
3349  
3350  	dp_context_free_mem(soc, DP_RX_ERR_RING_HIST_TYPE,
3351  			    soc->rx_err_ring_history);
3352  
3353  	/*
3354  	 * No need for a featurized detach since qdf_mem_free takes
3355  	 * care of NULL pointer.
3356  	 */
3357  	dp_context_free_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE,
3358  			    soc->rx_reinject_ring_history);
3359  
3360  	for (i = 0; i < MAX_PDEV_CNT; i++)
3361  		dp_context_free_mem(soc, DP_RX_REFILL_RING_HIST_TYPE,
3362  				    soc->rx_refill_ring_history[i]);
3363  }
3364  
3365  #else
dp_soc_rx_history_attach(struct dp_soc * soc)3366  static inline void dp_soc_rx_history_attach(struct dp_soc *soc)
3367  {
3368  }
3369  
dp_soc_rx_history_detach(struct dp_soc * soc)3370  static inline void dp_soc_rx_history_detach(struct dp_soc *soc)
3371  {
3372  }
3373  #endif
3374  
3375  #ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY
3376  /**
3377   * dp_soc_mon_status_ring_history_attach() - Attach the monitor status
3378   *					     buffer record history.
3379   * @soc: DP soc handle
3380   *
3381   * This function allocates memory to track the event for a monitor
3382   * status buffer, before its parsed and freed.
3383   *
3384   * Return: None
3385   */
dp_soc_mon_status_ring_history_attach(struct dp_soc * soc)3386  static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc)
3387  {
3388  	soc->mon_status_ring_history = dp_context_alloc_mem(soc,
3389  				DP_MON_STATUS_BUF_HIST_TYPE,
3390  				sizeof(struct dp_mon_status_ring_history));
3391  	if (!soc->mon_status_ring_history) {
3392  		dp_err("Failed to alloc memory for mon status ring history");
3393  		return;
3394  	}
3395  }
3396  
3397  /**
3398   * dp_soc_mon_status_ring_history_detach() - Detach the monitor status buffer
3399   *					     record history.
3400   * @soc: DP soc handle
3401   *
3402   * Return: None
3403   */
dp_soc_mon_status_ring_history_detach(struct dp_soc * soc)3404  static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc)
3405  {
3406  	dp_context_free_mem(soc, DP_MON_STATUS_BUF_HIST_TYPE,
3407  			    soc->mon_status_ring_history);
3408  }
3409  #else
dp_soc_mon_status_ring_history_attach(struct dp_soc * soc)3410  static void dp_soc_mon_status_ring_history_attach(struct dp_soc *soc)
3411  {
3412  }
3413  
dp_soc_mon_status_ring_history_detach(struct dp_soc * soc)3414  static void dp_soc_mon_status_ring_history_detach(struct dp_soc *soc)
3415  {
3416  }
3417  #endif
3418  
3419  #ifdef WLAN_FEATURE_DP_TX_DESC_HISTORY
3420  /**
3421   * dp_soc_tx_history_attach() - Attach the ring history record buffers
3422   * @soc: DP soc structure
3423   *
3424   * This function allocates the memory for recording the tx tcl ring and
3425   * the tx comp ring entries. There is no error returned in case
3426   * of allocation failure since the record function checks if the history is
3427   * initialized or not. We do not want to fail the driver load in case of
3428   * failure to allocate memory for debug history.
3429   *
3430   * Return: None
3431   */
dp_soc_tx_history_attach(struct dp_soc * soc)3432  static void dp_soc_tx_history_attach(struct dp_soc *soc)
3433  {
3434  	dp_soc_frag_history_attach(soc, &soc->tx_tcl_history,
3435  				   DP_TX_TCL_HIST_MAX_SLOTS,
3436  				   DP_TX_TCL_HIST_PER_SLOT_MAX,
3437  				   sizeof(struct dp_tx_desc_event),
3438  				   true, DP_TX_TCL_HIST_TYPE);
3439  	dp_soc_frag_history_attach(soc, &soc->tx_comp_history,
3440  				   DP_TX_COMP_HIST_MAX_SLOTS,
3441  				   DP_TX_COMP_HIST_PER_SLOT_MAX,
3442  				   sizeof(struct dp_tx_desc_event),
3443  				   true, DP_TX_COMP_HIST_TYPE);
3444  }
3445  
3446  /**
3447   * dp_soc_tx_history_detach() - Detach the ring history record buffers
3448   * @soc: DP soc structure
3449   *
3450   * This function frees the memory for recording the tx tcl ring and
3451   * the tx comp ring entries.
3452   *
3453   * Return: None
3454   */
dp_soc_tx_history_detach(struct dp_soc * soc)3455  static void dp_soc_tx_history_detach(struct dp_soc *soc)
3456  {
3457  	dp_soc_frag_history_detach(soc, &soc->tx_tcl_history,
3458  				   DP_TX_TCL_HIST_MAX_SLOTS,
3459  				   true, DP_TX_TCL_HIST_TYPE);
3460  	dp_soc_frag_history_detach(soc, &soc->tx_comp_history,
3461  				   DP_TX_COMP_HIST_MAX_SLOTS,
3462  				   true, DP_TX_COMP_HIST_TYPE);
3463  }
3464  
3465  #else
dp_soc_tx_history_attach(struct dp_soc * soc)3466  static inline void dp_soc_tx_history_attach(struct dp_soc *soc)
3467  {
3468  }
3469  
dp_soc_tx_history_detach(struct dp_soc * soc)3470  static inline void dp_soc_tx_history_detach(struct dp_soc *soc)
3471  {
3472  }
3473  #endif /* WLAN_FEATURE_DP_TX_DESC_HISTORY */
3474  
3475  #ifdef DP_RX_MSDU_DONE_FAIL_HISTORY
dp_soc_msdu_done_fail_history_attach(struct dp_soc * soc)3476  static void dp_soc_msdu_done_fail_history_attach(struct dp_soc *soc)
3477  {
3478  	soc->msdu_done_fail_hist =
3479  		qdf_mem_malloc(sizeof(struct dp_msdu_done_fail_history));
3480  	if (soc->msdu_done_fail_hist)
3481  		qdf_atomic_init(&soc->msdu_done_fail_hist->index);
3482  }
3483  
dp_soc_msdu_done_fail_history_detach(struct dp_soc * soc)3484  static void dp_soc_msdu_done_fail_history_detach(struct dp_soc *soc)
3485  {
3486  	if (soc->msdu_done_fail_hist)
3487  		qdf_mem_free(soc->msdu_done_fail_hist);
3488  }
3489  #else
dp_soc_msdu_done_fail_history_attach(struct dp_soc * soc)3490  static inline void dp_soc_msdu_done_fail_history_attach(struct dp_soc *soc)
3491  {
3492  }
3493  
dp_soc_msdu_done_fail_history_detach(struct dp_soc * soc)3494  static inline void dp_soc_msdu_done_fail_history_detach(struct dp_soc *soc)
3495  {
3496  }
3497  #endif
3498  
3499  #ifdef DP_RX_PEEK_MSDU_DONE_WAR
dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc * soc)3500  static void dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc *soc)
3501  {
3502  	qdf_atomic_init(&soc->msdu_done_fail_desc_list.index);
3503  	qdf_atomic_set(&soc->msdu_done_fail_desc_list.index,
3504  		       DP_MSDU_DONE_FAIL_DESCS_MAX - 1);
3505  }
3506  #else
dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc * soc)3507  static void dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc *soc)
3508  {
3509  }
3510  #endif
3511  
3512  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
3513  QDF_STATUS
dp_rx_fst_attach_wrapper(struct dp_soc * soc,struct dp_pdev * pdev)3514  dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev)
3515  {
3516  	struct dp_rx_fst *rx_fst = NULL;
3517  	QDF_STATUS ret = QDF_STATUS_SUCCESS;
3518  
3519  	/* for Lithium the below API is not registered
3520  	 * hence fst attach happens for each pdev
3521  	 */
3522  	if (!soc->arch_ops.dp_get_rx_fst)
3523  		return dp_rx_fst_attach(soc, pdev);
3524  
3525  	rx_fst = soc->arch_ops.dp_get_rx_fst();
3526  
3527  	/* for BE the FST attach is called only once per
3528  	 * ML context. if rx_fst is already registered
3529  	 * increase the ref count and return.
3530  	 */
3531  	if (rx_fst) {
3532  		soc->rx_fst = rx_fst;
3533  		pdev->rx_fst = rx_fst;
3534  		soc->arch_ops.dp_rx_fst_ref();
3535  	} else {
3536  		ret = dp_rx_fst_attach(soc, pdev);
3537  		if ((ret != QDF_STATUS_SUCCESS) &&
3538  		    (ret != QDF_STATUS_E_NOSUPPORT))
3539  			return ret;
3540  
3541  		soc->arch_ops.dp_set_rx_fst(soc->rx_fst);
3542  		soc->arch_ops.dp_rx_fst_ref();
3543  	}
3544  	return ret;
3545  }
3546  
3547  void
dp_rx_fst_detach_wrapper(struct dp_soc * soc,struct dp_pdev * pdev)3548  dp_rx_fst_detach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev)
3549  {
3550  	struct dp_rx_fst *rx_fst = NULL;
3551  
3552  	/* for Lithium the below API is not registered
3553  	 * hence fst detach happens for each pdev
3554  	 */
3555  	if (!soc->arch_ops.dp_get_rx_fst) {
3556  		dp_rx_fst_detach(soc, pdev);
3557  		return;
3558  	}
3559  
3560  	rx_fst = soc->arch_ops.dp_get_rx_fst();
3561  
3562  	/* for BE the FST detach is called only when last
3563  	 * ref count reaches 1.
3564  	 */
3565  	if (rx_fst) {
3566  		if (soc->arch_ops.dp_rx_fst_deref() == 1)
3567  			dp_rx_fst_detach(soc, pdev);
3568  	}
3569  	pdev->rx_fst = NULL;
3570  }
3571  #else
3572  QDF_STATUS
dp_rx_fst_attach_wrapper(struct dp_soc * soc,struct dp_pdev * pdev)3573  dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev)
3574  {
3575  	return QDF_STATUS_SUCCESS;
3576  }
3577  
3578  void
dp_rx_fst_detach_wrapper(struct dp_soc * soc,struct dp_pdev * pdev)3579  dp_rx_fst_detach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev)
3580  {
3581  }
3582  #endif
3583  
3584  /**
3585   * dp_pdev_attach_wifi3() - attach txrx pdev
3586   * @txrx_soc: Datapath SOC handle
3587   * @params: Params for PDEV attach
3588   *
3589   * Return: QDF_STATUS
3590   */
3591  static inline
dp_pdev_attach_wifi3(struct cdp_soc_t * txrx_soc,struct cdp_pdev_attach_params * params)3592  QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
3593  				struct cdp_pdev_attach_params *params)
3594  {
3595  	qdf_size_t pdev_context_size;
3596  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
3597  	struct dp_pdev *pdev = NULL;
3598  	uint8_t pdev_id = params->pdev_id;
3599  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
3600  	int nss_cfg;
3601  	QDF_STATUS ret;
3602  
3603  	pdev_context_size =
3604  		soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_PDEV);
3605  	if (pdev_context_size)
3606  		pdev = dp_context_alloc_mem(soc, DP_PDEV_TYPE,
3607  					    pdev_context_size);
3608  
3609  	if (!pdev) {
3610  		dp_init_err("%pK: DP PDEV memory allocation failed",
3611  			    soc);
3612  		goto fail0;
3613  	}
3614  	wlan_minidump_log(pdev, sizeof(*pdev), soc->ctrl_psoc,
3615  			  WLAN_MD_DP_PDEV, "dp_pdev");
3616  
3617  	soc_cfg_ctx = soc->wlan_cfg_ctx;
3618  	pdev->wlan_cfg_ctx = wlan_cfg_pdev_attach(soc->ctrl_psoc);
3619  
3620  	if (!pdev->wlan_cfg_ctx) {
3621  		dp_init_err("%pK: pdev cfg_attach failed", soc);
3622  		goto fail1;
3623  	}
3624  
3625  	pdev->soc = soc;
3626  	pdev->pdev_id = pdev_id;
3627  	soc->pdev_list[pdev_id] = pdev;
3628  	pdev->lmac_id = wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, pdev_id);
3629  	soc->pdev_count++;
3630  
3631  	dp_ssr_dump_pdev_register(pdev, pdev_id);
3632  
3633  	/*sync DP pdev cfg items with profile support after cfg_pdev_attach*/
3634  	wlan_dp_pdev_cfg_sync_profile((struct cdp_soc_t *)soc, pdev_id);
3635  
3636  	/*
3637  	 * set nss pdev config based on soc config
3638  	 */
3639  	nss_cfg = wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx);
3640  	wlan_cfg_set_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx,
3641  					 (nss_cfg & (1 << pdev_id)));
3642  
3643  	/* Allocate memory for pdev srng rings */
3644  	if (dp_pdev_srng_alloc(pdev)) {
3645  		dp_init_err("%pK: dp_pdev_srng_alloc failed", soc);
3646  		goto fail2;
3647  	}
3648  
3649  	/* Setup second Rx refill buffer ring */
3650  	if (dp_setup_ipa_rx_refill_buf_ring(soc, pdev)) {
3651  		dp_init_err("%pK: dp_srng_alloc failed rxrefill2 ring",
3652  			    soc);
3653  		goto fail3;
3654  	}
3655  
3656  	/* Allocate memory for pdev rxdma rings */
3657  	if (dp_rxdma_ring_alloc(soc, pdev)) {
3658  		dp_init_err("%pK: dp_rxdma_ring_alloc failed", soc);
3659  		goto fail4;
3660  	}
3661  
3662  	/* Rx specific init */
3663  	if (dp_rx_pdev_desc_pool_alloc(pdev)) {
3664  		dp_init_err("%pK: dp_rx_pdev_attach failed", soc);
3665  		goto fail4;
3666  	}
3667  
3668  	if (dp_monitor_pdev_attach(pdev)) {
3669  		dp_init_err("%pK: dp_monitor_pdev_attach failed", soc);
3670  		goto fail5;
3671  	}
3672  
3673  	soc->arch_ops.txrx_pdev_attach(pdev, params);
3674  
3675  	/* Setup third Rx refill buffer ring */
3676  	if (dp_setup_ipa_rx_alt_refill_buf_ring(soc, pdev)) {
3677  		dp_init_err("%pK: dp_srng_alloc failed rxrefill3 ring",
3678  			    soc);
3679  		goto fail6;
3680  	}
3681  
3682  	ret = dp_rx_fst_attach_wrapper(soc, pdev);
3683  	if ((ret != QDF_STATUS_SUCCESS) && (ret != QDF_STATUS_E_NOSUPPORT)) {
3684  		dp_init_err("%pK: RX FST attach failed: pdev %d err %d",
3685  			    soc, pdev_id, ret);
3686  		goto fail7;
3687  	}
3688  
3689  	return QDF_STATUS_SUCCESS;
3690  
3691  fail7:
3692  	dp_free_ipa_rx_alt_refill_buf_ring(soc, pdev);
3693  fail6:
3694  	dp_monitor_pdev_detach(pdev);
3695  fail5:
3696  	dp_rx_pdev_desc_pool_free(pdev);
3697  fail4:
3698  	dp_rxdma_ring_free(pdev);
3699  	dp_free_ipa_rx_refill_buf_ring(soc, pdev);
3700  fail3:
3701  	dp_pdev_srng_free(pdev);
3702  fail2:
3703  	wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx);
3704  fail1:
3705  	soc->pdev_list[pdev_id] = NULL;
3706  	qdf_mem_free(pdev);
3707  fail0:
3708  	return QDF_STATUS_E_FAILURE;
3709  }
3710  
3711  /**
3712   * dp_pdev_flush_pending_vdevs() - Flush all delete pending vdevs in pdev
3713   * @pdev: Datapath PDEV handle
3714   *
3715   * This is the last chance to flush all pending dp vdevs/peers,
3716   * some peer/vdev leak case like Non-SSR + peer unmap missing
3717   * will be covered here.
3718   *
3719   * Return: None
3720   */
dp_pdev_flush_pending_vdevs(struct dp_pdev * pdev)3721  static void dp_pdev_flush_pending_vdevs(struct dp_pdev *pdev)
3722  {
3723  	struct dp_soc *soc = pdev->soc;
3724  	struct dp_vdev *vdev_arr[MAX_VDEV_CNT] = {0};
3725  	uint32_t i = 0;
3726  	uint32_t num_vdevs = 0;
3727  	struct dp_vdev *vdev = NULL;
3728  
3729  	if (TAILQ_EMPTY(&soc->inactive_vdev_list))
3730  		return;
3731  
3732  	qdf_spin_lock_bh(&soc->inactive_vdev_list_lock);
3733  	TAILQ_FOREACH(vdev, &soc->inactive_vdev_list,
3734  		      inactive_list_elem) {
3735  		if (vdev->pdev != pdev)
3736  			continue;
3737  
3738  		vdev_arr[num_vdevs] = vdev;
3739  		num_vdevs++;
3740  		/* take reference to free */
3741  		dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CDP);
3742  	}
3743  	qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock);
3744  
3745  	for (i = 0; i < num_vdevs; i++) {
3746  		dp_vdev_flush_peers((struct cdp_vdev *)vdev_arr[i], 0, 0);
3747  		dp_vdev_unref_delete(soc, vdev_arr[i], DP_MOD_ID_CDP);
3748  	}
3749  }
3750  
3751  #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
3752  /**
3753   * dp_vdev_stats_hw_offload_target_config() - Send HTT command to FW
3754   *                                          for enable/disable of HW vdev stats
3755   * @soc: Datapath soc handle
3756   * @pdev_id: INVALID_PDEV_ID for all pdevs or 0,1,2 for individual pdev
3757   * @enable: flag to represent enable/disable of hw vdev stats
3758   *
3759   * Return: none
3760   */
dp_vdev_stats_hw_offload_target_config(struct dp_soc * soc,uint8_t pdev_id,bool enable)3761  static void dp_vdev_stats_hw_offload_target_config(struct dp_soc *soc,
3762  						   uint8_t pdev_id,
3763  						   bool enable)
3764  {
3765  	/* Check SOC level config for HW offload vdev stats support */
3766  	if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) {
3767  		dp_debug("%pK: HW vdev offload stats is disabled", soc);
3768  		return;
3769  	}
3770  
3771  	/* Send HTT command to FW for enable of stats */
3772  	dp_h2t_hw_vdev_stats_config_send(soc, pdev_id, enable, false, 0);
3773  }
3774  
3775  /**
3776   * dp_vdev_stats_hw_offload_target_clear() - Clear HW vdev stats on target
3777   * @soc: Datapath soc handle
3778   * @pdev_id: pdev_id (0,1,2)
3779   * @vdev_id_bitmask: bitmask with vdev_id(s) for which stats are to be
3780   *                   cleared on HW
3781   *
3782   * Return: none
3783   */
3784  static
dp_vdev_stats_hw_offload_target_clear(struct dp_soc * soc,uint8_t pdev_id,uint64_t vdev_id_bitmask)3785  void dp_vdev_stats_hw_offload_target_clear(struct dp_soc *soc, uint8_t pdev_id,
3786  					   uint64_t vdev_id_bitmask)
3787  {
3788  	/* Check SOC level config for HW offload vdev stats support */
3789  	if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) {
3790  		dp_debug("%pK: HW vdev offload stats is disabled", soc);
3791  		return;
3792  	}
3793  
3794  	/* Send HTT command to FW for reset of stats */
3795  	dp_h2t_hw_vdev_stats_config_send(soc, pdev_id, true, true,
3796  					 vdev_id_bitmask);
3797  }
3798  #else
3799  static void
dp_vdev_stats_hw_offload_target_config(struct dp_soc * soc,uint8_t pdev_id,bool enable)3800  dp_vdev_stats_hw_offload_target_config(struct dp_soc *soc, uint8_t pdev_id,
3801  				       bool enable)
3802  {
3803  }
3804  
3805  static
dp_vdev_stats_hw_offload_target_clear(struct dp_soc * soc,uint8_t pdev_id,uint64_t vdev_id_bitmask)3806  void dp_vdev_stats_hw_offload_target_clear(struct dp_soc *soc, uint8_t pdev_id,
3807  					   uint64_t vdev_id_bitmask)
3808  {
3809  }
3810  #endif /*QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT */
3811  
3812  /**
3813   * dp_pdev_deinit() - Deinit txrx pdev
3814   * @txrx_pdev: Datapath PDEV handle
3815   * @force: Force deinit
3816   *
3817   * Return: None
3818   */
dp_pdev_deinit(struct cdp_pdev * txrx_pdev,int force)3819  static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force)
3820  {
3821  	struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev;
3822  	qdf_nbuf_t curr_nbuf, next_nbuf;
3823  
3824  	if (pdev->pdev_deinit)
3825  		return;
3826  
3827  	dp_tx_me_exit(pdev);
3828  	dp_rx_pdev_buffers_free(pdev);
3829  	dp_rx_pdev_desc_pool_deinit(pdev);
3830  	dp_pdev_bkp_stats_detach(pdev);
3831  	qdf_event_destroy(&pdev->fw_peer_stats_event);
3832  	qdf_event_destroy(&pdev->fw_stats_event);
3833  	qdf_event_destroy(&pdev->fw_obss_stats_event);
3834  	if (pdev->sojourn_buf)
3835  		qdf_nbuf_free(pdev->sojourn_buf);
3836  
3837  	dp_pdev_flush_pending_vdevs(pdev);
3838  	dp_tx_desc_flush(pdev, NULL, true);
3839  
3840  	qdf_spinlock_destroy(&pdev->tx_mutex);
3841  	qdf_spinlock_destroy(&pdev->vdev_list_lock);
3842  
3843  	dp_monitor_pdev_deinit(pdev);
3844  
3845  	dp_pdev_srng_deinit(pdev);
3846  
3847  	dp_ipa_uc_detach(pdev->soc, pdev);
3848  	dp_deinit_ipa_rx_alt_refill_buf_ring(pdev->soc, pdev);
3849  	dp_deinit_ipa_rx_refill_buf_ring(pdev->soc, pdev);
3850  	dp_rxdma_ring_cleanup(pdev->soc, pdev);
3851  
3852  	curr_nbuf = pdev->invalid_peer_head_msdu;
3853  	while (curr_nbuf) {
3854  		next_nbuf = qdf_nbuf_next(curr_nbuf);
3855  		dp_rx_nbuf_free(curr_nbuf);
3856  		curr_nbuf = next_nbuf;
3857  	}
3858  	pdev->invalid_peer_head_msdu = NULL;
3859  	pdev->invalid_peer_tail_msdu = NULL;
3860  
3861  	dp_wdi_event_detach(pdev);
3862  	pdev->pdev_deinit = 1;
3863  }
3864  
3865  /**
3866   * dp_pdev_deinit_wifi3() - Deinit txrx pdev
3867   * @psoc: Datapath psoc handle
3868   * @pdev_id: Id of datapath PDEV handle
3869   * @force: Force deinit
3870   *
3871   * Return: QDF_STATUS
3872   */
3873  static QDF_STATUS
dp_pdev_deinit_wifi3(struct cdp_soc_t * psoc,uint8_t pdev_id,int force)3874  dp_pdev_deinit_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id,
3875  		     int force)
3876  {
3877  	struct dp_pdev *txrx_pdev;
3878  
3879  	txrx_pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc,
3880  						       pdev_id);
3881  
3882  	if (!txrx_pdev)
3883  		return QDF_STATUS_E_FAILURE;
3884  
3885  	dp_pdev_deinit((struct cdp_pdev *)txrx_pdev, force);
3886  
3887  	return QDF_STATUS_SUCCESS;
3888  }
3889  
3890  /**
3891   * dp_pdev_post_attach() - Do post pdev attach after dev_alloc_name
3892   * @txrx_pdev: Datapath PDEV handle
3893   *
3894   * Return: None
3895   */
dp_pdev_post_attach(struct cdp_pdev * txrx_pdev)3896  static void dp_pdev_post_attach(struct cdp_pdev *txrx_pdev)
3897  {
3898  	struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev;
3899  
3900  	dp_monitor_tx_capture_debugfs_init(pdev);
3901  
3902  	if (dp_pdev_htt_stats_dbgfs_init(pdev)) {
3903  		dp_init_err("%pK: Failed to initialize pdev HTT stats debugfs", pdev->soc);
3904  	}
3905  }
3906  
3907  /**
3908   * dp_pdev_post_attach_wifi3() - attach txrx pdev post
3909   * @soc: Datapath soc handle
3910   * @pdev_id: pdev id of pdev
3911   *
3912   * Return: QDF_STATUS
3913   */
dp_pdev_post_attach_wifi3(struct cdp_soc_t * soc,uint8_t pdev_id)3914  static int dp_pdev_post_attach_wifi3(struct cdp_soc_t *soc,
3915  				     uint8_t pdev_id)
3916  {
3917  	struct dp_pdev *pdev;
3918  
3919  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
3920  						  pdev_id);
3921  
3922  	if (!pdev) {
3923  		dp_init_err("%pK: DP PDEV is Null for pdev id %d",
3924  			    (struct dp_soc *)soc, pdev_id);
3925  		return QDF_STATUS_E_FAILURE;
3926  	}
3927  
3928  	dp_pdev_post_attach((struct cdp_pdev *)pdev);
3929  	return QDF_STATUS_SUCCESS;
3930  }
3931  
3932  /**
3933   * dp_pdev_detach() - Complete rest of pdev detach
3934   * @txrx_pdev: Datapath PDEV handle
3935   * @force: Force deinit
3936   *
3937   * Return: None
3938   */
dp_pdev_detach(struct cdp_pdev * txrx_pdev,int force)3939  static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force)
3940  {
3941  	struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev;
3942  	struct dp_soc *soc = pdev->soc;
3943  
3944  	dp_rx_fst_detach_wrapper(soc, pdev);
3945  	dp_pdev_htt_stats_dbgfs_deinit(pdev);
3946  	dp_rx_pdev_desc_pool_free(pdev);
3947  	dp_monitor_pdev_detach(pdev);
3948  	dp_rxdma_ring_free(pdev);
3949  	dp_free_ipa_rx_refill_buf_ring(soc, pdev);
3950  	dp_free_ipa_rx_alt_refill_buf_ring(soc, pdev);
3951  	dp_pdev_srng_free(pdev);
3952  
3953  	soc->pdev_count--;
3954  	soc->pdev_list[pdev->pdev_id] = NULL;
3955  
3956  	wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx);
3957  	wlan_minidump_remove(pdev, sizeof(*pdev), soc->ctrl_psoc,
3958  			     WLAN_MD_DP_PDEV, "dp_pdev");
3959  	dp_context_free_mem(soc, DP_PDEV_TYPE, pdev);
3960  }
3961  
3962  /**
3963   * dp_pdev_detach_wifi3() - detach txrx pdev
3964   * @psoc: Datapath soc handle
3965   * @pdev_id: pdev id of pdev
3966   * @force: Force detach
3967   *
3968   * Return: QDF_STATUS
3969   */
dp_pdev_detach_wifi3(struct cdp_soc_t * psoc,uint8_t pdev_id,int force)3970  static QDF_STATUS dp_pdev_detach_wifi3(struct cdp_soc_t *psoc, uint8_t pdev_id,
3971  				       int force)
3972  {
3973  	struct dp_pdev *pdev;
3974  	struct dp_soc *soc = (struct dp_soc *)psoc;
3975  
3976  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)psoc,
3977  						  pdev_id);
3978  
3979  	if (!pdev) {
3980  		dp_init_err("%pK: DP PDEV is Null for pdev id %d",
3981  			    (struct dp_soc *)psoc, pdev_id);
3982  		return QDF_STATUS_E_FAILURE;
3983  	}
3984  
3985  	dp_ssr_dump_pdev_unregister(pdev_id);
3986  
3987  	soc->arch_ops.txrx_pdev_detach(pdev);
3988  
3989  	dp_pdev_detach((struct cdp_pdev *)pdev, force);
3990  	return QDF_STATUS_SUCCESS;
3991  }
3992  
dp_soc_print_inactive_objects(struct dp_soc * soc)3993  void dp_soc_print_inactive_objects(struct dp_soc *soc)
3994  {
3995  	struct dp_peer *peer = NULL;
3996  	struct dp_peer *tmp_peer = NULL;
3997  	struct dp_vdev *vdev = NULL;
3998  	struct dp_vdev *tmp_vdev = NULL;
3999  	int i = 0;
4000  	uint32_t count;
4001  
4002  	if (TAILQ_EMPTY(&soc->inactive_peer_list) &&
4003  	    TAILQ_EMPTY(&soc->inactive_vdev_list))
4004  		return;
4005  
4006  	TAILQ_FOREACH_SAFE(peer, &soc->inactive_peer_list,
4007  			   inactive_list_elem, tmp_peer) {
4008  		for (i = 0; i < DP_MOD_ID_MAX; i++) {
4009  			count = qdf_atomic_read(&peer->mod_refs[i]);
4010  			if (count)
4011  				DP_PRINT_STATS("peer %pK Module id %u ==> %u",
4012  					       peer, i, count);
4013  		}
4014  	}
4015  
4016  	TAILQ_FOREACH_SAFE(vdev, &soc->inactive_vdev_list,
4017  			   inactive_list_elem, tmp_vdev) {
4018  		for (i = 0; i < DP_MOD_ID_MAX; i++) {
4019  			count = qdf_atomic_read(&vdev->mod_refs[i]);
4020  			if (count)
4021  				DP_PRINT_STATS("vdev %pK Module id %u ==> %u",
4022  					       vdev, i, count);
4023  		}
4024  	}
4025  	QDF_BUG(0);
4026  }
4027  
4028  /**
4029   * dp_soc_deinit_wifi3() - Deinitialize txrx SOC
4030   * @txrx_soc: Opaque DP SOC handle
4031   *
4032   * Return: None
4033   */
dp_soc_deinit_wifi3(struct cdp_soc_t * txrx_soc)4034  static void dp_soc_deinit_wifi3(struct cdp_soc_t *txrx_soc)
4035  {
4036  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
4037  
4038  	soc->arch_ops.txrx_soc_deinit(soc);
4039  }
4040  
4041  /**
4042   * dp_soc_detach() - Detach rest of txrx SOC
4043   * @txrx_soc: DP SOC handle, struct cdp_soc_t is first element of struct dp_soc.
4044   *
4045   * Return: None
4046   */
dp_soc_detach(struct cdp_soc_t * txrx_soc)4047  static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
4048  {
4049  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
4050  
4051  	soc->arch_ops.txrx_soc_detach(soc);
4052  
4053  	qdf_ssr_driver_dump_unregister_region("wlan_cfg_ctx");
4054  	qdf_ssr_driver_dump_unregister_region("dp_soc");
4055  	qdf_ssr_driver_dump_unregister_region("tcl_wbm_map_array");
4056  	qdf_nbuf_ssr_unregister_region();
4057  
4058  	dp_runtime_deinit();
4059  
4060  	dp_soc_unset_qref_debug_list(soc);
4061  	dp_sysfs_deinitialize_stats(soc);
4062  	dp_soc_swlm_detach(soc);
4063  	dp_soc_tx_desc_sw_pools_free(soc);
4064  	dp_soc_srng_free(soc);
4065  	dp_hw_link_desc_ring_free(soc);
4066  	dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID);
4067  	wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
4068  	dp_soc_tx_hw_desc_history_detach(soc);
4069  	dp_soc_tx_history_detach(soc);
4070  	dp_soc_mon_status_ring_history_detach(soc);
4071  	dp_soc_rx_history_detach(soc);
4072  	dp_soc_cfg_history_detach(soc);
4073  	dp_soc_msdu_done_fail_history_detach(soc);
4074  
4075  	if (!dp_monitor_modularized_enable()) {
4076  		dp_mon_soc_detach_wrapper(soc);
4077  	}
4078  
4079  	qdf_mem_free(soc->cdp_soc.ops);
4080  	qdf_mem_common_free(soc);
4081  }
4082  
4083  /**
4084   * dp_soc_detach_wifi3() - Detach txrx SOC
4085   * @txrx_soc: DP SOC handle, struct cdp_soc_t is first element of struct dp_soc.
4086   *
4087   * Return: None
4088   */
dp_soc_detach_wifi3(struct cdp_soc_t * txrx_soc)4089  static void dp_soc_detach_wifi3(struct cdp_soc_t *txrx_soc)
4090  {
4091  	dp_soc_detach(txrx_soc);
4092  }
4093  
4094  #ifdef QCA_HOST2FW_RXBUF_RING
4095  #ifdef IPA_WDI3_VLAN_SUPPORT
4096  static inline
dp_rxdma_setup_refill_ring3(struct dp_soc * soc,struct dp_pdev * pdev,uint8_t idx)4097  void dp_rxdma_setup_refill_ring3(struct dp_soc *soc,
4098  				 struct dp_pdev *pdev,
4099  				 uint8_t idx)
4100  {
4101  	if (pdev->rx_refill_buf_ring3.hal_srng)
4102  		htt_srng_setup(soc->htt_handle, idx,
4103  			       pdev->rx_refill_buf_ring3.hal_srng,
4104  			       RXDMA_BUF);
4105  }
4106  #else
4107  static inline
dp_rxdma_setup_refill_ring3(struct dp_soc * soc,struct dp_pdev * pdev,uint8_t idx)4108  void dp_rxdma_setup_refill_ring3(struct dp_soc *soc,
4109  				 struct dp_pdev *pdev,
4110  				 uint8_t idx)
4111  { }
4112  #endif
4113  
4114  #ifdef WIFI_MONITOR_SUPPORT
dp_lpc_tx_config(struct dp_pdev * pdev)4115  static inline QDF_STATUS dp_lpc_tx_config(struct dp_pdev *pdev)
4116  {
4117  	return dp_local_pkt_capture_tx_config(pdev);
4118  }
4119  #else
dp_lpc_tx_config(struct dp_pdev * pdev)4120  static inline QDF_STATUS dp_lpc_tx_config(struct dp_pdev *pdev)
4121  {
4122  	return QDF_STATUS_SUCCESS;
4123  }
4124  #endif
4125  
4126  /**
4127   * dp_rxdma_ring_config() - configure the RX DMA rings
4128   * @soc: data path SoC handle
4129   *
4130   * This function is used to configure the MAC rings.
4131   * On MCL host provides buffers in Host2FW ring
4132   * FW refills (copies) buffers to the ring and updates
4133   * ring_idx in register
4134   *
4135   * Return: zero on success, non-zero on failure
4136   */
dp_rxdma_ring_config(struct dp_soc * soc)4137  static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
4138  {
4139  	int i;
4140  	QDF_STATUS status = QDF_STATUS_SUCCESS;
4141  
4142  	for (i = 0; i < MAX_PDEV_CNT; i++) {
4143  		struct dp_pdev *pdev = soc->pdev_list[i];
4144  
4145  		if (pdev) {
4146  			int mac_id;
4147  			int max_mac_rings =
4148  				 wlan_cfg_get_num_mac_rings
4149  				(pdev->wlan_cfg_ctx);
4150  			int lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i);
4151  
4152  			htt_srng_setup(soc->htt_handle, i,
4153  				       soc->rx_refill_buf_ring[lmac_id]
4154  				       .hal_srng,
4155  				       RXDMA_BUF);
4156  
4157  			if (pdev->rx_refill_buf_ring2.hal_srng)
4158  				htt_srng_setup(soc->htt_handle, i,
4159  					       pdev->rx_refill_buf_ring2
4160  					       .hal_srng,
4161  					       RXDMA_BUF);
4162  
4163  			dp_rxdma_setup_refill_ring3(soc, pdev, i);
4164  
4165  			dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings);
4166  			dp_lpc_tx_config(pdev);
4167  			dp_info("pdev_id %d max_mac_rings %d",
4168  			       pdev->pdev_id, max_mac_rings);
4169  
4170  			for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
4171  				int mac_for_pdev =
4172  					dp_get_mac_id_for_pdev(mac_id,
4173  							       pdev->pdev_id);
4174  				/*
4175  				 * Obtain lmac id from pdev to access the LMAC
4176  				 * ring in soc context
4177  				 */
4178  				lmac_id =
4179  				dp_get_lmac_id_for_pdev_id(soc,
4180  							   mac_id,
4181  							   pdev->pdev_id);
4182  				dp_info("mac_id %d", mac_for_pdev);
4183  
4184  				htt_srng_setup(soc->htt_handle, mac_for_pdev,
4185  					 pdev->rx_mac_buf_ring[mac_id]
4186  						.hal_srng,
4187  					 RXDMA_BUF);
4188  
4189  				if (!soc->rxdma2sw_rings_not_supported)
4190  					dp_htt_setup_rxdma_err_dst_ring(soc,
4191  						mac_for_pdev, lmac_id);
4192  
4193  				/* Configure monitor mode rings */
4194  				status = dp_monitor_htt_srng_setup(soc, pdev,
4195  								   lmac_id,
4196  								   mac_for_pdev);
4197  				if (status != QDF_STATUS_SUCCESS) {
4198  					dp_err("Failed to send htt monitor messages to target");
4199  					return status;
4200  				}
4201  
4202  			}
4203  		}
4204  	}
4205  
4206  	dp_reap_timer_init(soc);
4207  	return status;
4208  }
4209  #else
4210  /* This is only for WIN */
dp_rxdma_ring_config(struct dp_soc * soc)4211  static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
4212  {
4213  	int i;
4214  	QDF_STATUS status = QDF_STATUS_SUCCESS;
4215  	int mac_for_pdev;
4216  	int lmac_id;
4217  
4218  	/* Configure monitor mode rings */
4219  	dp_monitor_soc_htt_srng_setup(soc);
4220  
4221  	for (i = 0; i < MAX_PDEV_CNT; i++) {
4222  		struct dp_pdev *pdev =  soc->pdev_list[i];
4223  
4224  		if (!pdev)
4225  			continue;
4226  
4227  		mac_for_pdev = i;
4228  		lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, i);
4229  
4230  		if (soc->rx_refill_buf_ring[lmac_id].hal_srng)
4231  			htt_srng_setup(soc->htt_handle, mac_for_pdev,
4232  				       soc->rx_refill_buf_ring[lmac_id].
4233  				       hal_srng, RXDMA_BUF);
4234  
4235  		/* Configure monitor mode rings */
4236  		dp_monitor_htt_srng_setup(soc, pdev,
4237  					  lmac_id,
4238  					  mac_for_pdev);
4239  		if (!soc->rxdma2sw_rings_not_supported)
4240  			htt_srng_setup(soc->htt_handle, mac_for_pdev,
4241  				       soc->rxdma_err_dst_ring[lmac_id].hal_srng,
4242  				       RXDMA_DST);
4243  	}
4244  
4245  	dp_reap_timer_init(soc);
4246  	return status;
4247  }
4248  #endif
4249  
4250  /**
4251   * dp_rx_target_fst_config() - configure the RXOLE Flow Search Engine
4252   *
4253   * This function is used to configure the FSE HW block in RX OLE on a
4254   * per pdev basis. Here, we will be programming parameters related to
4255   * the Flow Search Table.
4256   *
4257   * @soc: data path SoC handle
4258   *
4259   * Return: zero on success, non-zero on failure
4260   */
4261  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
4262  static QDF_STATUS
dp_rx_target_fst_config(struct dp_soc * soc)4263  dp_rx_target_fst_config(struct dp_soc *soc)
4264  {
4265  	int i;
4266  	QDF_STATUS status = QDF_STATUS_SUCCESS;
4267  
4268  	for (i = 0; i < MAX_PDEV_CNT; i++) {
4269  		struct dp_pdev *pdev = soc->pdev_list[i];
4270  
4271  		/* Flow search is not enabled if NSS offload is enabled */
4272  		if (pdev &&
4273  		    !wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) {
4274  			status = dp_rx_flow_send_fst_fw_setup(pdev->soc, pdev);
4275  			if (status != QDF_STATUS_SUCCESS)
4276  				break;
4277  		}
4278  	}
4279  	return status;
4280  }
4281  #else
dp_rx_target_fst_config(struct dp_soc * soc)4282  static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc)
4283  {
4284  	return QDF_STATUS_SUCCESS;
4285  }
4286  #endif
4287  
4288  #ifndef WLAN_DP_FEATURE_SW_LATENCY_MGR
dp_print_swlm_stats(struct dp_soc * soc)4289  static inline QDF_STATUS dp_print_swlm_stats(struct dp_soc *soc)
4290  {
4291  	return QDF_STATUS_SUCCESS;
4292  }
4293  #endif /* !WLAN_DP_FEATURE_SW_LATENCY_MGR */
4294  
4295  #ifdef WLAN_SUPPORT_PPEDS
4296  /**
4297   * dp_soc_target_ppe_rxole_rxdma_cfg() - Configure the RxOLe and RxDMA for PPE
4298   * @soc: DP Tx/Rx handle
4299   *
4300   * Return: QDF_STATUS
4301   */
4302  static
dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc * soc)4303  QDF_STATUS dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc *soc)
4304  {
4305  	struct dp_htt_rxdma_rxole_ppe_config htt_cfg = {0};
4306  	QDF_STATUS status;
4307  
4308  	/*
4309  	 * Program RxDMA to override the reo destination indication
4310  	 * with REO2PPE_DST_IND, when use_ppe is set to 1 in RX_MSDU_END,
4311  	 * thereby driving the packet to REO2PPE ring.
4312  	 * If the MSDU is spanning more than 1 buffer, then this
4313  	 * override is not done.
4314  	 */
4315  	htt_cfg.override = 1;
4316  	htt_cfg.reo_destination_indication = REO2PPE_DST_IND;
4317  	htt_cfg.multi_buffer_msdu_override_en = 0;
4318  
4319  	/*
4320  	 * Override use_ppe to 0 in RxOLE for the following
4321  	 * cases.
4322  	 */
4323  	htt_cfg.intra_bss_override = 1;
4324  	htt_cfg.decap_raw_override = 1;
4325  	htt_cfg.decap_nwifi_override = 1;
4326  	htt_cfg.ip_frag_override = 1;
4327  
4328  	status = dp_htt_rxdma_rxole_ppe_cfg_set(soc, &htt_cfg);
4329  	if (status != QDF_STATUS_SUCCESS)
4330  		dp_err("RxOLE and RxDMA PPE config failed %d", status);
4331  
4332  	return status;
4333  }
4334  
4335  #else
4336  static inline
dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc * soc)4337  QDF_STATUS dp_soc_target_ppe_rxole_rxdma_cfg(struct dp_soc *soc)
4338  {
4339  	return QDF_STATUS_SUCCESS;
4340  }
4341  
4342  #endif /* WLAN_SUPPORT_PPEDS */
4343  
4344  #ifdef DP_UMAC_HW_RESET_SUPPORT
dp_register_umac_reset_handlers(struct dp_soc * soc)4345  static void dp_register_umac_reset_handlers(struct dp_soc *soc)
4346  {
4347  	dp_umac_reset_register_rx_action_callback(soc,
4348  					dp_umac_reset_action_trigger_recovery,
4349  					UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY);
4350  
4351  	dp_umac_reset_register_rx_action_callback(soc,
4352  		dp_umac_reset_handle_pre_reset, UMAC_RESET_ACTION_DO_PRE_RESET);
4353  
4354  	dp_umac_reset_register_rx_action_callback(soc,
4355  					dp_umac_reset_handle_post_reset,
4356  					UMAC_RESET_ACTION_DO_POST_RESET_START);
4357  
4358  	dp_umac_reset_register_rx_action_callback(soc,
4359  				dp_umac_reset_handle_post_reset_complete,
4360  				UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE);
4361  
4362  }
4363  #else
dp_register_umac_reset_handlers(struct dp_soc * soc)4364  static void dp_register_umac_reset_handlers(struct dp_soc *soc)
4365  {
4366  }
4367  #endif
4368  /**
4369   * dp_soc_attach_target_wifi3() - SOC initialization in the target
4370   * @cdp_soc: Opaque Datapath SOC handle
4371   *
4372   * Return: zero on success, non-zero on failure
4373   */
4374  static QDF_STATUS
dp_soc_attach_target_wifi3(struct cdp_soc_t * cdp_soc)4375  dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc)
4376  {
4377  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
4378  	QDF_STATUS status = QDF_STATUS_SUCCESS;
4379  	struct hal_reo_params reo_params;
4380  
4381  	htt_soc_attach_target(soc->htt_handle);
4382  
4383  	status = dp_soc_target_ppe_rxole_rxdma_cfg(soc);
4384  	if (status != QDF_STATUS_SUCCESS) {
4385  		dp_err("Failed to send htt RxOLE and RxDMA messages to target");
4386  		return status;
4387  	}
4388  
4389  	status = dp_rxdma_ring_config(soc);
4390  	if (status != QDF_STATUS_SUCCESS) {
4391  		dp_err("Failed to send htt srng setup messages to target");
4392  		return status;
4393  	}
4394  
4395  	status = soc->arch_ops.dp_rxdma_ring_sel_cfg(soc);
4396  	if (status != QDF_STATUS_SUCCESS) {
4397  		dp_err("Failed to send htt ring config message to target");
4398  		return status;
4399  	}
4400  
4401  	status = dp_soc_umac_reset_init(cdp_soc);
4402  	if (status != QDF_STATUS_SUCCESS &&
4403  	    status != QDF_STATUS_E_NOSUPPORT) {
4404  		dp_err("Failed to initialize UMAC reset");
4405  		return status;
4406  	}
4407  
4408  	dp_register_umac_reset_handlers(soc);
4409  
4410  	status = dp_rx_target_fst_config(soc);
4411  	if (status != QDF_STATUS_SUCCESS &&
4412  	    status != QDF_STATUS_E_NOSUPPORT) {
4413  		dp_err("Failed to send htt fst setup config message to target");
4414  		return status;
4415  	}
4416  
4417  	DP_STATS_INIT(soc);
4418  
4419  	dp_runtime_init(soc);
4420  
4421  	/* Enable HW vdev offload stats if feature is supported */
4422  	dp_vdev_stats_hw_offload_target_config(soc, INVALID_PDEV_ID, true);
4423  
4424  	/* initialize work queue for stats processing */
4425  	qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc);
4426  
4427  	wlan_cfg_soc_update_tgt_params(soc->wlan_cfg_ctx,
4428  				       soc->ctrl_psoc);
4429  	/* Setup HW REO */
4430  	qdf_mem_zero(&reo_params, sizeof(reo_params));
4431  
4432  	if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) {
4433  		/*
4434  		 * Reo ring remap is not required if both radios
4435  		 * are offloaded to NSS
4436  		 */
4437  
4438  		if (soc->arch_ops.reo_remap_config(soc, &reo_params.remap0,
4439  						   &reo_params.remap1,
4440  						   &reo_params.remap2))
4441  			reo_params.rx_hash_enabled = true;
4442  		else
4443  			reo_params.rx_hash_enabled = false;
4444  	}
4445  
4446  	/*
4447  	 * set the fragment destination ring
4448  	 */
4449  	dp_reo_frag_dst_set(soc, &reo_params.frag_dst_ring);
4450  
4451  	if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx))
4452  		reo_params.alt_dst_ind_0 = REO_REMAP_RELEASE;
4453  
4454  	reo_params.reo_qref = &soc->reo_qref;
4455  	hal_reo_setup(soc->hal_soc, &reo_params, 1);
4456  
4457  	hal_reo_set_err_dst_remap(soc->hal_soc);
4458  
4459  	soc->features.pn_in_reo_dest = hal_reo_enable_pn_in_dest(soc->hal_soc);
4460  
4461  	return QDF_STATUS_SUCCESS;
4462  }
4463  
4464  /**
4465   * dp_vdev_id_map_tbl_add() - Add vdev into vdev_id table
4466   * @soc: SoC handle
4467   * @vdev: vdev handle
4468   * @vdev_id: vdev_id
4469   *
4470   * Return: None
4471   */
dp_vdev_id_map_tbl_add(struct dp_soc * soc,struct dp_vdev * vdev,uint8_t vdev_id)4472  static void dp_vdev_id_map_tbl_add(struct dp_soc *soc,
4473  				   struct dp_vdev *vdev,
4474  				   uint8_t vdev_id)
4475  {
4476  	QDF_ASSERT(vdev_id <= MAX_VDEV_CNT);
4477  
4478  	qdf_spin_lock_bh(&soc->vdev_map_lock);
4479  
4480  	if (dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CONFIG) !=
4481  			QDF_STATUS_SUCCESS) {
4482  		dp_vdev_info("%pK: unable to get vdev reference at MAP vdev %pK vdev_id %u",
4483  			     soc, vdev, vdev_id);
4484  		qdf_spin_unlock_bh(&soc->vdev_map_lock);
4485  		return;
4486  	}
4487  
4488  	if (!soc->vdev_id_map[vdev_id])
4489  		soc->vdev_id_map[vdev_id] = vdev;
4490  	else
4491  		QDF_ASSERT(0);
4492  
4493  	qdf_spin_unlock_bh(&soc->vdev_map_lock);
4494  }
4495  
4496  /**
4497   * dp_vdev_id_map_tbl_remove() - remove vdev from vdev_id table
4498   * @soc: SoC handle
4499   * @vdev: vdev handle
4500   *
4501   * Return: None
4502   */
dp_vdev_id_map_tbl_remove(struct dp_soc * soc,struct dp_vdev * vdev)4503  static void dp_vdev_id_map_tbl_remove(struct dp_soc *soc,
4504  				      struct dp_vdev *vdev)
4505  {
4506  	qdf_spin_lock_bh(&soc->vdev_map_lock);
4507  	QDF_ASSERT(soc->vdev_id_map[vdev->vdev_id] == vdev);
4508  
4509  	soc->vdev_id_map[vdev->vdev_id] = NULL;
4510  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG);
4511  	qdf_spin_unlock_bh(&soc->vdev_map_lock);
4512  }
4513  
4514  /**
4515   * dp_vdev_pdev_list_add() - add vdev into pdev's list
4516   * @soc: soc handle
4517   * @pdev: pdev handle
4518   * @vdev: vdev handle
4519   *
4520   * Return: none
4521   */
dp_vdev_pdev_list_add(struct dp_soc * soc,struct dp_pdev * pdev,struct dp_vdev * vdev)4522  static void dp_vdev_pdev_list_add(struct dp_soc *soc,
4523  				  struct dp_pdev *pdev,
4524  				  struct dp_vdev *vdev)
4525  {
4526  	qdf_spin_lock_bh(&pdev->vdev_list_lock);
4527  	if (dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CONFIG) !=
4528  			QDF_STATUS_SUCCESS) {
4529  		dp_vdev_info("%pK: unable to get vdev reference at MAP vdev %pK",
4530  			     soc, vdev);
4531  		qdf_spin_unlock_bh(&pdev->vdev_list_lock);
4532  		return;
4533  	}
4534  	/* add this vdev into the pdev's list */
4535  	TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem);
4536  	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
4537  }
4538  
4539  /**
4540   * dp_vdev_pdev_list_remove() - remove vdev from pdev's list
4541   * @soc: SoC handle
4542   * @pdev: pdev handle
4543   * @vdev: VDEV handle
4544   *
4545   * Return: none
4546   */
dp_vdev_pdev_list_remove(struct dp_soc * soc,struct dp_pdev * pdev,struct dp_vdev * vdev)4547  static void dp_vdev_pdev_list_remove(struct dp_soc *soc,
4548  				     struct dp_pdev *pdev,
4549  				     struct dp_vdev *vdev)
4550  {
4551  	uint8_t found = 0;
4552  	struct dp_vdev *tmpvdev = NULL;
4553  
4554  	qdf_spin_lock_bh(&pdev->vdev_list_lock);
4555  	TAILQ_FOREACH(tmpvdev, &pdev->vdev_list, vdev_list_elem) {
4556  		if (tmpvdev == vdev) {
4557  			found = 1;
4558  			break;
4559  		}
4560  	}
4561  
4562  	if (found) {
4563  		TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem);
4564  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG);
4565  	} else {
4566  		dp_vdev_debug("%pK: vdev:%pK not found in pdev:%pK vdevlist:%pK",
4567  			      soc, vdev, pdev, &pdev->vdev_list);
4568  		QDF_ASSERT(0);
4569  	}
4570  	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
4571  }
4572  
4573  #ifdef QCA_SUPPORT_EAPOL_OVER_CONTROL_PORT
4574  /**
4575   * dp_vdev_init_rx_eapol() - initializing osif_rx_eapol
4576   * @vdev: Datapath VDEV handle
4577   *
4578   * Return: None
4579   */
dp_vdev_init_rx_eapol(struct dp_vdev * vdev)4580  static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
4581  {
4582  	vdev->osif_rx_eapol = NULL;
4583  }
4584  
4585  /**
4586   * dp_vdev_register_rx_eapol() - Register VDEV operations for rx_eapol
4587   * @vdev: DP vdev handle
4588   * @txrx_ops: Tx and Rx operations
4589   *
4590   * Return: None
4591   */
dp_vdev_register_rx_eapol(struct dp_vdev * vdev,struct ol_txrx_ops * txrx_ops)4592  static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
4593  					     struct ol_txrx_ops *txrx_ops)
4594  {
4595  	vdev->osif_rx_eapol = txrx_ops->rx.rx_eapol;
4596  }
4597  #else
dp_vdev_init_rx_eapol(struct dp_vdev * vdev)4598  static inline void dp_vdev_init_rx_eapol(struct dp_vdev *vdev)
4599  {
4600  }
4601  
dp_vdev_register_rx_eapol(struct dp_vdev * vdev,struct ol_txrx_ops * txrx_ops)4602  static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
4603  					     struct ol_txrx_ops *txrx_ops)
4604  {
4605  }
4606  #endif
4607  
4608  #ifdef WLAN_FEATURE_11BE_MLO
dp_vdev_save_mld_addr(struct dp_vdev * vdev,struct cdp_vdev_info * vdev_info)4609  static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
4610  					 struct cdp_vdev_info *vdev_info)
4611  {
4612  	if (vdev_info->mld_mac_addr)
4613  		qdf_mem_copy(&vdev->mld_mac_addr.raw[0],
4614  			     vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE);
4615  }
4616  
4617  #ifdef WLAN_MLO_MULTI_CHIP
4618  static inline void
dp_vdev_update_bridge_vdev_param(struct dp_vdev * vdev,struct cdp_vdev_info * vdev_info)4619  dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev,
4620  				 struct cdp_vdev_info *vdev_info)
4621  {
4622  	if (vdev_info->is_bridge_vap)
4623  		vdev->is_bridge_vdev = 1;
4624  
4625  	dp_info("is_bridge_link = %d vdev id = %d chip id = %d",
4626  		vdev->is_bridge_vdev, vdev->vdev_id,
4627  		dp_get_chip_id(vdev->pdev->soc));
4628  }
4629  #else
4630  static inline void
dp_vdev_update_bridge_vdev_param(struct dp_vdev * vdev,struct cdp_vdev_info * vdev_info)4631  dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev,
4632  				 struct cdp_vdev_info *vdev_info)
4633  {
4634  }
4635  #endif /* WLAN_MLO_MULTI_CHIP */
4636  
4637  #else
dp_vdev_save_mld_addr(struct dp_vdev * vdev,struct cdp_vdev_info * vdev_info)4638  static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
4639  					 struct cdp_vdev_info *vdev_info)
4640  {
4641  
4642  }
4643  
4644  static inline void
dp_vdev_update_bridge_vdev_param(struct dp_vdev * vdev,struct cdp_vdev_info * vdev_info)4645  dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev,
4646  				 struct cdp_vdev_info *vdev_info)
4647  {
4648  }
4649  #endif
4650  
4651  #ifdef DP_TRAFFIC_END_INDICATION
4652  /**
4653   * dp_tx_vdev_traffic_end_indication_attach() - Initialize data end indication
4654   *                                              related members in VDEV
4655   * @vdev: DP vdev handle
4656   *
4657   * Return: None
4658   */
4659  static inline void
dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev * vdev)4660  dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev *vdev)
4661  {
4662  	qdf_nbuf_queue_init(&vdev->end_ind_pkt_q);
4663  }
4664  
4665  /**
4666   * dp_tx_vdev_traffic_end_indication_detach() - De-init data end indication
4667   *                                              related members in VDEV
4668   * @vdev: DP vdev handle
4669   *
4670   * Return: None
4671   */
4672  static inline void
dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev * vdev)4673  dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev *vdev)
4674  {
4675  	qdf_nbuf_t nbuf;
4676  
4677  	while ((nbuf = qdf_nbuf_queue_remove(&vdev->end_ind_pkt_q)) != NULL)
4678  		qdf_nbuf_free(nbuf);
4679  }
4680  #else
4681  static inline void
dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev * vdev)4682  dp_tx_vdev_traffic_end_indication_attach(struct dp_vdev *vdev)
4683  {}
4684  
4685  static inline void
dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev * vdev)4686  dp_tx_vdev_traffic_end_indication_detach(struct dp_vdev *vdev)
4687  {}
4688  #endif
4689  
4690  #ifdef WLAN_DP_VDEV_NO_SELF_PEER
dp_vdev_self_peer_required(struct dp_soc * soc,struct dp_vdev * vdev)4691  static inline bool dp_vdev_self_peer_required(struct dp_soc *soc,
4692  					      struct dp_vdev *vdev)
4693  {
4694  	return false;
4695  }
4696  #else
dp_vdev_self_peer_required(struct dp_soc * soc,struct dp_vdev * vdev)4697  static inline bool dp_vdev_self_peer_required(struct dp_soc *soc,
4698  					      struct dp_vdev *vdev)
4699  {
4700  	if (wlan_op_mode_sta == vdev->opmode)
4701  		return true;
4702  
4703  	return false;
4704  }
4705  #endif
4706  
4707  /**
4708   * dp_vdev_attach_wifi3() - attach txrx vdev
4709   * @cdp_soc: CDP SoC context
4710   * @pdev_id: PDEV ID for vdev creation
4711   * @vdev_info: parameters used for vdev creation
4712   *
4713   * Return: status
4714   */
dp_vdev_attach_wifi3(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,struct cdp_vdev_info * vdev_info)4715  static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
4716  				       uint8_t pdev_id,
4717  				       struct cdp_vdev_info *vdev_info)
4718  {
4719  	int i = 0;
4720  	qdf_size_t vdev_context_size;
4721  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
4722  	struct dp_pdev *pdev =
4723  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
4724  						   pdev_id);
4725  	struct dp_vdev *vdev;
4726  	uint8_t *vdev_mac_addr = vdev_info->vdev_mac_addr;
4727  	uint8_t vdev_id = vdev_info->vdev_id;
4728  	enum wlan_op_mode op_mode = vdev_info->op_mode;
4729  	enum wlan_op_subtype subtype = vdev_info->subtype;
4730  	enum QDF_OPMODE qdf_opmode = vdev_info->qdf_opmode;
4731  	uint8_t vdev_stats_id = vdev_info->vdev_stats_id;
4732  
4733  	vdev_context_size =
4734  		soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_VDEV);
4735  	vdev = qdf_mem_malloc(vdev_context_size);
4736  
4737  	if (!pdev) {
4738  		dp_init_err("%pK: DP PDEV is Null for pdev id %d",
4739  			    cdp_soc, pdev_id);
4740  		qdf_mem_free(vdev);
4741  		goto fail0;
4742  	}
4743  
4744  	if (!vdev) {
4745  		dp_init_err("%pK: DP VDEV memory allocation failed",
4746  			    cdp_soc);
4747  		goto fail0;
4748  	}
4749  
4750  	wlan_minidump_log(vdev, sizeof(*vdev), soc->ctrl_psoc,
4751  			  WLAN_MD_DP_VDEV, "dp_vdev");
4752  
4753  	vdev->pdev = pdev;
4754  	vdev->vdev_id = vdev_id;
4755  	vdev->vdev_stats_id = vdev_stats_id;
4756  	vdev->opmode = op_mode;
4757  	vdev->subtype = subtype;
4758  	vdev->qdf_opmode = qdf_opmode;
4759  	vdev->osdev = soc->osdev;
4760  
4761  	vdev->osif_rx = NULL;
4762  	vdev->osif_rsim_rx_decap = NULL;
4763  	vdev->osif_get_key = NULL;
4764  	vdev->osif_tx_free_ext = NULL;
4765  	vdev->osif_vdev = NULL;
4766  
4767  	vdev->delete.pending = 0;
4768  	vdev->safemode = 0;
4769  	vdev->drop_unenc = 1;
4770  	vdev->sec_type = cdp_sec_type_none;
4771  	vdev->multipass_en = false;
4772  	vdev->wrap_vdev = false;
4773  	dp_vdev_init_rx_eapol(vdev);
4774  	qdf_atomic_init(&vdev->ref_cnt);
4775  	for (i = 0; i < DP_MOD_ID_MAX; i++)
4776  		qdf_atomic_init(&vdev->mod_refs[i]);
4777  
4778  	/* Take one reference for create*/
4779  	qdf_atomic_inc(&vdev->ref_cnt);
4780  	qdf_atomic_inc(&vdev->mod_refs[DP_MOD_ID_CONFIG]);
4781  	vdev->num_peers = 0;
4782  #ifdef notyet
4783  	vdev->filters_num = 0;
4784  #endif
4785  	vdev->lmac_id = pdev->lmac_id;
4786  
4787  	qdf_mem_copy(&vdev->mac_addr.raw[0], vdev_mac_addr, QDF_MAC_ADDR_SIZE);
4788  
4789  	dp_vdev_update_bridge_vdev_param(vdev, vdev_info);
4790  	dp_vdev_save_mld_addr(vdev, vdev_info);
4791  
4792  	/* TODO: Initialize default HTT meta data that will be used in
4793  	 * TCL descriptors for packets transmitted from this VDEV
4794  	 */
4795  
4796  	qdf_spinlock_create(&vdev->peer_list_lock);
4797  	TAILQ_INIT(&vdev->peer_list);
4798  	dp_peer_multipass_list_init(vdev);
4799  	if ((soc->intr_mode == DP_INTR_POLL) &&
4800  	    wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx) != 0) {
4801  		if ((pdev->vdev_count == 0) ||
4802  		    (wlan_op_mode_monitor == vdev->opmode))
4803  			qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
4804  	} else if (dp_soc_get_con_mode(soc) == QDF_GLOBAL_MISSION_MODE &&
4805  		   soc->intr_mode == DP_INTR_MSI &&
4806  		   wlan_op_mode_monitor == vdev->opmode &&
4807  		   !dp_mon_mode_local_pkt_capture(soc)) {
4808  		/* Timer to reap status ring in mission mode */
4809  		dp_monitor_vdev_timer_start(soc);
4810  	}
4811  
4812  	dp_vdev_id_map_tbl_add(soc, vdev, vdev_id);
4813  
4814  	if (wlan_op_mode_monitor == vdev->opmode) {
4815  		if (dp_monitor_vdev_attach(vdev) == QDF_STATUS_SUCCESS) {
4816  			dp_monitor_pdev_set_mon_vdev(vdev);
4817  			return dp_monitor_vdev_set_monitor_mode_buf_rings(pdev);
4818  		}
4819  		return QDF_STATUS_E_FAILURE;
4820  	}
4821  
4822  	vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx);
4823  	vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx);
4824  	vdev->dscp_tid_map_id = 0;
4825  	vdev->mcast_enhancement_en = 0;
4826  	vdev->igmp_mcast_enhanc_en = 0;
4827  	vdev->raw_mode_war = wlan_cfg_get_raw_mode_war(soc->wlan_cfg_ctx);
4828  	vdev->prev_tx_enq_tstamp = 0;
4829  	vdev->prev_rx_deliver_tstamp = 0;
4830  	vdev->skip_sw_tid_classification = DP_TX_HW_DSCP_TID_MAP_VALID;
4831  	dp_tx_vdev_traffic_end_indication_attach(vdev);
4832  
4833  	dp_vdev_pdev_list_add(soc, pdev, vdev);
4834  	pdev->vdev_count++;
4835  
4836  	if (wlan_op_mode_sta != vdev->opmode &&
4837  	    wlan_op_mode_ndi != vdev->opmode)
4838  		vdev->ap_bridge_enabled = true;
4839  	else
4840  		vdev->ap_bridge_enabled = false;
4841  	dp_init_info("%pK: wlan_cfg_ap_bridge_enabled %d",
4842  		     cdp_soc, vdev->ap_bridge_enabled);
4843  
4844  	dp_tx_vdev_attach(vdev);
4845  
4846  	dp_monitor_vdev_attach(vdev);
4847  	if (!pdev->is_lro_hash_configured) {
4848  		if (QDF_IS_STATUS_SUCCESS(dp_lro_hash_setup(soc, pdev)))
4849  			pdev->is_lro_hash_configured = true;
4850  		else
4851  			dp_err("LRO hash setup failure!");
4852  	}
4853  
4854  	dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_ATTACH, vdev);
4855  	dp_info("Created vdev %pK ("QDF_MAC_ADDR_FMT") vdev_id %d", vdev,
4856  		QDF_MAC_ADDR_REF(vdev->mac_addr.raw), vdev->vdev_id);
4857  	DP_STATS_INIT(vdev);
4858  
4859  	if (QDF_IS_STATUS_ERROR(soc->arch_ops.txrx_vdev_attach(soc, vdev)))
4860  		goto fail0;
4861  
4862  	if (dp_vdev_self_peer_required(soc, vdev))
4863  		dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id,
4864  				     vdev->mac_addr.raw, CDP_LINK_PEER_TYPE);
4865  
4866  	dp_pdev_update_fast_rx_flag(soc, pdev);
4867  
4868  	return QDF_STATUS_SUCCESS;
4869  
4870  fail0:
4871  	return QDF_STATUS_E_FAILURE;
4872  }
4873  
4874  #ifndef QCA_HOST_MODE_WIFI_DISABLED
4875  /**
4876   * dp_vdev_fetch_tx_handler() - Fetch Tx handlers
4877   * @vdev: struct dp_vdev *
4878   * @soc: struct dp_soc *
4879   * @ctx: struct ol_txrx_hardtart_ctxt *
4880   */
dp_vdev_fetch_tx_handler(struct dp_vdev * vdev,struct dp_soc * soc,struct ol_txrx_hardtart_ctxt * ctx)4881  static inline void dp_vdev_fetch_tx_handler(struct dp_vdev *vdev,
4882  					    struct dp_soc *soc,
4883  					    struct ol_txrx_hardtart_ctxt *ctx)
4884  {
4885  	/* Enable vdev_id check only for ap, if flag is enabled */
4886  	if (vdev->mesh_vdev)
4887  		ctx->tx = dp_tx_send_mesh;
4888  	else if ((wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx)) &&
4889  		 (vdev->opmode == wlan_op_mode_ap)) {
4890  		ctx->tx = dp_tx_send_vdev_id_check;
4891  		ctx->tx_fast = dp_tx_send_vdev_id_check;
4892  	} else {
4893  		ctx->tx = dp_tx_send;
4894  		ctx->tx_fast = soc->arch_ops.dp_tx_send_fast;
4895  	}
4896  
4897  	/* Avoid check in regular exception Path */
4898  	if ((wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx)) &&
4899  	    (vdev->opmode == wlan_op_mode_ap))
4900  		ctx->tx_exception = dp_tx_send_exception_vdev_id_check;
4901  	else
4902  		ctx->tx_exception = dp_tx_send_exception;
4903  }
4904  
4905  /**
4906   * dp_vdev_register_tx_handler() - Register Tx handler
4907   * @vdev: struct dp_vdev *
4908   * @soc: struct dp_soc *
4909   * @txrx_ops: struct ol_txrx_ops *
4910   */
dp_vdev_register_tx_handler(struct dp_vdev * vdev,struct dp_soc * soc,struct ol_txrx_ops * txrx_ops)4911  static inline void dp_vdev_register_tx_handler(struct dp_vdev *vdev,
4912  					       struct dp_soc *soc,
4913  					       struct ol_txrx_ops *txrx_ops)
4914  {
4915  	struct ol_txrx_hardtart_ctxt ctx = {0};
4916  
4917  	dp_vdev_fetch_tx_handler(vdev, soc, &ctx);
4918  
4919  	txrx_ops->tx.tx = ctx.tx;
4920  	txrx_ops->tx.tx_fast = ctx.tx_fast;
4921  	txrx_ops->tx.tx_exception = ctx.tx_exception;
4922  
4923  	dp_info("Configure tx_vdev_id_chk_handler Feature Flag: %d and mode:%d for vdev_id:%d",
4924  		wlan_cfg_is_tx_per_pkt_vdev_id_check_enabled(soc->wlan_cfg_ctx),
4925  		vdev->opmode, vdev->vdev_id);
4926  }
4927  #else /* QCA_HOST_MODE_WIFI_DISABLED */
dp_vdev_register_tx_handler(struct dp_vdev * vdev,struct dp_soc * soc,struct ol_txrx_ops * txrx_ops)4928  static inline void dp_vdev_register_tx_handler(struct dp_vdev *vdev,
4929  					       struct dp_soc *soc,
4930  					       struct ol_txrx_ops *txrx_ops)
4931  {
4932  }
4933  
dp_vdev_fetch_tx_handler(struct dp_vdev * vdev,struct dp_soc * soc,struct ol_txrx_hardtart_ctxt * ctx)4934  static inline void dp_vdev_fetch_tx_handler(struct dp_vdev *vdev,
4935  					    struct dp_soc *soc,
4936  					    struct ol_txrx_hardtart_ctxt *ctx)
4937  {
4938  }
4939  #endif /* QCA_HOST_MODE_WIFI_DISABLED */
4940  
4941  /**
4942   * dp_vdev_register_wifi3() - Register VDEV operations from osif layer
4943   * @soc_hdl: Datapath soc handle
4944   * @vdev_id: id of Datapath VDEV handle
4945   * @osif_vdev: OSIF vdev handle
4946   * @txrx_ops: Tx and Rx operations
4947   *
4948   * Return: DP VDEV handle on success, NULL on failure
4949   */
dp_vdev_register_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,ol_osif_vdev_handle osif_vdev,struct ol_txrx_ops * txrx_ops)4950  static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
4951  					 uint8_t vdev_id,
4952  					 ol_osif_vdev_handle osif_vdev,
4953  					 struct ol_txrx_ops *txrx_ops)
4954  {
4955  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
4956  	struct dp_vdev *vdev =	dp_vdev_get_ref_by_id(soc, vdev_id,
4957  						      DP_MOD_ID_CDP);
4958  
4959  	if (!vdev)
4960  		return QDF_STATUS_E_FAILURE;
4961  
4962  	vdev->osif_vdev = osif_vdev;
4963  	vdev->osif_rx = txrx_ops->rx.rx;
4964  	vdev->osif_rx_stack = txrx_ops->rx.rx_stack;
4965  	vdev->osif_rx_flush = txrx_ops->rx.rx_flush;
4966  	vdev->osif_gro_flush = txrx_ops->rx.rx_gro_flush;
4967  	vdev->osif_rsim_rx_decap = txrx_ops->rx.rsim_rx_decap;
4968  	vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx;
4969  	vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush;
4970  	vdev->osif_get_key = txrx_ops->get_key;
4971  	dp_monitor_vdev_register_osif(vdev, txrx_ops);
4972  	vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext;
4973  	vdev->tx_comp = txrx_ops->tx.tx_comp;
4974  	vdev->stats_cb = txrx_ops->rx.stats_rx;
4975  	vdev->tx_classify_critical_pkt_cb =
4976  		txrx_ops->tx.tx_classify_critical_pkt_cb;
4977  #ifdef notyet
4978  #if ATH_SUPPORT_WAPI
4979  	vdev->osif_check_wai = txrx_ops->rx.wai_check;
4980  #endif
4981  #endif
4982  #ifdef UMAC_SUPPORT_PROXY_ARP
4983  	vdev->osif_proxy_arp = txrx_ops->proxy_arp;
4984  #endif
4985  	vdev->me_convert = txrx_ops->me_convert;
4986  	vdev->get_tsf_time = txrx_ops->get_tsf_time;
4987  	vdev->vdev_del_notify = txrx_ops->vdev_del_notify;
4988  
4989  	dp_vdev_register_rx_eapol(vdev, txrx_ops);
4990  
4991  	dp_vdev_register_tx_handler(vdev, soc, txrx_ops);
4992  
4993  	dp_init_info("%pK: DP Vdev Register success", soc);
4994  
4995  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
4996  	return QDF_STATUS_SUCCESS;
4997  }
4998  
4999  #ifdef WLAN_FEATURE_11BE_MLO
dp_peer_delete(struct dp_soc * soc,struct dp_peer * peer,void * arg)5000  void dp_peer_delete(struct dp_soc *soc,
5001  		    struct dp_peer *peer,
5002  		    void *arg)
5003  {
5004  	if (!peer->valid)
5005  		return;
5006  
5007  	dp_peer_delete_wifi3((struct cdp_soc_t *)soc,
5008  			     peer->vdev->vdev_id,
5009  			     peer->mac_addr.raw, 0,
5010  			     peer->peer_type);
5011  }
5012  #else
dp_peer_delete(struct dp_soc * soc,struct dp_peer * peer,void * arg)5013  void dp_peer_delete(struct dp_soc *soc,
5014  		    struct dp_peer *peer,
5015  		    void *arg)
5016  {
5017  	if (!peer->valid)
5018  		return;
5019  
5020  	dp_peer_delete_wifi3((struct cdp_soc_t *)soc,
5021  			     peer->vdev->vdev_id,
5022  			     peer->mac_addr.raw, 0,
5023  			     CDP_LINK_PEER_TYPE);
5024  }
5025  #endif
5026  
5027  #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
5028  static uint8_t
dp_mlo_get_num_link_peer(struct dp_soc * soc,struct dp_peer * peer)5029  dp_mlo_get_num_link_peer(struct dp_soc *soc, struct dp_peer *peer)
5030  {
5031  	if (soc->cdp_soc.ol_ops->peer_get_num_mlo_links)
5032  		return soc->cdp_soc.ol_ops->peer_get_num_mlo_links(
5033  				soc->ctrl_psoc,
5034  				peer->vdev->vdev_id,
5035  				peer->mac_addr.raw,
5036  				IS_MLO_DP_MLD_PEER(peer));
5037  
5038  	return 0;
5039  }
5040  
dp_mlo_peer_delete(struct dp_soc * soc,struct dp_peer * peer,void * arg)5041  void dp_mlo_peer_delete(struct dp_soc *soc, struct dp_peer *peer, void *arg)
5042  {
5043  	if (!peer->valid)
5044  		return;
5045  
5046  	/* skip deleting the SLO peers */
5047  	if (dp_mlo_get_num_link_peer(soc, peer) == 1)
5048  		return;
5049  
5050  	if (IS_MLO_DP_LINK_PEER(peer))
5051  		dp_peer_delete_wifi3((struct cdp_soc_t *)soc,
5052  				     peer->vdev->vdev_id,
5053  				     peer->mac_addr.raw, 0,
5054  				     CDP_LINK_PEER_TYPE);
5055  }
5056  
5057  /**
5058   * dp_mlo_link_peer_flush() - flush all the link peers
5059   * @soc: Datapath soc handle
5060   * @peer: DP peer handle to be checked
5061   *
5062   * Return: None
5063   */
dp_mlo_link_peer_flush(struct dp_soc * soc,struct dp_peer * peer)5064  static void dp_mlo_link_peer_flush(struct dp_soc *soc, struct dp_peer *peer)
5065  {
5066  	int cnt = 0;
5067  	struct dp_peer *link_peer = NULL;
5068  	struct dp_mld_link_peers link_peers_info = {NULL};
5069  
5070  	if (!IS_MLO_DP_MLD_PEER(peer))
5071  		return;
5072  
5073  	/* get link peers with reference */
5074  	dp_get_link_peers_ref_from_mld_peer(soc, peer, &link_peers_info,
5075  					    DP_MOD_ID_CDP);
5076  	for (cnt = 0; cnt < link_peers_info.num_links; cnt++) {
5077  		link_peer = link_peers_info.link_peers[cnt];
5078  		if (!link_peer)
5079  			continue;
5080  
5081  		/* delete all the link peers */
5082  		dp_mlo_peer_delete(link_peer->vdev->pdev->soc, link_peer, NULL);
5083  		/* unmap all the link peers */
5084  		dp_rx_peer_unmap_handler(link_peer->vdev->pdev->soc,
5085  					 link_peer->peer_id,
5086  					 link_peer->vdev->vdev_id,
5087  					 link_peer->mac_addr.raw, 0,
5088  					 DP_PEER_WDS_COUNT_INVALID);
5089  	}
5090  	dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
5091  }
5092  #else
5093  static uint8_t
dp_mlo_get_num_link_peer(struct dp_soc * soc,struct dp_peer * peer)5094  dp_mlo_get_num_link_peer(struct dp_soc *soc, struct dp_peer *peer)
5095  {
5096  	return 0;
5097  }
5098  
dp_mlo_peer_delete(struct dp_soc * soc,struct dp_peer * peer,void * arg)5099  void dp_mlo_peer_delete(struct dp_soc *soc, struct dp_peer *peer, void *arg)
5100  {
5101  }
5102  
dp_mlo_link_peer_flush(struct dp_soc * soc,struct dp_peer * peer)5103  static void dp_mlo_link_peer_flush(struct dp_soc *soc, struct dp_peer *peer)
5104  {
5105  }
5106  #endif
5107  /**
5108   * dp_vdev_flush_peers() - Forcibily Flush peers of vdev
5109   * @vdev_handle: Datapath VDEV handle
5110   * @unmap_only: Flag to indicate "only unmap"
5111   * @mlo_peers_only: true if only MLO peers should be flushed
5112   *
5113   * Return: void
5114   */
dp_vdev_flush_peers(struct cdp_vdev * vdev_handle,bool unmap_only,bool mlo_peers_only)5115  static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle,
5116  				bool unmap_only,
5117  				bool mlo_peers_only)
5118  {
5119  	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
5120  	struct dp_pdev *pdev = vdev->pdev;
5121  	struct dp_soc *soc = pdev->soc;
5122  	struct dp_peer *peer;
5123  	uint32_t i = 0;
5124  
5125  
5126  	if (!unmap_only) {
5127  		if (!mlo_peers_only)
5128  			dp_vdev_iterate_peer_lock_safe(vdev,
5129  						       dp_peer_delete,
5130  						       NULL,
5131  						       DP_MOD_ID_CDP);
5132  		else
5133  			dp_vdev_iterate_peer_lock_safe(vdev,
5134  						       dp_mlo_peer_delete,
5135  						       NULL,
5136  						       DP_MOD_ID_CDP);
5137  	}
5138  
5139  	for (i = 0; i < soc->max_peer_id ; i++) {
5140  		peer = __dp_peer_get_ref_by_id(soc, i, DP_MOD_ID_CDP);
5141  
5142  		if (!peer)
5143  			continue;
5144  
5145  		if (peer->vdev != vdev) {
5146  			dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
5147  			continue;
5148  		}
5149  
5150  		if (!mlo_peers_only) {
5151  			dp_info("peer: " QDF_MAC_ADDR_FMT " is getting unmap",
5152  				QDF_MAC_ADDR_REF(peer->mac_addr.raw));
5153  			dp_mlo_link_peer_flush(soc, peer);
5154  			dp_rx_peer_unmap_handler(soc, i,
5155  						 vdev->vdev_id,
5156  						 peer->mac_addr.raw, 0,
5157  						 DP_PEER_WDS_COUNT_INVALID);
5158  			if (!IS_MLO_DP_MLD_PEER(peer))
5159  				SET_PEER_REF_CNT_ONE(peer);
5160  		} else if (IS_MLO_DP_LINK_PEER(peer) ||
5161  			   IS_MLO_DP_MLD_PEER(peer)) {
5162  			dp_info("peer: " QDF_MAC_ADDR_FMT " is getting unmap",
5163  				QDF_MAC_ADDR_REF(peer->mac_addr.raw));
5164  
5165  			/* skip deleting the SLO peers */
5166  			if (dp_mlo_get_num_link_peer(soc, peer) ==  1) {
5167  				dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
5168  				continue;
5169  			}
5170  
5171  			dp_mlo_link_peer_flush(soc, peer);
5172  			dp_rx_peer_unmap_handler(soc, i,
5173  						 vdev->vdev_id,
5174  						 peer->mac_addr.raw, 0,
5175  						 DP_PEER_WDS_COUNT_INVALID);
5176  			if (!IS_MLO_DP_MLD_PEER(peer))
5177  				SET_PEER_REF_CNT_ONE(peer);
5178  		}
5179  
5180  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
5181  	}
5182  }
5183  
5184  #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
5185  /**
5186   * dp_txrx_alloc_vdev_stats_id()- Allocate vdev_stats_id
5187   * @soc_hdl: Datapath soc handle
5188   * @vdev_stats_id: Address of vdev_stats_id
5189   *
5190   * Return: QDF_STATUS
5191   */
dp_txrx_alloc_vdev_stats_id(struct cdp_soc_t * soc_hdl,uint8_t * vdev_stats_id)5192  static QDF_STATUS dp_txrx_alloc_vdev_stats_id(struct cdp_soc_t *soc_hdl,
5193  					      uint8_t *vdev_stats_id)
5194  {
5195  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
5196  	uint8_t id = 0;
5197  
5198  	if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) {
5199  		*vdev_stats_id = CDP_INVALID_VDEV_STATS_ID;
5200  		return QDF_STATUS_E_FAILURE;
5201  	}
5202  
5203  	while (id < CDP_MAX_VDEV_STATS_ID) {
5204  		if (!qdf_atomic_test_and_set_bit(id, &soc->vdev_stats_id_map)) {
5205  			*vdev_stats_id = id;
5206  			return QDF_STATUS_SUCCESS;
5207  		}
5208  		id++;
5209  	}
5210  
5211  	*vdev_stats_id = CDP_INVALID_VDEV_STATS_ID;
5212  	return QDF_STATUS_E_FAILURE;
5213  }
5214  
5215  /**
5216   * dp_txrx_reset_vdev_stats_id() - Reset vdev_stats_id in dp_soc
5217   * @soc_hdl: Datapath soc handle
5218   * @vdev_stats_id: vdev_stats_id to reset in dp_soc
5219   *
5220   * Return: none
5221   */
dp_txrx_reset_vdev_stats_id(struct cdp_soc_t * soc_hdl,uint8_t vdev_stats_id)5222  static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc_hdl,
5223  					uint8_t vdev_stats_id)
5224  {
5225  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
5226  
5227  	if ((!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) ||
5228  	    (vdev_stats_id >= CDP_MAX_VDEV_STATS_ID))
5229  		return;
5230  
5231  	qdf_atomic_clear_bit(vdev_stats_id, &soc->vdev_stats_id_map);
5232  }
5233  #else
dp_txrx_reset_vdev_stats_id(struct cdp_soc_t * soc,uint8_t vdev_stats_id)5234  static void dp_txrx_reset_vdev_stats_id(struct cdp_soc_t *soc,
5235  					uint8_t vdev_stats_id)
5236  {}
5237  #endif
5238  /**
5239   * dp_vdev_detach_wifi3() - Detach txrx vdev
5240   * @cdp_soc: Datapath soc handle
5241   * @vdev_id: VDEV Id
5242   * @callback: Callback OL_IF on completion of detach
5243   * @cb_context:	Callback context
5244   *
5245   */
dp_vdev_detach_wifi3(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,ol_txrx_vdev_delete_cb callback,void * cb_context)5246  static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
5247  				       uint8_t vdev_id,
5248  				       ol_txrx_vdev_delete_cb callback,
5249  				       void *cb_context)
5250  {
5251  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
5252  	struct dp_pdev *pdev;
5253  	struct dp_neighbour_peer *peer = NULL;
5254  	struct dp_peer *vap_self_peer = NULL;
5255  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
5256  						     DP_MOD_ID_CDP);
5257  
5258  	if (!vdev)
5259  		return QDF_STATUS_E_FAILURE;
5260  
5261  	soc->arch_ops.txrx_vdev_detach(soc, vdev);
5262  
5263  	pdev = vdev->pdev;
5264  
5265  	vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev,
5266  							DP_MOD_ID_CONFIG);
5267  	if (vap_self_peer) {
5268  		qdf_spin_lock_bh(&soc->ast_lock);
5269  		if (vap_self_peer->self_ast_entry) {
5270  			dp_peer_del_ast(soc, vap_self_peer->self_ast_entry);
5271  			vap_self_peer->self_ast_entry = NULL;
5272  		}
5273  		qdf_spin_unlock_bh(&soc->ast_lock);
5274  
5275  		dp_peer_delete_wifi3((struct cdp_soc_t *)soc, vdev->vdev_id,
5276  				     vap_self_peer->mac_addr.raw, 0,
5277  				     CDP_LINK_PEER_TYPE);
5278  		dp_peer_unref_delete(vap_self_peer, DP_MOD_ID_CONFIG);
5279  	}
5280  
5281  	/*
5282  	 * If Target is hung, flush all peers before detaching vdev
5283  	 * this will free all references held due to missing
5284  	 * unmap commands from Target
5285  	 */
5286  	if (!hif_is_target_ready(HIF_GET_SOFTC(soc->hif_handle)))
5287  		dp_vdev_flush_peers((struct cdp_vdev *)vdev, false, false);
5288  	else if (hif_get_target_status(soc->hif_handle) == TARGET_STATUS_RESET)
5289  		dp_vdev_flush_peers((struct cdp_vdev *)vdev, true, false);
5290  
5291  	/* indicate that the vdev needs to be deleted */
5292  	vdev->delete.pending = 1;
5293  	dp_rx_vdev_detach(vdev);
5294  	/*
5295  	 * move it after dp_rx_vdev_detach(),
5296  	 * as the call back done in dp_rx_vdev_detach()
5297  	 * still need to get vdev pointer by vdev_id.
5298  	 */
5299  	dp_vdev_id_map_tbl_remove(soc, vdev);
5300  
5301  	dp_monitor_neighbour_peer_list_remove(pdev, vdev, peer);
5302  
5303  	dp_txrx_reset_vdev_stats_id(cdp_soc, vdev->vdev_stats_id);
5304  
5305  	dp_tx_vdev_multipass_deinit(vdev);
5306  	dp_tx_vdev_traffic_end_indication_detach(vdev);
5307  
5308  	if (vdev->vdev_dp_ext_handle) {
5309  		qdf_mem_free(vdev->vdev_dp_ext_handle);
5310  		vdev->vdev_dp_ext_handle = NULL;
5311  	}
5312  	vdev->delete.callback = callback;
5313  	vdev->delete.context = cb_context;
5314  
5315  	if (vdev->opmode != wlan_op_mode_monitor)
5316  		dp_vdev_pdev_list_remove(soc, pdev, vdev);
5317  
5318  	pdev->vdev_count--;
5319  	/* release reference taken above for find */
5320  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5321  
5322  	qdf_spin_lock_bh(&soc->inactive_vdev_list_lock);
5323  	TAILQ_INSERT_TAIL(&soc->inactive_vdev_list, vdev, inactive_list_elem);
5324  	qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock);
5325  
5326  	dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_DETACH, vdev);
5327  	dp_info("detach vdev %pK id %d pending refs %d",
5328  		vdev, vdev->vdev_id, qdf_atomic_read(&vdev->ref_cnt));
5329  
5330  	/* release reference taken at dp_vdev_create */
5331  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CONFIG);
5332  
5333  	return QDF_STATUS_SUCCESS;
5334  }
5335  
5336  #ifdef WLAN_FEATURE_11BE_MLO
5337  /**
5338   * is_dp_peer_can_reuse() - check if the dp_peer match condition to be reused
5339   * @vdev: Target DP vdev handle
5340   * @peer: DP peer handle to be checked
5341   * @peer_mac_addr: Target peer mac address
5342   * @peer_type: Target peer type
5343   *
5344   * Return: true - if match, false - not match
5345   */
5346  static inline
is_dp_peer_can_reuse(struct dp_vdev * vdev,struct dp_peer * peer,uint8_t * peer_mac_addr,enum cdp_peer_type peer_type)5347  bool is_dp_peer_can_reuse(struct dp_vdev *vdev,
5348  			  struct dp_peer *peer,
5349  			  uint8_t *peer_mac_addr,
5350  			  enum cdp_peer_type peer_type)
5351  {
5352  	if (peer->bss_peer && (peer->vdev == vdev) &&
5353  	    (peer->peer_type == peer_type) &&
5354  	    (qdf_mem_cmp(peer_mac_addr, peer->mac_addr.raw,
5355  			 QDF_MAC_ADDR_SIZE) == 0))
5356  		return true;
5357  
5358  	return false;
5359  }
5360  #else
5361  static inline
is_dp_peer_can_reuse(struct dp_vdev * vdev,struct dp_peer * peer,uint8_t * peer_mac_addr,enum cdp_peer_type peer_type)5362  bool is_dp_peer_can_reuse(struct dp_vdev *vdev,
5363  			  struct dp_peer *peer,
5364  			  uint8_t *peer_mac_addr,
5365  			  enum cdp_peer_type peer_type)
5366  {
5367  	if (peer->bss_peer && (peer->vdev == vdev) &&
5368  	    (qdf_mem_cmp(peer_mac_addr, peer->mac_addr.raw,
5369  			 QDF_MAC_ADDR_SIZE) == 0))
5370  		return true;
5371  
5372  	return false;
5373  }
5374  #endif
5375  
dp_peer_can_reuse(struct dp_vdev * vdev,uint8_t * peer_mac_addr,enum cdp_peer_type peer_type)5376  static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev,
5377  						uint8_t *peer_mac_addr,
5378  						enum cdp_peer_type peer_type)
5379  {
5380  	struct dp_peer *peer;
5381  	struct dp_soc *soc = vdev->pdev->soc;
5382  
5383  	qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
5384  	TAILQ_FOREACH(peer, &soc->inactive_peer_list,
5385  		      inactive_list_elem) {
5386  
5387  		/* reuse bss peer only when vdev matches*/
5388  		if (is_dp_peer_can_reuse(vdev, peer,
5389  					 peer_mac_addr, peer_type)) {
5390  			/* increment ref count for cdp_peer_create*/
5391  			if (dp_peer_get_ref(soc, peer, DP_MOD_ID_CONFIG) ==
5392  						QDF_STATUS_SUCCESS) {
5393  				TAILQ_REMOVE(&soc->inactive_peer_list, peer,
5394  					     inactive_list_elem);
5395  				qdf_spin_unlock_bh
5396  					(&soc->inactive_peer_list_lock);
5397  				return peer;
5398  			}
5399  		}
5400  	}
5401  
5402  	qdf_spin_unlock_bh(&soc->inactive_peer_list_lock);
5403  	return NULL;
5404  }
5405  
5406  #ifdef FEATURE_AST
dp_peer_ast_handle_roam_del(struct dp_soc * soc,struct dp_pdev * pdev,uint8_t * peer_mac_addr)5407  static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc,
5408  					       struct dp_pdev *pdev,
5409  					       uint8_t *peer_mac_addr)
5410  {
5411  	struct dp_ast_entry *ast_entry;
5412  
5413  	if (soc->ast_offload_support)
5414  		return;
5415  
5416  	qdf_spin_lock_bh(&soc->ast_lock);
5417  	if (soc->ast_override_support)
5418  		ast_entry = dp_peer_ast_hash_find_by_pdevid(soc, peer_mac_addr,
5419  							    pdev->pdev_id);
5420  	else
5421  		ast_entry = dp_peer_ast_hash_find_soc(soc, peer_mac_addr);
5422  
5423  	if (ast_entry && ast_entry->next_hop && !ast_entry->delete_in_progress)
5424  		dp_peer_del_ast(soc, ast_entry);
5425  
5426  	qdf_spin_unlock_bh(&soc->ast_lock);
5427  }
5428  #else
dp_peer_ast_handle_roam_del(struct dp_soc * soc,struct dp_pdev * pdev,uint8_t * peer_mac_addr)5429  static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc,
5430  					       struct dp_pdev *pdev,
5431  					       uint8_t *peer_mac_addr)
5432  {
5433  }
5434  #endif
5435  
5436  #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
5437  /**
5438   * dp_peer_hw_txrx_stats_init() - Initialize hw_txrx_stats_en in dp_peer
5439   * @soc: Datapath soc handle
5440   * @txrx_peer: Datapath peer handle
5441   *
5442   * Return: none
5443   */
5444  static inline
dp_peer_hw_txrx_stats_init(struct dp_soc * soc,struct dp_txrx_peer * txrx_peer)5445  void dp_peer_hw_txrx_stats_init(struct dp_soc *soc,
5446  				struct dp_txrx_peer *txrx_peer)
5447  {
5448  	txrx_peer->hw_txrx_stats_en =
5449  		wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx);
5450  }
5451  #else
5452  static inline
dp_peer_hw_txrx_stats_init(struct dp_soc * soc,struct dp_txrx_peer * txrx_peer)5453  void dp_peer_hw_txrx_stats_init(struct dp_soc *soc,
5454  				struct dp_txrx_peer *txrx_peer)
5455  {
5456  	txrx_peer->hw_txrx_stats_en = 0;
5457  }
5458  #endif
5459  
dp_txrx_peer_detach(struct dp_soc * soc,struct dp_peer * peer)5460  static QDF_STATUS dp_txrx_peer_detach(struct dp_soc *soc, struct dp_peer *peer)
5461  {
5462  	struct dp_txrx_peer *txrx_peer;
5463  	struct dp_pdev *pdev;
5464  	struct cdp_txrx_peer_params_update params = {0};
5465  
5466  	/* dp_txrx_peer exists for mld peer and legacy peer */
5467  	if (peer->txrx_peer) {
5468  		txrx_peer = peer->txrx_peer;
5469  		peer->txrx_peer = NULL;
5470  		pdev = txrx_peer->vdev->pdev;
5471  
5472  		if ((peer->vdev->opmode != wlan_op_mode_sta) &&
5473  		    !peer->bss_peer) {
5474  			params.vdev_id = peer->vdev->vdev_id;
5475  			params.peer_mac = peer->mac_addr.raw;
5476  
5477  			dp_wdi_event_handler(WDI_EVENT_PEER_DELETE, soc,
5478  					     (void *)&params, peer->peer_id,
5479  					     WDI_NO_VAL, pdev->pdev_id);
5480  		}
5481  
5482  		dp_peer_defrag_rx_tids_deinit(txrx_peer);
5483  		/*
5484  		 * Deallocate the extended stats contenxt
5485  		 */
5486  		dp_peer_delay_stats_ctx_dealloc(soc, txrx_peer);
5487  		dp_peer_rx_bufq_resources_deinit(txrx_peer);
5488  		dp_peer_jitter_stats_ctx_dealloc(pdev, txrx_peer);
5489  		dp_peer_sawf_stats_ctx_free(soc, txrx_peer);
5490  
5491  		qdf_mem_free(txrx_peer);
5492  	}
5493  
5494  	return QDF_STATUS_SUCCESS;
5495  }
5496  
5497  static inline
dp_txrx_peer_calculate_stats_size(struct dp_soc * soc,struct dp_peer * peer)5498  uint8_t dp_txrx_peer_calculate_stats_size(struct dp_soc *soc,
5499  					  struct dp_peer *peer)
5500  {
5501  	if ((wlan_cfg_is_peer_link_stats_enabled(soc->wlan_cfg_ctx)) &&
5502  	    IS_MLO_DP_MLD_PEER(peer)) {
5503  		return (DP_MAX_MLO_LINKS + 1);
5504  	}
5505  	return 1;
5506  }
5507  
dp_txrx_peer_attach(struct dp_soc * soc,struct dp_peer * peer)5508  static QDF_STATUS dp_txrx_peer_attach(struct dp_soc *soc, struct dp_peer *peer)
5509  {
5510  	struct dp_txrx_peer *txrx_peer;
5511  	struct dp_pdev *pdev;
5512  	struct cdp_txrx_peer_params_update params = {0};
5513  	uint8_t stats_arr_size = 0;
5514  
5515  	stats_arr_size = dp_txrx_peer_calculate_stats_size(soc, peer);
5516  
5517  	txrx_peer = (struct dp_txrx_peer *)qdf_mem_malloc(sizeof(*txrx_peer) +
5518  							  (stats_arr_size *
5519  							   sizeof(struct dp_peer_stats)));
5520  
5521  	if (!txrx_peer)
5522  		return QDF_STATUS_E_NOMEM; /* failure */
5523  
5524  	txrx_peer->peer_id = HTT_INVALID_PEER;
5525  	/* initialize the peer_id */
5526  	txrx_peer->vdev = peer->vdev;
5527  	pdev = peer->vdev->pdev;
5528  	txrx_peer->stats_arr_size = stats_arr_size;
5529  
5530  	DP_TXRX_PEER_STATS_INIT(txrx_peer,
5531  				(txrx_peer->stats_arr_size *
5532  				sizeof(struct dp_peer_stats)));
5533  
5534  	if (!IS_DP_LEGACY_PEER(peer))
5535  		txrx_peer->is_mld_peer = 1;
5536  
5537  	dp_wds_ext_peer_init(txrx_peer);
5538  	dp_peer_rx_bufq_resources_init(txrx_peer);
5539  	dp_peer_hw_txrx_stats_init(soc, txrx_peer);
5540  	/*
5541  	 * Allocate peer extended stats context. Fall through in
5542  	 * case of failure as its not an implicit requirement to have
5543  	 * this object for regular statistics updates.
5544  	 */
5545  	if (dp_peer_delay_stats_ctx_alloc(soc, txrx_peer) !=
5546  					  QDF_STATUS_SUCCESS)
5547  		dp_warn("peer delay_stats ctx alloc failed");
5548  
5549  	/*
5550  	 * Alloctate memory for jitter stats. Fall through in
5551  	 * case of failure as its not an implicit requirement to have
5552  	 * this object for regular statistics updates.
5553  	 */
5554  	if (dp_peer_jitter_stats_ctx_alloc(pdev, txrx_peer) !=
5555  					   QDF_STATUS_SUCCESS)
5556  		dp_warn("peer jitter_stats ctx alloc failed");
5557  
5558  	dp_set_peer_isolation(txrx_peer, false);
5559  
5560  	dp_peer_defrag_rx_tids_init(txrx_peer);
5561  
5562  	if (dp_peer_sawf_stats_ctx_alloc(soc, txrx_peer) != QDF_STATUS_SUCCESS)
5563  		dp_warn("peer sawf stats alloc failed");
5564  
5565  	dp_txrx_peer_attach_add(soc, peer, txrx_peer);
5566  
5567  	if ((peer->vdev->opmode == wlan_op_mode_sta) || peer->bss_peer)
5568  		return QDF_STATUS_SUCCESS;
5569  
5570  	params.peer_mac = peer->mac_addr.raw;
5571  	params.vdev_id = peer->vdev->vdev_id;
5572  	params.chip_id = dp_get_chip_id(soc);
5573  	params.pdev_id = peer->vdev->pdev->pdev_id;
5574  
5575  	dp_wdi_event_handler(WDI_EVENT_TXRX_PEER_CREATE, soc,
5576  			     (void *)&params, peer->peer_id,
5577  			     WDI_NO_VAL, params.pdev_id);
5578  
5579  	return QDF_STATUS_SUCCESS;
5580  }
5581  
5582  static inline
dp_txrx_peer_stats_clr(struct dp_txrx_peer * txrx_peer)5583  void dp_txrx_peer_stats_clr(struct dp_txrx_peer *txrx_peer)
5584  {
5585  	if (!txrx_peer)
5586  		return;
5587  
5588  	txrx_peer->tx_failed = 0;
5589  	txrx_peer->comp_pkt.num = 0;
5590  	txrx_peer->comp_pkt.bytes = 0;
5591  	txrx_peer->to_stack.num = 0;
5592  	txrx_peer->to_stack.bytes = 0;
5593  
5594  	DP_TXRX_PEER_STATS_CLR(txrx_peer,
5595  			       (txrx_peer->stats_arr_size *
5596  			       sizeof(struct dp_peer_stats)));
5597  	dp_peer_delay_stats_ctx_clr(txrx_peer);
5598  	dp_peer_jitter_stats_ctx_clr(txrx_peer);
5599  }
5600  
5601  #if defined WLAN_FEATURE_11BE_MLO && defined DP_MLO_LINK_STATS_SUPPORT
5602  /**
5603   * dp_txrx_peer_reset_local_link_id() - Reset local link id
5604   * @txrx_peer: txrx peer handle
5605   *
5606   * Return: None
5607   */
5608  static inline void
dp_txrx_peer_reset_local_link_id(struct dp_txrx_peer * txrx_peer)5609  dp_txrx_peer_reset_local_link_id(struct dp_txrx_peer *txrx_peer)
5610  {
5611  	int i;
5612  
5613  	for (i = 0; i <= DP_MAX_MLO_LINKS; i++)
5614  		txrx_peer->ll_band[i] = DP_BAND_INVALID;
5615  }
5616  #else
5617  static inline void
dp_txrx_peer_reset_local_link_id(struct dp_txrx_peer * txrx_peer)5618  dp_txrx_peer_reset_local_link_id(struct dp_txrx_peer *txrx_peer)
5619  {
5620  }
5621  #endif
5622  
5623  /**
5624   * dp_peer_create_wifi3() - attach txrx peer
5625   * @soc_hdl: Datapath soc handle
5626   * @vdev_id: id of vdev
5627   * @peer_mac_addr: Peer MAC address
5628   * @peer_type: link or MLD peer type
5629   *
5630   * Return: 0 on success, -1 on failure
5631   */
5632  static QDF_STATUS
dp_peer_create_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac_addr,enum cdp_peer_type peer_type)5633  dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
5634  		     uint8_t *peer_mac_addr, enum cdp_peer_type peer_type)
5635  {
5636  	struct dp_peer *peer;
5637  	int i;
5638  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
5639  	struct dp_pdev *pdev;
5640  	enum cdp_txrx_ast_entry_type ast_type = CDP_TXRX_AST_TYPE_STATIC;
5641  	struct dp_vdev *vdev = NULL;
5642  
5643  	if (!peer_mac_addr)
5644  		return QDF_STATUS_E_FAILURE;
5645  
5646  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
5647  
5648  	if (!vdev)
5649  		return QDF_STATUS_E_FAILURE;
5650  
5651  	pdev = vdev->pdev;
5652  	soc = pdev->soc;
5653  
5654  	/*
5655  	 * If a peer entry with given MAC address already exists,
5656  	 * reuse the peer and reset the state of peer.
5657  	 */
5658  	peer = dp_peer_can_reuse(vdev, peer_mac_addr, peer_type);
5659  
5660  	if (peer) {
5661  		qdf_atomic_init(&peer->is_default_route_set);
5662  		dp_peer_cleanup(vdev, peer);
5663  
5664  		dp_peer_vdev_list_add(soc, vdev, peer);
5665  		dp_peer_find_hash_add(soc, peer);
5666  
5667  		if (dp_peer_rx_tids_create(peer) != QDF_STATUS_SUCCESS) {
5668  			dp_alert("RX tid alloc fail for peer %pK (" QDF_MAC_ADDR_FMT ")",
5669  				 peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw));
5670  			dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5671  			return QDF_STATUS_E_FAILURE;
5672  		}
5673  
5674  		if (IS_MLO_DP_MLD_PEER(peer))
5675  			dp_mld_peer_init_link_peers_info(peer);
5676  
5677  		qdf_spin_lock_bh(&soc->ast_lock);
5678  		dp_peer_delete_ast_entries(soc, peer);
5679  		qdf_spin_unlock_bh(&soc->ast_lock);
5680  
5681  		if ((vdev->opmode == wlan_op_mode_sta) &&
5682  		    !qdf_mem_cmp(peer_mac_addr, &vdev->mac_addr.raw[0],
5683  		     QDF_MAC_ADDR_SIZE)) {
5684  			ast_type = CDP_TXRX_AST_TYPE_SELF;
5685  		}
5686  		dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0);
5687  
5688  		peer->valid = 1;
5689  		peer->is_tdls_peer = false;
5690  		dp_local_peer_id_alloc(pdev, peer);
5691  
5692  		qdf_spinlock_create(&peer->peer_info_lock);
5693  
5694  		DP_STATS_INIT(peer);
5695  
5696  		/*
5697  		 * In tx_monitor mode, filter may be set for unassociated peer
5698  		 * when unassociated peer get associated peer need to
5699  		 * update tx_cap_enabled flag to support peer filter.
5700  		 */
5701  		if (!IS_MLO_DP_MLD_PEER(peer)) {
5702  			dp_monitor_peer_tx_capture_filter_check(pdev, peer);
5703  			dp_monitor_peer_reset_stats(soc, peer);
5704  		}
5705  
5706  		if (peer->txrx_peer) {
5707  			dp_peer_rx_bufq_resources_init(peer->txrx_peer);
5708  			dp_txrx_peer_stats_clr(peer->txrx_peer);
5709  			dp_set_peer_isolation(peer->txrx_peer, false);
5710  			dp_wds_ext_peer_init(peer->txrx_peer);
5711  			dp_peer_hw_txrx_stats_init(soc, peer->txrx_peer);
5712  			dp_txrx_peer_reset_local_link_id(peer->txrx_peer);
5713  		}
5714  
5715  		dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_CREATE,
5716  					     peer, vdev, 1);
5717  		dp_info("vdev %pK Reused peer %pK ("QDF_MAC_ADDR_FMT
5718  			") vdev_ref_cnt "
5719  			"%d peer_ref_cnt: %d",
5720  			vdev, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw),
5721  			qdf_atomic_read(&vdev->ref_cnt),
5722  			qdf_atomic_read(&peer->ref_cnt));
5723  			dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT);
5724  
5725  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5726  		return QDF_STATUS_SUCCESS;
5727  	} else {
5728  		/*
5729  		 * When a STA roams from RPTR AP to ROOT AP and vice versa, we
5730  		 * need to remove the AST entry which was earlier added as a WDS
5731  		 * entry.
5732  		 * If an AST entry exists, but no peer entry exists with a given
5733  		 * MAC addresses, we could deduce it as a WDS entry
5734  		 */
5735  		dp_peer_ast_handle_roam_del(soc, pdev, peer_mac_addr);
5736  	}
5737  
5738  #ifdef notyet
5739  	peer = (struct dp_peer *)qdf_mempool_alloc(soc->osdev,
5740  		soc->mempool_ol_ath_peer);
5741  #else
5742  	peer = (struct dp_peer *)qdf_mem_malloc(sizeof(*peer));
5743  #endif
5744  	wlan_minidump_log(peer,
5745  			  sizeof(*peer),
5746  			  soc->ctrl_psoc,
5747  			  WLAN_MD_DP_PEER, "dp_peer");
5748  	if (!peer) {
5749  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5750  		return QDF_STATUS_E_FAILURE; /* failure */
5751  	}
5752  
5753  	qdf_mem_zero(peer, sizeof(struct dp_peer));
5754  
5755  	/* store provided params */
5756  	peer->vdev = vdev;
5757  
5758  	/* initialize the peer_id */
5759  	peer->peer_id = HTT_INVALID_PEER;
5760  
5761  	qdf_mem_copy(
5762  		&peer->mac_addr.raw[0], peer_mac_addr, QDF_MAC_ADDR_SIZE);
5763  
5764  	DP_PEER_SET_TYPE(peer, peer_type);
5765  	if (IS_MLO_DP_MLD_PEER(peer)) {
5766  		if (dp_txrx_peer_attach(soc, peer) !=
5767  				QDF_STATUS_SUCCESS)
5768  			goto fail; /* failure */
5769  
5770  		dp_mld_peer_init_link_peers_info(peer);
5771  	}
5772  
5773  	if (dp_monitor_peer_attach(soc, peer) != QDF_STATUS_SUCCESS)
5774  		dp_warn("peer monitor ctx alloc failed");
5775  
5776  	TAILQ_INIT(&peer->ast_entry_list);
5777  
5778  	/* get the vdev reference for new peer */
5779  	dp_vdev_get_ref(soc, vdev, DP_MOD_ID_CHILD);
5780  
5781  	if ((vdev->opmode == wlan_op_mode_sta) &&
5782  	    !qdf_mem_cmp(peer_mac_addr, &vdev->mac_addr.raw[0],
5783  			 QDF_MAC_ADDR_SIZE)) {
5784  		ast_type = CDP_TXRX_AST_TYPE_SELF;
5785  	}
5786  	qdf_spinlock_create(&peer->peer_state_lock);
5787  	dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0);
5788  	qdf_spinlock_create(&peer->peer_info_lock);
5789  
5790  	/* reset the ast index to flowid table */
5791  	dp_peer_reset_flowq_map(peer);
5792  
5793  	qdf_atomic_init(&peer->ref_cnt);
5794  
5795  	for (i = 0; i < DP_MOD_ID_MAX; i++)
5796  		qdf_atomic_init(&peer->mod_refs[i]);
5797  
5798  	/* keep one reference for attach */
5799  	qdf_atomic_inc(&peer->ref_cnt);
5800  	qdf_atomic_inc(&peer->mod_refs[DP_MOD_ID_CONFIG]);
5801  
5802  	dp_peer_vdev_list_add(soc, vdev, peer);
5803  
5804  	/* TODO: See if hash based search is required */
5805  	dp_peer_find_hash_add(soc, peer);
5806  
5807  	/* Initialize the peer state */
5808  	peer->state = OL_TXRX_PEER_STATE_DISC;
5809  
5810  	dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_CREATE,
5811  				     peer, vdev, 0);
5812  	dp_info("vdev %pK created peer %pK ("QDF_MAC_ADDR_FMT") vdev_ref_cnt "
5813  		"%d peer_ref_cnt: %d",
5814  		vdev, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw),
5815  		qdf_atomic_read(&vdev->ref_cnt),
5816  		qdf_atomic_read(&peer->ref_cnt));
5817  	/*
5818  	 * For every peer MAp message search and set if bss_peer
5819  	 */
5820  	if (qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
5821  			QDF_MAC_ADDR_SIZE) == 0 &&
5822  			(wlan_op_mode_sta != vdev->opmode)) {
5823  		dp_info("vdev bss_peer!!");
5824  		peer->bss_peer = 1;
5825  		if (peer->txrx_peer)
5826  			peer->txrx_peer->bss_peer = 1;
5827  	}
5828  
5829  	if (wlan_op_mode_sta == vdev->opmode &&
5830  	    qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
5831  			QDF_MAC_ADDR_SIZE) == 0) {
5832  		peer->sta_self_peer = 1;
5833  	}
5834  
5835  	if (dp_peer_rx_tids_create(peer) != QDF_STATUS_SUCCESS) {
5836  		dp_alert("RX tid alloc fail for peer %pK (" QDF_MAC_ADDR_FMT ")",
5837  			 peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw));
5838  		goto fail;
5839  	}
5840  
5841  	peer->valid = 1;
5842  	dp_local_peer_id_alloc(pdev, peer);
5843  	DP_STATS_INIT(peer);
5844  
5845  	if (dp_peer_sawf_ctx_alloc(soc, peer) != QDF_STATUS_SUCCESS)
5846  		dp_warn("peer sawf context alloc failed");
5847  
5848  	dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT);
5849  
5850  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5851  
5852  	return QDF_STATUS_SUCCESS;
5853  fail:
5854  	qdf_mem_free(peer);
5855  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
5856  
5857  	return QDF_STATUS_E_FAILURE;
5858  }
5859  
dp_peer_legacy_setup(struct dp_soc * soc,struct dp_peer * peer)5860  QDF_STATUS dp_peer_legacy_setup(struct dp_soc *soc, struct dp_peer *peer)
5861  {
5862  	/* txrx_peer might exist already in peer reuse case */
5863  	if (peer->txrx_peer)
5864  		return QDF_STATUS_SUCCESS;
5865  
5866  	if (dp_txrx_peer_attach(soc, peer) !=
5867  				QDF_STATUS_SUCCESS) {
5868  		dp_err("peer txrx ctx alloc failed");
5869  		return QDF_STATUS_E_FAILURE;
5870  	}
5871  
5872  	return QDF_STATUS_SUCCESS;
5873  }
5874  
5875  #ifdef WLAN_FEATURE_11BE_MLO
dp_mld_peer_change_vdev(struct dp_soc * soc,struct dp_peer * mld_peer,uint8_t new_vdev_id)5876  static QDF_STATUS dp_mld_peer_change_vdev(struct dp_soc *soc,
5877  					  struct dp_peer *mld_peer,
5878  					  uint8_t new_vdev_id)
5879  {
5880  	struct dp_vdev *prev_vdev;
5881  
5882  	prev_vdev = mld_peer->vdev;
5883  	/* release the ref to original dp_vdev */
5884  	dp_vdev_unref_delete(soc, mld_peer->vdev,
5885  			     DP_MOD_ID_CHILD);
5886  	/*
5887  	 * get the ref to new dp_vdev,
5888  	 * increase dp_vdev ref_cnt
5889  	 */
5890  	mld_peer->vdev = dp_vdev_get_ref_by_id(soc, new_vdev_id,
5891  					       DP_MOD_ID_CHILD);
5892  	mld_peer->txrx_peer->vdev = mld_peer->vdev;
5893  
5894  	dp_info("Change vdev for ML peer " QDF_MAC_ADDR_FMT
5895  		" old vdev %pK id %d new vdev %pK id %d",
5896  		QDF_MAC_ADDR_REF(mld_peer->mac_addr.raw),
5897  		prev_vdev, prev_vdev->vdev_id, mld_peer->vdev, new_vdev_id);
5898  
5899  	dp_cfg_event_record_mlo_setup_vdev_update_evt(
5900  			soc, mld_peer, prev_vdev,
5901  			mld_peer->vdev);
5902  
5903  	return QDF_STATUS_SUCCESS;
5904  }
5905  
dp_peer_mlo_setup(struct dp_soc * soc,struct dp_peer * peer,uint8_t vdev_id,struct cdp_peer_setup_info * setup_info)5906  QDF_STATUS dp_peer_mlo_setup(
5907  			struct dp_soc *soc,
5908  			struct dp_peer *peer,
5909  			uint8_t vdev_id,
5910  			struct cdp_peer_setup_info *setup_info)
5911  {
5912  	struct dp_peer *mld_peer = NULL;
5913  	struct cdp_txrx_peer_params_update params = {0};
5914  
5915  	/* Non-MLO connection */
5916  	if (!setup_info || !setup_info->mld_peer_mac) {
5917  		/* To handle downgrade scenarios */
5918  		if (peer->vdev->opmode == wlan_op_mode_sta) {
5919  			struct cdp_txrx_peer_params_update params = {0};
5920  
5921  			params.chip_id = dp_get_chip_id(soc);
5922  			params.pdev_id = peer->vdev->pdev->pdev_id;
5923  			params.vdev_id = peer->vdev->vdev_id;
5924  
5925  			dp_wdi_event_handler(
5926  					WDI_EVENT_STA_PRIMARY_UMAC_UPDATE,
5927  					soc,
5928  					(void *)&params, peer->peer_id,
5929  					WDI_NO_VAL, params.pdev_id);
5930  		}
5931  		return QDF_STATUS_SUCCESS;
5932  	}
5933  
5934  	dp_cfg_event_record_peer_setup_evt(soc, DP_CFG_EVENT_MLO_SETUP,
5935  					   peer, NULL, vdev_id, setup_info);
5936  
5937  	/* if this is the first link peer */
5938  	if (setup_info->is_first_link)
5939  		/* create MLD peer */
5940  		dp_peer_create_wifi3((struct cdp_soc_t *)soc,
5941  				     vdev_id,
5942  				     setup_info->mld_peer_mac,
5943  				     CDP_MLD_PEER_TYPE);
5944  
5945  	if (peer->vdev->opmode == wlan_op_mode_sta &&
5946  	    setup_info->is_primary_link) {
5947  		struct cdp_txrx_peer_params_update params = {0};
5948  
5949  		params.chip_id = dp_get_chip_id(soc);
5950  		params.pdev_id = peer->vdev->pdev->pdev_id;
5951  		params.vdev_id = peer->vdev->vdev_id;
5952  
5953  		dp_wdi_event_handler(
5954  				WDI_EVENT_STA_PRIMARY_UMAC_UPDATE,
5955  				soc,
5956  				(void *)&params, peer->peer_id,
5957  				WDI_NO_VAL, params.pdev_id);
5958  	}
5959  
5960  	peer->first_link = setup_info->is_first_link;
5961  	peer->primary_link = setup_info->is_primary_link;
5962  	mld_peer = dp_mld_peer_find_hash_find(soc,
5963  					      setup_info->mld_peer_mac,
5964  					      0, vdev_id, DP_MOD_ID_CDP);
5965  
5966  	dp_info("Peer %pK MAC " QDF_MAC_ADDR_FMT " mld peer %pK MAC "
5967  		QDF_MAC_ADDR_FMT " first_link %d, primary_link %d", peer,
5968  		QDF_MAC_ADDR_REF(peer->mac_addr.raw), mld_peer,
5969  		QDF_MAC_ADDR_REF(setup_info->mld_peer_mac),
5970  		peer->first_link,
5971  		peer->primary_link);
5972  
5973  	if (mld_peer) {
5974  		if (setup_info->is_first_link) {
5975  			/* assign rx_tid to mld peer */
5976  			mld_peer->rx_tid = peer->rx_tid;
5977  			/* no cdp_peer_setup for MLD peer,
5978  			 * set it for addba processing
5979  			 */
5980  			qdf_atomic_set(&mld_peer->is_default_route_set, 1);
5981  		} else {
5982  			/* free link peer original rx_tids mem */
5983  			dp_peer_rx_tids_destroy(peer);
5984  			/* assign mld peer rx_tid to link peer */
5985  			peer->rx_tid = mld_peer->rx_tid;
5986  		}
5987  
5988  		if (setup_info->is_primary_link &&
5989  		    !setup_info->is_first_link) {
5990  			/*
5991  			 * if first link is not the primary link,
5992  			 * then need to change mld_peer->vdev as
5993  			 * primary link dp_vdev is not same one
5994  			 * during mld peer creation.
5995  			 */
5996  			dp_info("Primary link is not the first link. vdev: %pK "
5997  				"vdev_id %d vdev_ref_cnt %d",
5998  				mld_peer->vdev, vdev_id,
5999  				qdf_atomic_read(&mld_peer->vdev->ref_cnt));
6000  
6001  			dp_mld_peer_change_vdev(soc, mld_peer, vdev_id);
6002  
6003  			params.vdev_id = peer->vdev->vdev_id;
6004  			params.peer_mac = mld_peer->mac_addr.raw;
6005  			params.chip_id = dp_get_chip_id(soc);
6006  			params.pdev_id = peer->vdev->pdev->pdev_id;
6007  
6008  			dp_wdi_event_handler(
6009  					WDI_EVENT_PEER_PRIMARY_UMAC_UPDATE,
6010  					soc, (void *)&params, peer->peer_id,
6011  					WDI_NO_VAL, params.pdev_id);
6012  		}
6013  
6014  		/* associate mld and link peer */
6015  		dp_link_peer_add_mld_peer(peer, mld_peer);
6016  		dp_mld_peer_add_link_peer(mld_peer, peer, setup_info->is_bridge_peer);
6017  
6018  		mld_peer->txrx_peer->is_mld_peer = 1;
6019  		dp_peer_unref_delete(mld_peer, DP_MOD_ID_CDP);
6020  	} else {
6021  		peer->mld_peer = NULL;
6022  		dp_err("mld peer" QDF_MAC_ADDR_FMT "not found!",
6023  		       QDF_MAC_ADDR_REF(setup_info->mld_peer_mac));
6024  		return QDF_STATUS_E_FAILURE;
6025  	}
6026  
6027  	return QDF_STATUS_SUCCESS;
6028  }
6029  
6030  /**
6031   * dp_mlo_peer_authorize() - authorize MLO peer
6032   * @soc: soc handle
6033   * @peer: pointer to link peer
6034   *
6035   * Return: void
6036   */
dp_mlo_peer_authorize(struct dp_soc * soc,struct dp_peer * peer)6037  static void dp_mlo_peer_authorize(struct dp_soc *soc,
6038  				  struct dp_peer *peer)
6039  {
6040  	int i;
6041  	struct dp_peer *link_peer = NULL;
6042  	struct dp_peer *mld_peer = peer->mld_peer;
6043  	struct dp_mld_link_peers link_peers_info;
6044  
6045  	if (!mld_peer)
6046  		return;
6047  
6048  	/* get link peers with reference */
6049  	dp_get_link_peers_ref_from_mld_peer(soc, mld_peer,
6050  					    &link_peers_info,
6051  					    DP_MOD_ID_CDP);
6052  
6053  	for (i = 0; i < link_peers_info.num_links; i++) {
6054  		link_peer = link_peers_info.link_peers[i];
6055  
6056  		if (!link_peer->authorize) {
6057  			dp_release_link_peers_ref(&link_peers_info,
6058  						  DP_MOD_ID_CDP);
6059  			mld_peer->authorize = false;
6060  			return;
6061  		}
6062  	}
6063  
6064  	/* if we are here all link peers are authorized,
6065  	 * authorize ml_peer also
6066  	 */
6067  	mld_peer->authorize = true;
6068  
6069  	/* release link peers reference */
6070  	dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
6071  }
6072  #endif
6073  
6074  /**
6075   * dp_peer_setup_wifi3_wrapper() - initialize the peer
6076   * @soc_hdl: soc handle object
6077   * @vdev_id : vdev_id of vdev object
6078   * @peer_mac: Peer's mac address
6079   * @setup_info: peer setup info for MLO
6080   *
6081   * Return: QDF_STATUS
6082   */
6083  static QDF_STATUS
dp_peer_setup_wifi3_wrapper(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,struct cdp_peer_setup_info * setup_info)6084  dp_peer_setup_wifi3_wrapper(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
6085  			    uint8_t *peer_mac,
6086  			    struct cdp_peer_setup_info *setup_info)
6087  {
6088  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
6089  
6090  	return soc->arch_ops.txrx_peer_setup(soc_hdl, vdev_id,
6091  					     peer_mac, setup_info);
6092  }
6093  
6094  /**
6095   * dp_cp_peer_del_resp_handler() - Handle the peer delete response
6096   * @soc_hdl: Datapath SOC handle
6097   * @vdev_id: id of virtual device object
6098   * @mac_addr: Mac address of the peer
6099   *
6100   * Return: QDF_STATUS
6101   */
dp_cp_peer_del_resp_handler(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mac_addr)6102  static QDF_STATUS dp_cp_peer_del_resp_handler(struct cdp_soc_t *soc_hdl,
6103  					      uint8_t vdev_id,
6104  					      uint8_t *mac_addr)
6105  {
6106  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
6107  	struct dp_ast_entry  *ast_entry = NULL;
6108  	txrx_ast_free_cb cb = NULL;
6109  	void *cookie;
6110  
6111  	if (soc->ast_offload_support)
6112  		return QDF_STATUS_E_INVAL;
6113  
6114  	qdf_spin_lock_bh(&soc->ast_lock);
6115  
6116  	ast_entry =
6117  		dp_peer_ast_hash_find_by_vdevid(soc, mac_addr,
6118  						vdev_id);
6119  
6120  	/* in case of qwrap we have multiple BSS peers
6121  	 * with same mac address
6122  	 *
6123  	 * AST entry for this mac address will be created
6124  	 * only for one peer hence it will be NULL here
6125  	 */
6126  	if ((!ast_entry || !ast_entry->delete_in_progress) ||
6127  	    (ast_entry->peer_id != HTT_INVALID_PEER)) {
6128  		qdf_spin_unlock_bh(&soc->ast_lock);
6129  		return QDF_STATUS_E_FAILURE;
6130  	}
6131  
6132  	if (ast_entry->is_mapped)
6133  		soc->ast_table[ast_entry->ast_idx] = NULL;
6134  
6135  	DP_STATS_INC(soc, ast.deleted, 1);
6136  	dp_peer_ast_hash_remove(soc, ast_entry);
6137  
6138  	cb = ast_entry->callback;
6139  	cookie = ast_entry->cookie;
6140  	ast_entry->callback = NULL;
6141  	ast_entry->cookie = NULL;
6142  
6143  	soc->num_ast_entries--;
6144  	qdf_spin_unlock_bh(&soc->ast_lock);
6145  
6146  	if (cb) {
6147  		cb(soc->ctrl_psoc,
6148  		   dp_soc_to_cdp_soc(soc),
6149  		   cookie,
6150  		   CDP_TXRX_AST_DELETED);
6151  	}
6152  	qdf_mem_free(ast_entry);
6153  
6154  	return QDF_STATUS_SUCCESS;
6155  }
6156  
6157  #ifdef WLAN_SUPPORT_MSCS
6158  /**
6159   * dp_record_mscs_params() - Record MSCS parameters sent by the STA in
6160   * the MSCS Request to the AP.
6161   * @soc_hdl: Datapath soc handle
6162   * @peer_mac: STA Mac address
6163   * @vdev_id: ID of the vdev handle
6164   * @mscs_params: Structure having MSCS parameters obtained
6165   * from handshake
6166   * @active: Flag to set MSCS active/inactive
6167   *
6168   * The AP makes a note of these parameters while comparing the MSDUs
6169   * sent by the STA, to send the downlink traffic with correct User
6170   * priority.
6171   *
6172   * Return: QDF_STATUS - Success/Invalid
6173   */
6174  static QDF_STATUS
dp_record_mscs_params(struct cdp_soc_t * soc_hdl,uint8_t * peer_mac,uint8_t vdev_id,struct cdp_mscs_params * mscs_params,bool active)6175  dp_record_mscs_params(struct cdp_soc_t *soc_hdl, uint8_t *peer_mac,
6176  		      uint8_t vdev_id, struct cdp_mscs_params *mscs_params,
6177  		      bool active)
6178  {
6179  	struct dp_peer *peer;
6180  	struct dp_peer *tgt_peer;
6181  	QDF_STATUS status = QDF_STATUS_E_INVAL;
6182  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
6183  
6184  	peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
6185  				      DP_MOD_ID_CDP);
6186  
6187  	if (!peer) {
6188  		dp_err("Peer is NULL!");
6189  		goto fail;
6190  	}
6191  
6192  	tgt_peer = dp_get_tgt_peer_from_peer(peer);
6193  	if (!tgt_peer)
6194  		goto fail;
6195  
6196  	if (!active) {
6197  		dp_info("MSCS Procedure is terminated");
6198  		tgt_peer->mscs_active = active;
6199  		goto fail;
6200  	}
6201  
6202  	if (mscs_params->classifier_type == IEEE80211_TCLAS_MASK_CLA_TYPE_4) {
6203  		/* Populate entries inside IPV4 database first */
6204  		tgt_peer->mscs_ipv4_parameter.user_priority_bitmap =
6205  			mscs_params->user_pri_bitmap;
6206  		tgt_peer->mscs_ipv4_parameter.user_priority_limit =
6207  			mscs_params->user_pri_limit;
6208  		tgt_peer->mscs_ipv4_parameter.classifier_mask =
6209  			mscs_params->classifier_mask;
6210  
6211  		/* Populate entries inside IPV6 database */
6212  		tgt_peer->mscs_ipv6_parameter.user_priority_bitmap =
6213  			mscs_params->user_pri_bitmap;
6214  		tgt_peer->mscs_ipv6_parameter.user_priority_limit =
6215  			mscs_params->user_pri_limit;
6216  		tgt_peer->mscs_ipv6_parameter.classifier_mask =
6217  			mscs_params->classifier_mask;
6218  		tgt_peer->mscs_active = 1;
6219  		dp_info("\n\tMSCS Procedure request based parameters for "QDF_MAC_ADDR_FMT"\n"
6220  			"\tClassifier_type = %d\tUser priority bitmap = %x\n"
6221  			"\tUser priority limit = %x\tClassifier mask = %x",
6222  			QDF_MAC_ADDR_REF(peer_mac),
6223  			mscs_params->classifier_type,
6224  			tgt_peer->mscs_ipv4_parameter.user_priority_bitmap,
6225  			tgt_peer->mscs_ipv4_parameter.user_priority_limit,
6226  			tgt_peer->mscs_ipv4_parameter.classifier_mask);
6227  	}
6228  
6229  	status = QDF_STATUS_SUCCESS;
6230  fail:
6231  	if (peer)
6232  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6233  	return status;
6234  }
6235  #endif
6236  
6237  /**
6238   * dp_get_sec_type() - Get the security type
6239   * @soc: soc handle
6240   * @vdev_id: id of dp handle
6241   * @peer_mac: mac of datapath PEER handle
6242   * @sec_idx:    Security id (mcast, ucast)
6243   *
6244   * return sec_type: Security type
6245   */
dp_get_sec_type(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac,uint8_t sec_idx)6246  static int dp_get_sec_type(struct cdp_soc_t *soc, uint8_t vdev_id,
6247  			   uint8_t *peer_mac, uint8_t sec_idx)
6248  {
6249  	int sec_type = 0;
6250  	struct dp_peer *peer =
6251  			dp_peer_get_tgt_peer_hash_find((struct dp_soc *)soc,
6252  						       peer_mac, 0, vdev_id,
6253  						       DP_MOD_ID_CDP);
6254  
6255  	if (!peer) {
6256  		dp_cdp_err("%pK: Peer is NULL!", (struct dp_soc *)soc);
6257  		return sec_type;
6258  	}
6259  
6260  	if (!peer->txrx_peer) {
6261  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6262  		dp_peer_debug("%pK: txrx peer is NULL!", soc);
6263  		return sec_type;
6264  	}
6265  	sec_type = peer->txrx_peer->security[sec_idx].sec_type;
6266  
6267  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6268  	return sec_type;
6269  }
6270  
6271  /**
6272   * dp_peer_authorize() - authorize txrx peer
6273   * @soc_hdl: soc handle
6274   * @vdev_id: id of dp handle
6275   * @peer_mac: mac of datapath PEER handle
6276   * @authorize:
6277   *
6278   * Return: QDF_STATUS
6279   *
6280   */
6281  static QDF_STATUS
dp_peer_authorize(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,uint32_t authorize)6282  dp_peer_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
6283  		  uint8_t *peer_mac, uint32_t authorize)
6284  {
6285  	QDF_STATUS status = QDF_STATUS_SUCCESS;
6286  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
6287  	struct dp_peer *peer = dp_peer_get_tgt_peer_hash_find(soc, peer_mac,
6288  							      0, vdev_id,
6289  							      DP_MOD_ID_CDP);
6290  
6291  	if (!peer) {
6292  		dp_cdp_debug("%pK: Peer is NULL!", soc);
6293  		status = QDF_STATUS_E_FAILURE;
6294  	} else {
6295  		peer->authorize = authorize ? 1 : 0;
6296  		if (peer->txrx_peer)
6297  			peer->txrx_peer->authorize = peer->authorize;
6298  
6299  		if (!peer->authorize)
6300  			dp_peer_flush_frags(soc_hdl, vdev_id, peer_mac);
6301  
6302  		dp_mlo_peer_authorize(soc, peer);
6303  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6304  	}
6305  
6306  	return status;
6307  }
6308  
6309  /**
6310   * dp_peer_get_authorize() - get peer authorize status
6311   * @soc_hdl: soc handle
6312   * @vdev_id: id of dp handle
6313   * @peer_mac: mac of datapath PEER handle
6314   *
6315   * Return: true is peer is authorized, false otherwise
6316   */
6317  static bool
dp_peer_get_authorize(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac)6318  dp_peer_get_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
6319  		      uint8_t *peer_mac)
6320  {
6321  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
6322  	bool authorize = false;
6323  	struct dp_peer *peer = dp_peer_find_hash_find(soc, peer_mac,
6324  						      0, vdev_id,
6325  						      DP_MOD_ID_CDP);
6326  
6327  	if (!peer) {
6328  		dp_cdp_debug("%pK: Peer is NULL!", soc);
6329  		return authorize;
6330  	}
6331  
6332  	authorize = peer->authorize;
6333  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6334  
6335  	return authorize;
6336  }
6337  
dp_vdev_unref_delete(struct dp_soc * soc,struct dp_vdev * vdev,enum dp_mod_id mod_id)6338  void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
6339  			  enum dp_mod_id mod_id)
6340  {
6341  	ol_txrx_vdev_delete_cb vdev_delete_cb = NULL;
6342  	void *vdev_delete_context = NULL;
6343  	ol_txrx_vdev_delete_cb vdev_del_notify = NULL;
6344  	void *vdev_del_noitfy_ctx = NULL;
6345  	uint8_t vdev_id = vdev->vdev_id;
6346  	struct dp_pdev *pdev = vdev->pdev;
6347  	struct dp_vdev *tmp_vdev = NULL;
6348  	uint8_t found = 0;
6349  
6350  	QDF_ASSERT(qdf_atomic_dec_return(&vdev->mod_refs[mod_id]) >= 0);
6351  
6352  	/* Return if this is not the last reference*/
6353  	if (!qdf_atomic_dec_and_test(&vdev->ref_cnt))
6354  		return;
6355  
6356  	/*
6357  	 * This should be set as last reference need to released
6358  	 * after cdp_vdev_detach() is called
6359  	 *
6360  	 * if this assert is hit there is a ref count issue
6361  	 */
6362  	QDF_ASSERT(vdev->delete.pending);
6363  
6364  	vdev_delete_cb = vdev->delete.callback;
6365  	vdev_delete_context = vdev->delete.context;
6366  
6367  	vdev_del_notify = vdev->vdev_del_notify;
6368  	vdev_del_noitfy_ctx = vdev->osif_vdev;
6369  
6370  	dp_info("deleting vdev object %pK (" QDF_MAC_ADDR_FMT ")%s",
6371  		vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw),
6372  		vdev_del_notify ? " with del_notify" : "");
6373  
6374  	if (wlan_op_mode_monitor == vdev->opmode) {
6375  		dp_monitor_vdev_delete(soc, vdev);
6376  		goto free_vdev;
6377  	}
6378  
6379  	/* all peers are gone, go ahead and delete it */
6380  	dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
6381  			FLOW_TYPE_VDEV, vdev_id);
6382  	dp_tx_vdev_detach(vdev);
6383  	dp_monitor_vdev_detach(vdev);
6384  
6385  free_vdev:
6386  	qdf_spinlock_destroy(&vdev->peer_list_lock);
6387  
6388  	qdf_spin_lock_bh(&soc->inactive_vdev_list_lock);
6389  	TAILQ_FOREACH(tmp_vdev, &soc->inactive_vdev_list,
6390  		      inactive_list_elem) {
6391  		if (tmp_vdev == vdev) {
6392  			found = 1;
6393  			break;
6394  		}
6395  	}
6396  	if (found)
6397  		TAILQ_REMOVE(&soc->inactive_vdev_list, vdev,
6398  			     inactive_list_elem);
6399  	/* delete this peer from the list */
6400  	qdf_spin_unlock_bh(&soc->inactive_vdev_list_lock);
6401  
6402  	dp_cfg_event_record_vdev_evt(soc, DP_CFG_EVENT_VDEV_UNREF_DEL,
6403  				     vdev);
6404  	wlan_minidump_remove(vdev, sizeof(*vdev), soc->ctrl_psoc,
6405  			     WLAN_MD_DP_VDEV, "dp_vdev");
6406  	qdf_mem_free(vdev);
6407  	vdev = NULL;
6408  
6409  	if (vdev_delete_cb)
6410  		vdev_delete_cb(vdev_delete_context);
6411  
6412  	if (vdev_del_notify)
6413  		vdev_del_notify(vdev_del_noitfy_ctx);
6414  }
6415  
6416  qdf_export_symbol(dp_vdev_unref_delete);
6417  
dp_peer_unref_delete(struct dp_peer * peer,enum dp_mod_id mod_id)6418  void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id)
6419  {
6420  	struct dp_vdev *vdev = peer->vdev;
6421  	struct dp_pdev *pdev = vdev->pdev;
6422  	struct dp_soc *soc = pdev->soc;
6423  	uint16_t peer_id;
6424  	struct dp_peer *tmp_peer;
6425  	bool found = false;
6426  
6427  	if (mod_id > DP_MOD_ID_RX)
6428  		QDF_ASSERT(qdf_atomic_dec_return(&peer->mod_refs[mod_id]) >= 0);
6429  
6430  	/*
6431  	 * Hold the lock all the way from checking if the peer ref count
6432  	 * is zero until the peer references are removed from the hash
6433  	 * table and vdev list (if the peer ref count is zero).
6434  	 * This protects against a new HL tx operation starting to use the
6435  	 * peer object just after this function concludes it's done being used.
6436  	 * Furthermore, the lock needs to be held while checking whether the
6437  	 * vdev's list of peers is empty, to make sure that list is not modified
6438  	 * concurrently with the empty check.
6439  	 */
6440  	if (qdf_atomic_dec_and_test(&peer->ref_cnt)) {
6441  		peer_id = peer->peer_id;
6442  
6443  		/*
6444  		 * Make sure that the reference to the peer in
6445  		 * peer object map is removed
6446  		 */
6447  		QDF_ASSERT(peer_id == HTT_INVALID_PEER);
6448  
6449  		dp_peer_info("Deleting peer %pK ("QDF_MAC_ADDR_FMT")", peer,
6450  			     QDF_MAC_ADDR_REF(peer->mac_addr.raw));
6451  
6452  		dp_peer_sawf_ctx_free(soc, peer);
6453  
6454  		wlan_minidump_remove(peer, sizeof(*peer), soc->ctrl_psoc,
6455  				     WLAN_MD_DP_PEER, "dp_peer");
6456  
6457  		qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
6458  		TAILQ_FOREACH(tmp_peer, &soc->inactive_peer_list,
6459  			      inactive_list_elem) {
6460  			if (tmp_peer == peer) {
6461  				found = 1;
6462  				break;
6463  			}
6464  		}
6465  		if (found)
6466  			TAILQ_REMOVE(&soc->inactive_peer_list, peer,
6467  				     inactive_list_elem);
6468  		/* delete this peer from the list */
6469  		qdf_spin_unlock_bh(&soc->inactive_peer_list_lock);
6470  		DP_AST_ASSERT(TAILQ_EMPTY(&peer->ast_entry_list));
6471  		dp_peer_update_state(soc, peer, DP_PEER_STATE_FREED);
6472  
6473  		/* cleanup the peer data */
6474  		dp_peer_cleanup(vdev, peer);
6475  
6476  		dp_monitor_peer_detach(soc, peer);
6477  
6478  		qdf_spinlock_destroy(&peer->peer_state_lock);
6479  
6480  		dp_txrx_peer_detach(soc, peer);
6481  		dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_UNREF_DEL,
6482  					     peer, vdev, 0);
6483  		qdf_mem_free(peer);
6484  
6485  		/*
6486  		 * Decrement ref count taken at peer create
6487  		 */
6488  		dp_peer_info("Deleted peer. Unref vdev %pK, vdev_ref_cnt %d",
6489  			     vdev, qdf_atomic_read(&vdev->ref_cnt));
6490  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CHILD);
6491  	}
6492  }
6493  
6494  qdf_export_symbol(dp_peer_unref_delete);
6495  
dp_txrx_peer_unref_delete(dp_txrx_ref_handle handle,enum dp_mod_id mod_id)6496  void dp_txrx_peer_unref_delete(dp_txrx_ref_handle handle,
6497  			       enum dp_mod_id mod_id)
6498  {
6499  	dp_peer_unref_delete((struct dp_peer *)handle, mod_id);
6500  }
6501  
6502  qdf_export_symbol(dp_txrx_peer_unref_delete);
6503  
6504  /**
6505   * dp_peer_delete_wifi3() - Delete txrx peer
6506   * @soc_hdl: soc handle
6507   * @vdev_id: id of dp handle
6508   * @peer_mac: mac of datapath PEER handle
6509   * @bitmap: bitmap indicating special handling of request.
6510   * @peer_type: peer type (link or MLD)
6511   *
6512   */
dp_peer_delete_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,uint32_t bitmap,enum cdp_peer_type peer_type)6513  static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
6514  				       uint8_t vdev_id,
6515  				       uint8_t *peer_mac, uint32_t bitmap,
6516  				       enum cdp_peer_type peer_type)
6517  {
6518  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6519  	struct dp_peer *peer;
6520  	struct cdp_peer_info peer_info = { 0 };
6521  	struct dp_vdev *vdev = NULL;
6522  
6523  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac,
6524  				 false, peer_type);
6525  	peer = dp_peer_hash_find_wrapper(soc, &peer_info, DP_MOD_ID_CDP);
6526  
6527  	/* Peer can be null for monitor vap mac address */
6528  	if (!peer) {
6529  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
6530  			  "%s: Invalid peer\n", __func__);
6531  		return QDF_STATUS_E_FAILURE;
6532  	}
6533  
6534  	if (!peer->valid) {
6535  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6536  		dp_err("Invalid peer: "QDF_MAC_ADDR_FMT,
6537  			QDF_MAC_ADDR_REF(peer_mac));
6538  		return QDF_STATUS_E_ALREADY;
6539  	}
6540  
6541  	vdev = peer->vdev;
6542  
6543  	if (!vdev) {
6544  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6545  		return QDF_STATUS_E_FAILURE;
6546  	}
6547  
6548  	peer->valid = 0;
6549  
6550  	dp_cfg_event_record_peer_evt(soc, DP_CFG_EVENT_PEER_DELETE, peer,
6551  				     vdev, 0);
6552  	dp_init_info("%pK: peer %pK (" QDF_MAC_ADDR_FMT ") pending-refs %d",
6553  		     soc, peer, QDF_MAC_ADDR_REF(peer->mac_addr.raw),
6554  		     qdf_atomic_read(&peer->ref_cnt));
6555  
6556  	dp_peer_rx_reo_shared_qaddr_delete(soc, peer);
6557  
6558  	dp_local_peer_id_free(peer->vdev->pdev, peer);
6559  
6560  	/* Drop all rx packets before deleting peer */
6561  	dp_clear_peer_internal(soc, peer);
6562  
6563  	qdf_spinlock_destroy(&peer->peer_info_lock);
6564  	dp_peer_multipass_list_remove(peer);
6565  
6566  	/* remove the reference to the peer from the hash table */
6567  	dp_peer_find_hash_remove(soc, peer);
6568  
6569  	dp_peer_vdev_list_remove(soc, vdev, peer);
6570  
6571  	dp_peer_mlo_delete(peer);
6572  
6573  	qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
6574  	TAILQ_INSERT_TAIL(&soc->inactive_peer_list, peer,
6575  			  inactive_list_elem);
6576  	qdf_spin_unlock_bh(&soc->inactive_peer_list_lock);
6577  
6578  	/*
6579  	 * Remove the reference added during peer_attach.
6580  	 * The peer will still be left allocated until the
6581  	 * PEER_UNMAP message arrives to remove the other
6582  	 * reference, added by the PEER_MAP message.
6583  	 */
6584  	dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
6585  	/*
6586  	 * Remove the reference taken above
6587  	 */
6588  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6589  
6590  	return QDF_STATUS_SUCCESS;
6591  }
6592  
6593  #ifdef DP_RX_UDP_OVER_PEER_ROAM
dp_update_roaming_peer_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac,uint32_t auth_status)6594  static QDF_STATUS dp_update_roaming_peer_wifi3(struct cdp_soc_t *soc_hdl,
6595  					       uint8_t vdev_id,
6596  					       uint8_t *peer_mac,
6597  					       uint32_t auth_status)
6598  {
6599  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6600  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
6601  						     DP_MOD_ID_CDP);
6602  	if (!vdev)
6603  		return QDF_STATUS_E_FAILURE;
6604  
6605  	vdev->roaming_peer_status = auth_status;
6606  	qdf_mem_copy(vdev->roaming_peer_mac.raw, peer_mac,
6607  		     QDF_MAC_ADDR_SIZE);
6608  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6609  
6610  	return QDF_STATUS_SUCCESS;
6611  }
6612  #endif
6613  /**
6614   * dp_get_vdev_mac_addr_wifi3() - Detach txrx peer
6615   * @soc_hdl: Datapath soc handle
6616   * @vdev_id: virtual interface id
6617   *
6618   * Return: MAC address on success, NULL on failure.
6619   *
6620   */
dp_get_vdev_mac_addr_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)6621  static uint8_t *dp_get_vdev_mac_addr_wifi3(struct cdp_soc_t *soc_hdl,
6622  					   uint8_t vdev_id)
6623  {
6624  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6625  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
6626  						     DP_MOD_ID_CDP);
6627  	uint8_t *mac = NULL;
6628  
6629  	if (!vdev)
6630  		return NULL;
6631  
6632  	mac = vdev->mac_addr.raw;
6633  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6634  
6635  	return mac;
6636  }
6637  
6638  /**
6639   * dp_vdev_set_wds() - Enable per packet stats
6640   * @soc_hdl: DP soc handle
6641   * @vdev_id: id of DP VDEV handle
6642   * @val: value
6643   *
6644   * Return: none
6645   */
dp_vdev_set_wds(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint32_t val)6646  static int dp_vdev_set_wds(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
6647  			   uint32_t val)
6648  {
6649  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6650  	struct dp_vdev *vdev =
6651  		dp_vdev_get_ref_by_id((struct dp_soc *)soc, vdev_id,
6652  				      DP_MOD_ID_CDP);
6653  
6654  	if (!vdev)
6655  		return QDF_STATUS_E_FAILURE;
6656  
6657  	vdev->wds_enabled = val;
6658  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6659  
6660  	return QDF_STATUS_SUCCESS;
6661  }
6662  
dp_get_opmode(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)6663  static int dp_get_opmode(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
6664  {
6665  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6666  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
6667  						     DP_MOD_ID_CDP);
6668  	int opmode;
6669  
6670  	if (!vdev) {
6671  		dp_err_rl("vdev for id %d is NULL", vdev_id);
6672  		return -EINVAL;
6673  	}
6674  	opmode = vdev->opmode;
6675  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6676  
6677  	return opmode;
6678  }
6679  
6680  /**
6681   * dp_get_os_rx_handles_from_vdev_wifi3() - Get os rx handles for a vdev
6682   * @soc_hdl: ol_txrx_soc_handle handle
6683   * @vdev_id: vdev id for which os rx handles are needed
6684   * @stack_fn_p: pointer to stack function pointer
6685   * @osif_vdev_p: pointer to ol_osif_vdev_handle
6686   *
6687   * Return: void
6688   */
6689  static
dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,ol_txrx_rx_fp * stack_fn_p,ol_osif_vdev_handle * osif_vdev_p)6690  void dp_get_os_rx_handles_from_vdev_wifi3(struct cdp_soc_t *soc_hdl,
6691  					  uint8_t vdev_id,
6692  					  ol_txrx_rx_fp *stack_fn_p,
6693  					  ol_osif_vdev_handle *osif_vdev_p)
6694  {
6695  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6696  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
6697  						     DP_MOD_ID_CDP);
6698  
6699  	if (qdf_unlikely(!vdev)) {
6700  		*stack_fn_p = NULL;
6701  		*osif_vdev_p = NULL;
6702  		return;
6703  	}
6704  	*stack_fn_p = vdev->osif_rx_stack;
6705  	*osif_vdev_p = vdev->osif_vdev;
6706  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6707  }
6708  
6709  /**
6710   * dp_get_ctrl_pdev_from_vdev_wifi3() - Get control pdev of vdev
6711   * @soc_hdl: datapath soc handle
6712   * @vdev_id: virtual device/interface id
6713   *
6714   * Return: Handle to control pdev
6715   */
dp_get_ctrl_pdev_from_vdev_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)6716  static struct cdp_cfg *dp_get_ctrl_pdev_from_vdev_wifi3(
6717  						struct cdp_soc_t *soc_hdl,
6718  						uint8_t vdev_id)
6719  {
6720  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6721  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
6722  						     DP_MOD_ID_CDP);
6723  	struct dp_pdev *pdev;
6724  
6725  	if (!vdev)
6726  		return NULL;
6727  
6728  	pdev = vdev->pdev;
6729  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6730  	return pdev ? (struct cdp_cfg *)pdev->wlan_cfg_ctx : NULL;
6731  }
6732  
dp_get_tx_pending(struct cdp_pdev * pdev_handle)6733  int32_t dp_get_tx_pending(struct cdp_pdev *pdev_handle)
6734  {
6735  	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
6736  
6737  	return qdf_atomic_read(&pdev->num_tx_outstanding);
6738  }
6739  
6740  /**
6741   * dp_get_peer_mac_from_peer_id() - get peer mac
6742   * @soc: CDP SoC handle
6743   * @peer_id: Peer ID
6744   * @peer_mac: MAC addr of PEER
6745   *
6746   * Return: QDF_STATUS
6747   */
dp_get_peer_mac_from_peer_id(struct cdp_soc_t * soc,uint32_t peer_id,uint8_t * peer_mac)6748  static QDF_STATUS dp_get_peer_mac_from_peer_id(struct cdp_soc_t *soc,
6749  					       uint32_t peer_id,
6750  					       uint8_t *peer_mac)
6751  {
6752  	struct dp_peer *peer;
6753  
6754  	if (soc && peer_mac) {
6755  		peer = dp_peer_get_ref_by_id((struct dp_soc *)soc,
6756  					     (uint16_t)peer_id,
6757  					     DP_MOD_ID_CDP);
6758  		if (peer) {
6759  			qdf_mem_copy(peer_mac, peer->mac_addr.raw,
6760  				     QDF_MAC_ADDR_SIZE);
6761  			dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
6762  			return QDF_STATUS_SUCCESS;
6763  		}
6764  	}
6765  
6766  	return QDF_STATUS_E_FAILURE;
6767  }
6768  
6769  #ifdef MESH_MODE_SUPPORT
6770  static
dp_vdev_set_mesh_mode(struct cdp_vdev * vdev_hdl,uint32_t val)6771  void dp_vdev_set_mesh_mode(struct cdp_vdev *vdev_hdl, uint32_t val)
6772  {
6773  	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
6774  
6775  	dp_cdp_info("%pK: val %d", vdev->pdev->soc, val);
6776  	vdev->mesh_vdev = val;
6777  	if (val)
6778  		vdev->skip_sw_tid_classification |=
6779  			DP_TX_MESH_ENABLED;
6780  	else
6781  		vdev->skip_sw_tid_classification &=
6782  			~DP_TX_MESH_ENABLED;
6783  }
6784  
6785  /**
6786   * dp_vdev_set_mesh_rx_filter() - to set the mesh rx filter
6787   * @vdev_hdl: virtual device object
6788   * @val: value to be set
6789   *
6790   * Return: void
6791   */
6792  static
dp_vdev_set_mesh_rx_filter(struct cdp_vdev * vdev_hdl,uint32_t val)6793  void dp_vdev_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val)
6794  {
6795  	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
6796  
6797  	dp_cdp_info("%pK: val %d", vdev->pdev->soc, val);
6798  	vdev->mesh_rx_filter = val;
6799  }
6800  #endif
6801  
6802  /**
6803   * dp_vdev_set_hlos_tid_override() - to set hlos tid override
6804   * @vdev: virtual device object
6805   * @val: value to be set
6806   *
6807   * Return: void
6808   */
6809  static
dp_vdev_set_hlos_tid_override(struct dp_vdev * vdev,uint32_t val)6810  void dp_vdev_set_hlos_tid_override(struct dp_vdev *vdev, uint32_t val)
6811  {
6812  	dp_cdp_info("%pK: val %d", vdev->pdev->soc, val);
6813  	if (val)
6814  		vdev->skip_sw_tid_classification |=
6815  			DP_TXRX_HLOS_TID_OVERRIDE_ENABLED;
6816  	else
6817  		vdev->skip_sw_tid_classification &=
6818  			~DP_TXRX_HLOS_TID_OVERRIDE_ENABLED;
6819  }
6820  
6821  /**
6822   * dp_vdev_get_hlos_tid_override() - to get hlos tid override flag
6823   * @vdev_hdl: virtual device object
6824   *
6825   * Return: 1 if this flag is set
6826   */
6827  static
dp_vdev_get_hlos_tid_override(struct cdp_vdev * vdev_hdl)6828  uint8_t dp_vdev_get_hlos_tid_override(struct cdp_vdev *vdev_hdl)
6829  {
6830  	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
6831  
6832  	return !!(vdev->skip_sw_tid_classification &
6833  			DP_TXRX_HLOS_TID_OVERRIDE_ENABLED);
6834  }
6835  
6836  #ifdef VDEV_PEER_PROTOCOL_COUNT
dp_enable_vdev_peer_protocol_count(struct cdp_soc_t * soc_hdl,int8_t vdev_id,bool enable)6837  static void dp_enable_vdev_peer_protocol_count(struct cdp_soc_t *soc_hdl,
6838  					       int8_t vdev_id,
6839  					       bool enable)
6840  {
6841  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6842  	struct dp_vdev *vdev;
6843  
6844  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
6845  	if (!vdev)
6846  		return;
6847  
6848  	dp_info("enable %d vdev_id %d", enable, vdev_id);
6849  	vdev->peer_protocol_count_track = enable;
6850  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6851  }
6852  
dp_enable_vdev_peer_protocol_drop_mask(struct cdp_soc_t * soc_hdl,int8_t vdev_id,int drop_mask)6853  static void dp_enable_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc_hdl,
6854  						   int8_t vdev_id,
6855  						   int drop_mask)
6856  {
6857  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6858  	struct dp_vdev *vdev;
6859  
6860  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
6861  	if (!vdev)
6862  		return;
6863  
6864  	dp_info("drop_mask %d vdev_id %d", drop_mask, vdev_id);
6865  	vdev->peer_protocol_count_dropmask = drop_mask;
6866  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6867  }
6868  
dp_is_vdev_peer_protocol_count_enabled(struct cdp_soc_t * soc_hdl,int8_t vdev_id)6869  static int dp_is_vdev_peer_protocol_count_enabled(struct cdp_soc_t *soc_hdl,
6870  						  int8_t vdev_id)
6871  {
6872  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6873  	struct dp_vdev *vdev;
6874  	int peer_protocol_count_track;
6875  
6876  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
6877  	if (!vdev)
6878  		return 0;
6879  
6880  	dp_info("enable %d vdev_id %d", vdev->peer_protocol_count_track,
6881  		vdev_id);
6882  	peer_protocol_count_track =
6883  		vdev->peer_protocol_count_track;
6884  
6885  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6886  	return peer_protocol_count_track;
6887  }
6888  
dp_get_vdev_peer_protocol_drop_mask(struct cdp_soc_t * soc_hdl,int8_t vdev_id)6889  static int dp_get_vdev_peer_protocol_drop_mask(struct cdp_soc_t *soc_hdl,
6890  					       int8_t vdev_id)
6891  {
6892  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
6893  	struct dp_vdev *vdev;
6894  	int peer_protocol_count_dropmask;
6895  
6896  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
6897  	if (!vdev)
6898  		return 0;
6899  
6900  	dp_info("drop_mask %d vdev_id %d", vdev->peer_protocol_count_dropmask,
6901  		vdev_id);
6902  	peer_protocol_count_dropmask =
6903  		vdev->peer_protocol_count_dropmask;
6904  
6905  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
6906  	return peer_protocol_count_dropmask;
6907  }
6908  
6909  #endif
6910  
dp_check_pdev_exists(struct dp_soc * soc,struct dp_pdev * data)6911  bool dp_check_pdev_exists(struct dp_soc *soc, struct dp_pdev *data)
6912  {
6913  	uint8_t pdev_count;
6914  
6915  	for (pdev_count = 0; pdev_count < MAX_PDEV_CNT; pdev_count++) {
6916  		if (soc->pdev_list[pdev_count] &&
6917  		    soc->pdev_list[pdev_count] == data)
6918  			return true;
6919  	}
6920  	return false;
6921  }
6922  
dp_aggregate_vdev_stats(struct dp_vdev * vdev,struct cdp_vdev_stats * vdev_stats,enum dp_pkt_xmit_type xmit_type)6923  void dp_aggregate_vdev_stats(struct dp_vdev *vdev,
6924  			     struct cdp_vdev_stats *vdev_stats,
6925  			     enum dp_pkt_xmit_type xmit_type)
6926  {
6927  	if (!vdev || !vdev->pdev)
6928  		return;
6929  
6930  	dp_update_vdev_ingress_stats(vdev);
6931  
6932  	dp_copy_vdev_stats_to_tgt_buf(vdev_stats,
6933  					    &vdev->stats, xmit_type);
6934  	dp_vdev_iterate_peer(vdev, dp_update_vdev_stats, vdev_stats,
6935  			     DP_MOD_ID_GENERIC_STATS);
6936  
6937  	dp_update_vdev_rate_stats(vdev_stats, &vdev->stats);
6938  
6939  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
6940  	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc,
6941  			     vdev_stats, vdev->vdev_id,
6942  			     UPDATE_VDEV_STATS, vdev->pdev->pdev_id);
6943  #endif
6944  }
6945  
dp_aggregate_pdev_stats(struct dp_pdev * pdev)6946  void dp_aggregate_pdev_stats(struct dp_pdev *pdev)
6947  {
6948  	struct dp_vdev *vdev = NULL;
6949  	struct dp_soc *soc;
6950  	struct cdp_vdev_stats *vdev_stats =
6951  			qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats));
6952  
6953  	if (!vdev_stats) {
6954  		dp_cdp_err("%pK: DP alloc failure - unable to get alloc vdev stats",
6955  			   pdev->soc);
6956  		return;
6957  	}
6958  
6959  	soc = pdev->soc;
6960  
6961  	qdf_mem_zero(&pdev->stats.tx, sizeof(pdev->stats.tx));
6962  	qdf_mem_zero(&pdev->stats.rx, sizeof(pdev->stats.rx));
6963  	qdf_mem_zero(&pdev->stats.tx_i, sizeof(pdev->stats.tx_i));
6964  	qdf_mem_zero(&pdev->stats.rx_i, sizeof(pdev->stats.rx_i));
6965  
6966  	if (dp_monitor_is_enable_mcopy_mode(pdev))
6967  		dp_monitor_invalid_peer_update_pdev_stats(soc, pdev);
6968  
6969  	qdf_spin_lock_bh(&pdev->vdev_list_lock);
6970  	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
6971  
6972  		dp_aggregate_vdev_stats(vdev, vdev_stats, DP_XMIT_TOTAL);
6973  		dp_update_pdev_stats(pdev, vdev_stats);
6974  		dp_update_pdev_ingress_stats(pdev, vdev);
6975  	}
6976  	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
6977  	qdf_mem_free(vdev_stats);
6978  
6979  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
6980  	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, &pdev->stats,
6981  			     pdev->pdev_id, UPDATE_PDEV_STATS, pdev->pdev_id);
6982  #endif
6983  }
6984  
6985  /**
6986   * dp_vdev_getstats() - get vdev packet level stats
6987   * @vdev_handle: Datapath VDEV handle
6988   * @stats: cdp network device stats structure
6989   *
6990   * Return: QDF_STATUS
6991   */
dp_vdev_getstats(struct cdp_vdev * vdev_handle,struct cdp_dev_stats * stats)6992  static QDF_STATUS dp_vdev_getstats(struct cdp_vdev *vdev_handle,
6993  				   struct cdp_dev_stats *stats)
6994  {
6995  	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
6996  	struct dp_pdev *pdev;
6997  	struct dp_soc *soc;
6998  	struct cdp_vdev_stats *vdev_stats;
6999  
7000  	if (!vdev)
7001  		return QDF_STATUS_E_FAILURE;
7002  
7003  	pdev = vdev->pdev;
7004  	if (!pdev)
7005  		return QDF_STATUS_E_FAILURE;
7006  
7007  	soc = pdev->soc;
7008  
7009  	vdev_stats = qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats));
7010  
7011  	if (!vdev_stats) {
7012  		dp_err("%pK: DP alloc failure - unable to get alloc vdev stats",
7013  		       soc);
7014  		return QDF_STATUS_E_FAILURE;
7015  	}
7016  
7017  	dp_aggregate_vdev_stats(vdev, vdev_stats, DP_XMIT_LINK);
7018  
7019  	stats->tx_packets = vdev_stats->tx.comp_pkt.num;
7020  	stats->tx_bytes = vdev_stats->tx.comp_pkt.bytes;
7021  
7022  	stats->tx_errors = vdev_stats->tx.tx_failed;
7023  	stats->tx_dropped = vdev_stats->tx_i.dropped.dropped_pkt.num +
7024  			    vdev_stats->tx_i.sg.dropped_host.num +
7025  			    vdev_stats->tx_i.mcast_en.dropped_map_error +
7026  			    vdev_stats->tx_i.mcast_en.dropped_self_mac +
7027  			    vdev_stats->tx_i.mcast_en.dropped_send_fail +
7028  			    vdev_stats->tx.nawds_mcast_drop;
7029  
7030  	if (!wlan_cfg_get_vdev_stats_hw_offload_config(soc->wlan_cfg_ctx)) {
7031  		stats->rx_packets = vdev_stats->rx.to_stack.num;
7032  		stats->rx_bytes = vdev_stats->rx.to_stack.bytes;
7033  	} else {
7034  		stats->rx_packets = vdev_stats->rx_i.reo_rcvd_pkt.num +
7035  				    vdev_stats->rx_i.null_q_desc_pkt.num +
7036  				    vdev_stats->rx_i.routed_eapol_pkt.num;
7037  		stats->rx_bytes = vdev_stats->rx_i.reo_rcvd_pkt.bytes +
7038  				  vdev_stats->rx_i.null_q_desc_pkt.bytes +
7039  				  vdev_stats->rx_i.routed_eapol_pkt.bytes;
7040  	}
7041  
7042  	stats->rx_errors = vdev_stats->rx.err.mic_err +
7043  			   vdev_stats->rx.err.decrypt_err +
7044  			   vdev_stats->rx.err.fcserr +
7045  			   vdev_stats->rx.err.pn_err +
7046  			   vdev_stats->rx.err.oor_err +
7047  			   vdev_stats->rx.err.jump_2k_err +
7048  			   vdev_stats->rx.err.rxdma_wifi_parse_err;
7049  
7050  	stats->rx_dropped = vdev_stats->rx.mec_drop.num +
7051  			    vdev_stats->rx.multipass_rx_pkt_drop +
7052  			    vdev_stats->rx.peer_unauth_rx_pkt_drop +
7053  			    vdev_stats->rx.policy_check_drop +
7054  			    vdev_stats->rx.nawds_mcast_drop +
7055  			    vdev_stats->rx.mcast_3addr_drop +
7056  			    vdev_stats->rx.ppeds_drop.num;
7057  
7058  	qdf_mem_free(vdev_stats);
7059  
7060  	return QDF_STATUS_SUCCESS;
7061  }
7062  
7063  /**
7064   * dp_pdev_getstats() - get pdev packet level stats
7065   * @pdev_handle: Datapath PDEV handle
7066   * @stats: cdp network device stats structure
7067   *
7068   * Return: QDF_STATUS
7069   */
dp_pdev_getstats(struct cdp_pdev * pdev_handle,struct cdp_dev_stats * stats)7070  static void dp_pdev_getstats(struct cdp_pdev *pdev_handle,
7071  			     struct cdp_dev_stats *stats)
7072  {
7073  	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
7074  
7075  	dp_aggregate_pdev_stats(pdev);
7076  
7077  	stats->tx_packets = pdev->stats.tx.comp_pkt.num;
7078  	stats->tx_bytes = pdev->stats.tx.comp_pkt.bytes;
7079  
7080  	stats->tx_errors = pdev->stats.tx.tx_failed;
7081  	stats->tx_dropped = pdev->stats.tx_i.dropped.dropped_pkt.num +
7082  			    pdev->stats.tx_i.sg.dropped_host.num +
7083  			    pdev->stats.tx_i.mcast_en.dropped_map_error +
7084  			    pdev->stats.tx_i.mcast_en.dropped_self_mac +
7085  			    pdev->stats.tx_i.mcast_en.dropped_send_fail +
7086  			    pdev->stats.tx.nawds_mcast_drop +
7087  			    pdev->stats.tso_stats.dropped_host.num;
7088  
7089  	if (!wlan_cfg_get_vdev_stats_hw_offload_config(pdev->soc->wlan_cfg_ctx)) {
7090  		stats->rx_packets = pdev->stats.rx.to_stack.num;
7091  		stats->rx_bytes = pdev->stats.rx.to_stack.bytes;
7092  	} else {
7093  		stats->rx_packets = pdev->stats.rx_i.reo_rcvd_pkt.num +
7094  				    pdev->stats.rx_i.null_q_desc_pkt.num +
7095  				    pdev->stats.rx_i.routed_eapol_pkt.num;
7096  		stats->rx_bytes = pdev->stats.rx_i.reo_rcvd_pkt.bytes +
7097  				  pdev->stats.rx_i.null_q_desc_pkt.bytes +
7098  				  pdev->stats.rx_i.routed_eapol_pkt.bytes;
7099  	}
7100  
7101  	stats->rx_errors = pdev->stats.err.ip_csum_err +
7102  		pdev->stats.err.tcp_udp_csum_err +
7103  		pdev->stats.rx.err.mic_err +
7104  		pdev->stats.rx.err.decrypt_err +
7105  		pdev->stats.rx.err.fcserr +
7106  		pdev->stats.rx.err.pn_err +
7107  		pdev->stats.rx.err.oor_err +
7108  		pdev->stats.rx.err.jump_2k_err +
7109  		pdev->stats.rx.err.rxdma_wifi_parse_err;
7110  	stats->rx_dropped = pdev->stats.dropped.msdu_not_done +
7111  		pdev->stats.dropped.mec +
7112  		pdev->stats.dropped.mesh_filter +
7113  		pdev->stats.dropped.wifi_parse +
7114  		pdev->stats.dropped.mon_rx_drop +
7115  		pdev->stats.dropped.mon_radiotap_update_err +
7116  		pdev->stats.rx.mec_drop.num +
7117  		pdev->stats.rx.ppeds_drop.num +
7118  		pdev->stats.rx.multipass_rx_pkt_drop +
7119  		pdev->stats.rx.peer_unauth_rx_pkt_drop +
7120  		pdev->stats.rx.policy_check_drop +
7121  		pdev->stats.rx.nawds_mcast_drop +
7122  		pdev->stats.rx.mcast_3addr_drop;
7123  }
7124  
7125  /**
7126   * dp_get_device_stats() - get interface level packet stats
7127   * @soc_hdl: soc handle
7128   * @id: vdev_id or pdev_id based on type
7129   * @stats: cdp network device stats structure
7130   * @type: device type pdev/vdev
7131   *
7132   * Return: QDF_STATUS
7133   */
dp_get_device_stats(struct cdp_soc_t * soc_hdl,uint8_t id,struct cdp_dev_stats * stats,uint8_t type)7134  static QDF_STATUS dp_get_device_stats(struct cdp_soc_t *soc_hdl, uint8_t id,
7135  				      struct cdp_dev_stats *stats,
7136  				      uint8_t type)
7137  {
7138  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
7139  	QDF_STATUS status = QDF_STATUS_E_FAILURE;
7140  	struct dp_vdev *vdev;
7141  
7142  	switch (type) {
7143  	case UPDATE_VDEV_STATS:
7144  		vdev = dp_vdev_get_ref_by_id(soc, id, DP_MOD_ID_CDP);
7145  
7146  		if (vdev) {
7147  			status = dp_vdev_getstats((struct cdp_vdev *)vdev,
7148  						  stats);
7149  			dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
7150  		}
7151  		return status;
7152  	case UPDATE_PDEV_STATS:
7153  		{
7154  			struct dp_pdev *pdev =
7155  				dp_get_pdev_from_soc_pdev_id_wifi3(
7156  						(struct dp_soc *)soc,
7157  						 id);
7158  			if (pdev) {
7159  				dp_pdev_getstats((struct cdp_pdev *)pdev,
7160  						 stats);
7161  				return QDF_STATUS_SUCCESS;
7162  			}
7163  		}
7164  		break;
7165  	default:
7166  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
7167  			"apstats cannot be updated for this input "
7168  			"type %d", type);
7169  		break;
7170  	}
7171  
7172  	return QDF_STATUS_E_FAILURE;
7173  }
7174  
7175  const
dp_srng_get_str_from_hal_ring_type(enum hal_ring_type ring_type)7176  char *dp_srng_get_str_from_hal_ring_type(enum hal_ring_type ring_type)
7177  {
7178  	switch (ring_type) {
7179  	case REO_DST:
7180  		return "Reo_dst";
7181  	case REO_EXCEPTION:
7182  		return "Reo_exception";
7183  	case REO_CMD:
7184  		return "Reo_cmd";
7185  	case REO_REINJECT:
7186  		return "Reo_reinject";
7187  	case REO_STATUS:
7188  		return "Reo_status";
7189  	case WBM2SW_RELEASE:
7190  		return "wbm2sw_release";
7191  	case TCL_DATA:
7192  		return "tcl_data";
7193  	case TCL_CMD_CREDIT:
7194  		return "tcl_cmd_credit";
7195  	case TCL_STATUS:
7196  		return "tcl_status";
7197  	case SW2WBM_RELEASE:
7198  		return "sw2wbm_release";
7199  	case RXDMA_BUF:
7200  		return "Rxdma_buf";
7201  	case RXDMA_DST:
7202  		return "Rxdma_dst";
7203  	case RXDMA_MONITOR_BUF:
7204  		return "Rxdma_monitor_buf";
7205  	case RXDMA_MONITOR_DESC:
7206  		return "Rxdma_monitor_desc";
7207  	case RXDMA_MONITOR_STATUS:
7208  		return "Rxdma_monitor_status";
7209  	case RXDMA_MONITOR_DST:
7210  		return "Rxdma_monitor_destination";
7211  	case WBM_IDLE_LINK:
7212  		return "WBM_hw_idle_link";
7213  	case PPE2TCL:
7214  		return "PPE2TCL";
7215  	case REO2PPE:
7216  		return "REO2PPE";
7217  	case TX_MONITOR_DST:
7218  		return "tx_monitor_destination";
7219  	case TX_MONITOR_BUF:
7220  		return "tx_monitor_buf";
7221  	default:
7222  		dp_err("Invalid ring type: %u", ring_type);
7223  		break;
7224  	}
7225  	return "Invalid";
7226  }
7227  
dp_print_napi_stats(struct dp_soc * soc)7228  void dp_print_napi_stats(struct dp_soc *soc)
7229  {
7230  	hif_print_napi_stats(soc->hif_handle);
7231  }
7232  
7233  /**
7234   * dp_txrx_host_peer_stats_clr() - Reinitialize the txrx peer stats
7235   * @soc: Datapath soc
7236   * @peer: Datatpath peer
7237   * @arg: argument to iter function
7238   *
7239   * Return: QDF_STATUS
7240   */
7241  static inline void
dp_txrx_host_peer_stats_clr(struct dp_soc * soc,struct dp_peer * peer,void * arg)7242  dp_txrx_host_peer_stats_clr(struct dp_soc *soc,
7243  			    struct dp_peer *peer,
7244  			    void *arg)
7245  {
7246  	struct dp_txrx_peer *txrx_peer = NULL;
7247  	struct dp_peer *tgt_peer = NULL;
7248  	struct cdp_interface_peer_stats peer_stats_intf = {0};
7249  
7250  	peer_stats_intf.rx_avg_snr = CDP_INVALID_SNR;
7251  
7252  	DP_STATS_CLR(peer);
7253  	/* Clear monitor peer stats */
7254  	dp_monitor_peer_reset_stats(soc, peer);
7255  
7256  	/* Clear MLD peer stats only when link peer is primary */
7257  	if (dp_peer_is_primary_link_peer(peer)) {
7258  		tgt_peer = dp_get_tgt_peer_from_peer(peer);
7259  		if (tgt_peer) {
7260  			DP_STATS_CLR(tgt_peer);
7261  			txrx_peer = tgt_peer->txrx_peer;
7262  			dp_txrx_peer_stats_clr(txrx_peer);
7263  		}
7264  	}
7265  
7266  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
7267  	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, peer->vdev->pdev->soc,
7268  			     &peer_stats_intf,  peer->peer_id,
7269  			     UPDATE_PEER_STATS, peer->vdev->pdev->pdev_id);
7270  #endif
7271  }
7272  
7273  #ifdef WLAN_DP_SRNG_USAGE_WM_TRACKING
dp_srng_clear_ring_usage_wm_stats(struct dp_soc * soc)7274  static inline void dp_srng_clear_ring_usage_wm_stats(struct dp_soc *soc)
7275  {
7276  	int ring;
7277  
7278  	for (ring = 0; ring < soc->num_reo_dest_rings; ring++)
7279  		hal_srng_clear_ring_usage_wm_locked(soc->hal_soc,
7280  					    soc->reo_dest_ring[ring].hal_srng);
7281  
7282  	for (ring = 0; ring < soc->num_tcl_data_rings; ring++) {
7283  		if (wlan_cfg_get_wbm_ring_num_for_index(
7284  					soc->wlan_cfg_ctx, ring) ==
7285  		    INVALID_WBM_RING_NUM)
7286  			continue;
7287  
7288  		hal_srng_clear_ring_usage_wm_locked(soc->hal_soc,
7289  					soc->tx_comp_ring[ring].hal_srng);
7290  	}
7291  }
7292  #else
dp_srng_clear_ring_usage_wm_stats(struct dp_soc * soc)7293  static inline void dp_srng_clear_ring_usage_wm_stats(struct dp_soc *soc)
7294  {
7295  }
7296  #endif
7297  
7298  #ifdef WLAN_SUPPORT_PPEDS
dp_clear_tx_ppeds_stats(struct dp_soc * soc)7299  static void dp_clear_tx_ppeds_stats(struct dp_soc *soc)
7300  {
7301  	if (soc->arch_ops.dp_ppeds_clear_stats)
7302  		soc->arch_ops.dp_ppeds_clear_stats(soc);
7303  }
7304  
dp_ppeds_clear_ring_util_stats(struct dp_soc * soc)7305  static void dp_ppeds_clear_ring_util_stats(struct dp_soc *soc)
7306  {
7307  	if (soc->arch_ops.dp_txrx_ppeds_clear_rings_stats)
7308  		soc->arch_ops.dp_txrx_ppeds_clear_rings_stats(soc);
7309  }
7310  #else
dp_clear_tx_ppeds_stats(struct dp_soc * soc)7311  static void dp_clear_tx_ppeds_stats(struct dp_soc *soc)
7312  {
7313  }
7314  
dp_ppeds_clear_ring_util_stats(struct dp_soc * soc)7315  static void dp_ppeds_clear_ring_util_stats(struct dp_soc *soc)
7316  {
7317  }
7318  #endif
7319  
7320  /**
7321   * dp_txrx_host_stats_clr() - Reinitialize the txrx stats
7322   * @vdev: DP_VDEV handle
7323   * @soc: DP_SOC handle
7324   *
7325   * Return: QDF_STATUS
7326   */
7327  static inline QDF_STATUS
dp_txrx_host_stats_clr(struct dp_vdev * vdev,struct dp_soc * soc)7328  dp_txrx_host_stats_clr(struct dp_vdev *vdev, struct dp_soc *soc)
7329  {
7330  	struct dp_vdev *var_vdev = NULL;
7331  
7332  	if (!vdev || !vdev->pdev)
7333  		return QDF_STATUS_E_FAILURE;
7334  
7335  	/*
7336  	 * if NSS offload is enabled, then send message
7337  	 * to NSS FW to clear the stats. Once NSS FW clears the statistics
7338  	 * then clear host statistics.
7339  	 */
7340  	if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) {
7341  		if (soc->cdp_soc.ol_ops->nss_stats_clr)
7342  			soc->cdp_soc.ol_ops->nss_stats_clr(soc->ctrl_psoc,
7343  							   vdev->vdev_id);
7344  	}
7345  
7346  	dp_vdev_stats_hw_offload_target_clear(soc, vdev->pdev->pdev_id,
7347  					      (1 << vdev->vdev_id));
7348  
7349  	DP_STATS_CLR(vdev->pdev);
7350  	DP_STATS_CLR(vdev->pdev->soc);
7351  
7352  	dp_clear_tx_ppeds_stats(soc);
7353  	dp_ppeds_clear_ring_util_stats(soc);
7354  
7355  	hif_clear_napi_stats(vdev->pdev->soc->hif_handle);
7356  
7357  	TAILQ_FOREACH(var_vdev, &vdev->pdev->vdev_list, vdev_list_elem) {
7358  		DP_STATS_CLR(var_vdev);
7359  		dp_vdev_iterate_peer(var_vdev, dp_txrx_host_peer_stats_clr,
7360  				     NULL, DP_MOD_ID_GENERIC_STATS);
7361  	}
7362  
7363  	dp_srng_clear_ring_usage_wm_stats(soc);
7364  
7365  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
7366  	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc,
7367  			     &vdev->stats,  vdev->vdev_id,
7368  			     UPDATE_VDEV_STATS, vdev->pdev->pdev_id);
7369  #endif
7370  	return QDF_STATUS_SUCCESS;
7371  }
7372  
7373  /**
7374   * dp_get_peer_calibr_stats()- Get peer calibrated stats
7375   * @peer: Datapath peer
7376   * @peer_stats: buffer for peer stats
7377   *
7378   * Return: none
7379   */
7380  static inline
dp_get_peer_calibr_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7381  void dp_get_peer_calibr_stats(struct dp_peer *peer,
7382  			      struct cdp_peer_stats *peer_stats)
7383  {
7384  	struct dp_peer *tgt_peer;
7385  
7386  	tgt_peer = dp_get_tgt_peer_from_peer(peer);
7387  	if (!tgt_peer)
7388  		return;
7389  
7390  	peer_stats->tx.last_per = tgt_peer->stats.tx.last_per;
7391  	peer_stats->tx.tx_bytes_success_last =
7392  				tgt_peer->stats.tx.tx_bytes_success_last;
7393  	peer_stats->tx.tx_data_success_last =
7394  					tgt_peer->stats.tx.tx_data_success_last;
7395  	peer_stats->tx.tx_byte_rate = tgt_peer->stats.tx.tx_byte_rate;
7396  	peer_stats->tx.tx_data_rate = tgt_peer->stats.tx.tx_data_rate;
7397  	peer_stats->tx.tx_data_ucast_last =
7398  					tgt_peer->stats.tx.tx_data_ucast_last;
7399  	peer_stats->tx.tx_data_ucast_rate =
7400  					tgt_peer->stats.tx.tx_data_ucast_rate;
7401  	peer_stats->tx.inactive_time = tgt_peer->stats.tx.inactive_time;
7402  	peer_stats->rx.rx_bytes_success_last =
7403  				tgt_peer->stats.rx.rx_bytes_success_last;
7404  	peer_stats->rx.rx_data_success_last =
7405  				tgt_peer->stats.rx.rx_data_success_last;
7406  	peer_stats->rx.rx_byte_rate = tgt_peer->stats.rx.rx_byte_rate;
7407  	peer_stats->rx.rx_data_rate = tgt_peer->stats.rx.rx_data_rate;
7408  }
7409  
7410  /**
7411   * dp_get_peer_basic_stats()- Get peer basic stats
7412   * @peer: Datapath peer
7413   * @peer_stats: buffer for peer stats
7414   *
7415   * Return: none
7416   */
7417  static inline
dp_get_peer_basic_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7418  void dp_get_peer_basic_stats(struct dp_peer *peer,
7419  			     struct cdp_peer_stats *peer_stats)
7420  {
7421  	struct dp_txrx_peer *txrx_peer;
7422  
7423  	txrx_peer = dp_get_txrx_peer(peer);
7424  	if (!txrx_peer)
7425  		return;
7426  
7427  	peer_stats->tx.comp_pkt.num += txrx_peer->comp_pkt.num;
7428  	peer_stats->tx.comp_pkt.bytes += txrx_peer->comp_pkt.bytes;
7429  	peer_stats->tx.tx_failed += txrx_peer->tx_failed;
7430  	peer_stats->rx.to_stack.num += txrx_peer->to_stack.num;
7431  	peer_stats->rx.to_stack.bytes += txrx_peer->to_stack.bytes;
7432  }
7433  
7434  #ifdef QCA_ENHANCED_STATS_SUPPORT
7435  /**
7436   * dp_get_peer_per_pkt_stats()- Get peer per pkt stats
7437   * @peer: Datapath peer
7438   * @peer_stats: buffer for peer stats
7439   *
7440   * Return: none
7441   */
7442  static inline
dp_get_peer_per_pkt_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7443  void dp_get_peer_per_pkt_stats(struct dp_peer *peer,
7444  			       struct cdp_peer_stats *peer_stats)
7445  {
7446  	struct dp_txrx_peer *txrx_peer;
7447  	struct dp_peer_per_pkt_stats *per_pkt_stats;
7448  	uint8_t inx = 0, link_id = 0;
7449  	struct dp_pdev *pdev;
7450  	struct dp_soc *soc;
7451  	uint8_t stats_arr_size;
7452  
7453  	txrx_peer = dp_get_txrx_peer(peer);
7454  	pdev = peer->vdev->pdev;
7455  
7456  	if (!txrx_peer)
7457  		return;
7458  
7459  	if (!IS_MLO_DP_LINK_PEER(peer)) {
7460  		stats_arr_size = txrx_peer->stats_arr_size;
7461  		for (inx = 0; inx < stats_arr_size; inx++) {
7462  			per_pkt_stats = &txrx_peer->stats[inx].per_pkt_stats;
7463  			DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats);
7464  		}
7465  	} else {
7466  		soc = pdev->soc;
7467  		link_id = dp_get_peer_hw_link_id(soc, pdev);
7468  		per_pkt_stats =
7469  			&txrx_peer->stats[link_id].per_pkt_stats;
7470  		DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats);
7471  	}
7472  }
7473  
7474  #ifdef WLAN_FEATURE_11BE_MLO
7475  /**
7476   * dp_get_peer_extd_stats()- Get peer extd stats
7477   * @peer: Datapath peer
7478   * @peer_stats: buffer for peer stats
7479   *
7480   * Return: none
7481   */
7482  static inline
dp_get_peer_extd_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7483  void dp_get_peer_extd_stats(struct dp_peer *peer,
7484  			    struct cdp_peer_stats *peer_stats)
7485  {
7486  	struct dp_soc *soc = peer->vdev->pdev->soc;
7487  
7488  	if (IS_MLO_DP_MLD_PEER(peer)) {
7489  		uint8_t i;
7490  		struct dp_peer *link_peer;
7491  		struct dp_soc *link_peer_soc;
7492  		struct dp_mld_link_peers link_peers_info;
7493  
7494  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
7495  						    &link_peers_info,
7496  						    DP_MOD_ID_CDP);
7497  		for (i = 0; i < link_peers_info.num_links; i++) {
7498  			link_peer = link_peers_info.link_peers[i];
7499  			link_peer_soc = link_peer->vdev->pdev->soc;
7500  			dp_monitor_peer_get_stats(link_peer_soc, link_peer,
7501  						  peer_stats,
7502  						  UPDATE_PEER_STATS);
7503  		}
7504  		dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
7505  	} else {
7506  		dp_monitor_peer_get_stats(soc, peer, peer_stats,
7507  					  UPDATE_PEER_STATS);
7508  	}
7509  }
7510  #else
7511  static inline
dp_get_peer_extd_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7512  void dp_get_peer_extd_stats(struct dp_peer *peer,
7513  			    struct cdp_peer_stats *peer_stats)
7514  {
7515  	struct dp_soc *soc = peer->vdev->pdev->soc;
7516  
7517  	dp_monitor_peer_get_stats(soc, peer, peer_stats, UPDATE_PEER_STATS);
7518  }
7519  #endif
7520  #else
7521  #if defined WLAN_FEATURE_11BE_MLO && defined DP_MLO_LINK_STATS_SUPPORT
7522  static inline
dp_get_peer_per_pkt_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7523  void dp_get_peer_per_pkt_stats(struct dp_peer *peer,
7524  			       struct cdp_peer_stats *peer_stats)
7525  {
7526  	uint8_t i, index;
7527  	struct dp_mld_link_peers link_peers_info;
7528  	struct dp_txrx_peer *txrx_peer;
7529  	struct dp_peer_per_pkt_stats *per_pkt_stats;
7530  	struct dp_soc *soc = peer->vdev->pdev->soc;
7531  
7532  	txrx_peer = dp_get_txrx_peer(peer);
7533  	if (!txrx_peer)
7534  		return;
7535  
7536  	if (IS_MLO_DP_MLD_PEER(peer)) {
7537  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
7538  						    &link_peers_info,
7539  						    DP_MOD_ID_GENERIC_STATS);
7540  		for (i = 0; i < link_peers_info.num_links; i++) {
7541  			if (i > txrx_peer->stats_arr_size)
7542  				break;
7543  			per_pkt_stats = &txrx_peer->stats[i].per_pkt_stats;
7544  			DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats);
7545  		}
7546  		dp_release_link_peers_ref(&link_peers_info,
7547  					  DP_MOD_ID_GENERIC_STATS);
7548  	} else {
7549  		index = dp_get_peer_link_id(peer);
7550  		per_pkt_stats = &txrx_peer->stats[index].per_pkt_stats;
7551  		DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats);
7552  		qdf_mem_copy(&peer_stats->mac_addr,
7553  			     &peer->mac_addr.raw[0],
7554  			     QDF_MAC_ADDR_SIZE);
7555  	}
7556  }
7557  
7558  static inline
dp_get_peer_extd_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7559  void dp_get_peer_extd_stats(struct dp_peer *peer,
7560  			    struct cdp_peer_stats *peer_stats)
7561  {
7562  	uint8_t i, index;
7563  	struct dp_mld_link_peers link_peers_info;
7564  	struct dp_txrx_peer *txrx_peer;
7565  	struct dp_peer_extd_stats *extd_stats;
7566  	struct dp_soc *soc = peer->vdev->pdev->soc;
7567  
7568  	txrx_peer = dp_get_txrx_peer(peer);
7569  	if (qdf_unlikely(!txrx_peer)) {
7570  		dp_err_rl("txrx_peer NULL for peer MAC: " QDF_MAC_ADDR_FMT,
7571  			  QDF_MAC_ADDR_REF(peer->mac_addr.raw));
7572  		return;
7573  	}
7574  
7575  	if (IS_MLO_DP_MLD_PEER(peer)) {
7576  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
7577  						    &link_peers_info,
7578  						    DP_MOD_ID_GENERIC_STATS);
7579  		for (i = 0; i < link_peers_info.num_links; i++) {
7580  			if (i > txrx_peer->stats_arr_size)
7581  				break;
7582  			extd_stats = &txrx_peer->stats[i].extd_stats;
7583  			/* Return aggregated stats for MLD peer */
7584  			DP_UPDATE_EXTD_STATS(peer_stats, extd_stats);
7585  		}
7586  		dp_release_link_peers_ref(&link_peers_info,
7587  					  DP_MOD_ID_GENERIC_STATS);
7588  	} else {
7589  		index = dp_get_peer_link_id(peer);
7590  		extd_stats = &txrx_peer->stats[index].extd_stats;
7591  		DP_UPDATE_EXTD_STATS(peer_stats, extd_stats);
7592  		qdf_mem_copy(&peer_stats->mac_addr,
7593  			     &peer->mac_addr.raw[0],
7594  			     QDF_MAC_ADDR_SIZE);
7595  	}
7596  }
7597  #else
7598  static inline
dp_get_peer_per_pkt_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7599  void dp_get_peer_per_pkt_stats(struct dp_peer *peer,
7600  			       struct cdp_peer_stats *peer_stats)
7601  {
7602  	struct dp_txrx_peer *txrx_peer;
7603  	struct dp_peer_per_pkt_stats *per_pkt_stats;
7604  
7605  	txrx_peer = dp_get_txrx_peer(peer);
7606  	if (!txrx_peer)
7607  		return;
7608  
7609  	per_pkt_stats = &txrx_peer->stats[0].per_pkt_stats;
7610  	DP_UPDATE_PER_PKT_STATS(peer_stats, per_pkt_stats);
7611  }
7612  
7613  static inline
dp_get_peer_extd_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7614  void dp_get_peer_extd_stats(struct dp_peer *peer,
7615  			    struct cdp_peer_stats *peer_stats)
7616  {
7617  	struct dp_txrx_peer *txrx_peer;
7618  	struct dp_peer_extd_stats *extd_stats;
7619  
7620  	txrx_peer = dp_get_txrx_peer(peer);
7621  	if (qdf_unlikely(!txrx_peer)) {
7622  		dp_err_rl("txrx_peer NULL");
7623  		return;
7624  	}
7625  
7626  	extd_stats = &txrx_peer->stats[0].extd_stats;
7627  	DP_UPDATE_EXTD_STATS(peer_stats, extd_stats);
7628  }
7629  #endif
7630  #endif
7631  
7632  /**
7633   * dp_get_peer_tx_per()- Get peer packet error ratio
7634   * @peer_stats: buffer for peer stats
7635   *
7636   * Return: none
7637   */
7638  static inline
dp_get_peer_tx_per(struct cdp_peer_stats * peer_stats)7639  void dp_get_peer_tx_per(struct cdp_peer_stats *peer_stats)
7640  {
7641  	if (peer_stats->tx.tx_success.num + peer_stats->tx.retries > 0)
7642  		peer_stats->tx.per = qdf_do_div((peer_stats->tx.retries * 100),
7643  				  (peer_stats->tx.tx_success.num +
7644  				   peer_stats->tx.retries));
7645  	else
7646  		peer_stats->tx.per = 0;
7647  }
7648  
dp_get_peer_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats)7649  void dp_get_peer_stats(struct dp_peer *peer, struct cdp_peer_stats *peer_stats)
7650  {
7651  	dp_get_peer_calibr_stats(peer, peer_stats);
7652  
7653  	dp_get_peer_basic_stats(peer, peer_stats);
7654  
7655  	dp_get_peer_per_pkt_stats(peer, peer_stats);
7656  
7657  	dp_get_peer_extd_stats(peer, peer_stats);
7658  
7659  	dp_get_peer_tx_per(peer_stats);
7660  }
7661  
7662  /**
7663   * dp_get_host_peer_stats()- function to print peer stats
7664   * @soc: dp_soc handle
7665   * @mac_addr: mac address of the peer
7666   *
7667   * Return: QDF_STATUS
7668   */
7669  static QDF_STATUS
dp_get_host_peer_stats(struct cdp_soc_t * soc,uint8_t * mac_addr)7670  dp_get_host_peer_stats(struct cdp_soc_t *soc, uint8_t *mac_addr)
7671  {
7672  	struct dp_peer *peer = NULL;
7673  	struct cdp_peer_stats *peer_stats = NULL;
7674  	struct cdp_peer_info peer_info = { 0 };
7675  
7676  	if (!mac_addr) {
7677  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
7678  			  "%s: NULL peer mac addr\n", __func__);
7679  		return QDF_STATUS_E_FAILURE;
7680  	}
7681  
7682  	DP_PEER_INFO_PARAMS_INIT(&peer_info, DP_VDEV_ALL, mac_addr, false,
7683  				 CDP_WILD_PEER_TYPE);
7684  
7685  	peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info,
7686  					 DP_MOD_ID_CDP);
7687  	if (!peer) {
7688  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
7689  			  "%s: Invalid peer\n", __func__);
7690  		return QDF_STATUS_E_FAILURE;
7691  	}
7692  
7693  	peer_stats = qdf_mem_malloc(sizeof(struct cdp_peer_stats));
7694  	if (!peer_stats) {
7695  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
7696  			  "%s: Memory allocation failed for cdp_peer_stats\n",
7697  			  __func__);
7698  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
7699  		return QDF_STATUS_E_NOMEM;
7700  	}
7701  
7702  	qdf_mem_zero(peer_stats, sizeof(struct cdp_peer_stats));
7703  
7704  	dp_get_peer_stats(peer, peer_stats);
7705  	dp_print_peer_stats(peer, peer_stats);
7706  
7707  	dp_peer_rxtid_stats(dp_get_tgt_peer_from_peer(peer),
7708  			    dp_rx_tid_stats_cb, NULL);
7709  
7710  	qdf_mem_free(peer_stats);
7711  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
7712  
7713  	return QDF_STATUS_SUCCESS;
7714  }
7715  
7716  /**
7717   * dp_txrx_stats_help() - Helper function for Txrx_Stats
7718   *
7719   * Return: None
7720   */
dp_txrx_stats_help(void)7721  static void dp_txrx_stats_help(void)
7722  {
7723  	dp_info("Command: iwpriv wlan0 txrx_stats <stats_option> <mac_id>");
7724  	dp_info("stats_option:");
7725  	dp_info("  1 -- HTT Tx Statistics");
7726  	dp_info("  2 -- HTT Rx Statistics");
7727  	dp_info("  3 -- HTT Tx HW Queue Statistics");
7728  	dp_info("  4 -- HTT Tx HW Sched Statistics");
7729  	dp_info("  5 -- HTT Error Statistics");
7730  	dp_info("  6 -- HTT TQM Statistics");
7731  	dp_info("  7 -- HTT TQM CMDQ Statistics");
7732  	dp_info("  8 -- HTT TX_DE_CMN Statistics");
7733  	dp_info("  9 -- HTT Tx Rate Statistics");
7734  	dp_info(" 10 -- HTT Rx Rate Statistics");
7735  	dp_info(" 11 -- HTT Peer Statistics");
7736  	dp_info(" 12 -- HTT Tx SelfGen Statistics");
7737  	dp_info(" 13 -- HTT Tx MU HWQ Statistics");
7738  	dp_info(" 14 -- HTT RING_IF_INFO Statistics");
7739  	dp_info(" 15 -- HTT SRNG Statistics");
7740  	dp_info(" 16 -- HTT SFM Info Statistics");
7741  	dp_info(" 17 -- HTT PDEV_TX_MU_MIMO_SCHED INFO Statistics");
7742  	dp_info(" 18 -- HTT Peer List Details");
7743  	dp_info(" 20 -- Clear Host Statistics");
7744  	dp_info(" 21 -- Host Rx Rate Statistics");
7745  	dp_info(" 22 -- Host Tx Rate Statistics");
7746  	dp_info(" 23 -- Host Tx Statistics");
7747  	dp_info(" 24 -- Host Rx Statistics");
7748  	dp_info(" 25 -- Host AST Statistics");
7749  	dp_info(" 26 -- Host SRNG PTR Statistics");
7750  	dp_info(" 27 -- Host Mon Statistics");
7751  	dp_info(" 28 -- Host REO Queue Statistics");
7752  	dp_info(" 29 -- Host Soc cfg param Statistics");
7753  	dp_info(" 30 -- Host pdev cfg param Statistics");
7754  	dp_info(" 31 -- Host NAPI stats");
7755  	dp_info(" 32 -- Host Interrupt stats");
7756  	dp_info(" 33 -- Host FISA stats");
7757  	dp_info(" 34 -- Host Register Work stats");
7758  	dp_info(" 35 -- HW REO Queue stats");
7759  	dp_info(" 36 -- Host WBM IDLE link desc ring HP/TP");
7760  	dp_info(" 37 -- Host SRNG usage watermark stats");
7761  }
7762  
7763  #ifdef DP_UMAC_HW_RESET_SUPPORT
7764  /**
7765   * dp_umac_rst_skel_enable_update() - Update skel dbg flag for umac reset
7766   * @soc: dp soc handle
7767   * @en: ebable/disable
7768   *
7769   * Return: void
7770   */
dp_umac_rst_skel_enable_update(struct dp_soc * soc,bool en)7771  static void dp_umac_rst_skel_enable_update(struct dp_soc *soc, bool en)
7772  {
7773  	soc->umac_reset_ctx.skel_enable = en;
7774  	dp_cdp_debug("UMAC HW reset debug skeleton code enabled :%u",
7775  		     soc->umac_reset_ctx.skel_enable);
7776  }
7777  
7778  /**
7779   * dp_umac_rst_skel_enable_get() - Get skel dbg flag for umac reset
7780   * @soc: dp soc handle
7781   *
7782   * Return: enable/disable flag
7783   */
dp_umac_rst_skel_enable_get(struct dp_soc * soc)7784  static bool dp_umac_rst_skel_enable_get(struct dp_soc *soc)
7785  {
7786  	return soc->umac_reset_ctx.skel_enable;
7787  }
7788  #else
dp_umac_rst_skel_enable_update(struct dp_soc * soc,bool en)7789  static void dp_umac_rst_skel_enable_update(struct dp_soc *soc, bool en)
7790  {
7791  }
7792  
dp_umac_rst_skel_enable_get(struct dp_soc * soc)7793  static bool dp_umac_rst_skel_enable_get(struct dp_soc *soc)
7794  {
7795  	return false;
7796  }
7797  #endif
7798  
7799  #ifndef WLAN_SOFTUMAC_SUPPORT
dp_print_reg_write_stats(struct dp_soc * soc)7800  static void dp_print_reg_write_stats(struct dp_soc *soc)
7801  {
7802  	hal_dump_reg_write_stats(soc->hal_soc);
7803  	hal_dump_reg_write_srng_stats(soc->hal_soc);
7804  }
7805  #else
dp_print_reg_write_stats(struct dp_soc * soc)7806  static void dp_print_reg_write_stats(struct dp_soc *soc)
7807  {
7808  	hif_print_reg_write_stats(soc->hif_handle);
7809  }
7810  #endif
7811  
7812  /**
7813   * dp_print_host_stats()- Function to print the stats aggregated at host
7814   * @vdev: DP_VDEV handle
7815   * @req: host stats type
7816   * @soc: dp soc handler
7817   *
7818   * Return: 0 on success, print error message in case of failure
7819   */
7820  static int
dp_print_host_stats(struct dp_vdev * vdev,struct cdp_txrx_stats_req * req,struct dp_soc * soc)7821  dp_print_host_stats(struct dp_vdev *vdev,
7822  		    struct cdp_txrx_stats_req *req,
7823  		    struct dp_soc *soc)
7824  {
7825  	struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev;
7826  	enum cdp_host_txrx_stats type =
7827  			dp_stats_mapping_table[req->stats][STATS_HOST];
7828  
7829  	dp_aggregate_pdev_stats(pdev);
7830  
7831  	switch (type) {
7832  	case TXRX_CLEAR_STATS:
7833  		dp_txrx_host_stats_clr(vdev, soc);
7834  		break;
7835  	case TXRX_RX_RATE_STATS:
7836  		dp_print_rx_rates(vdev);
7837  		break;
7838  	case TXRX_TX_RATE_STATS:
7839  		dp_print_tx_rates(vdev);
7840  		break;
7841  	case TXRX_TX_HOST_STATS:
7842  		dp_print_pdev_tx_stats(pdev);
7843  		dp_print_soc_tx_stats(pdev->soc);
7844  		dp_print_global_desc_count();
7845  		dp_print_vdev_mlo_mcast_tx_stats(vdev);
7846  		break;
7847  	case TXRX_RX_HOST_STATS:
7848  		dp_print_pdev_rx_stats(pdev);
7849  		dp_print_soc_rx_stats(pdev->soc);
7850  		break;
7851  	case TXRX_AST_STATS:
7852  		dp_print_ast_stats(pdev->soc);
7853  		dp_print_mec_stats(pdev->soc);
7854  		dp_print_peer_table(vdev);
7855  		if (soc->arch_ops.dp_mlo_print_ptnr_info)
7856  			soc->arch_ops.dp_mlo_print_ptnr_info(vdev);
7857  		break;
7858  	case TXRX_SRNG_PTR_STATS:
7859  		dp_print_ring_stats(pdev);
7860  		break;
7861  	case TXRX_RX_MON_STATS:
7862  		dp_monitor_print_pdev_rx_mon_stats(pdev);
7863  		break;
7864  	case TXRX_REO_QUEUE_STATS:
7865  		dp_get_host_peer_stats((struct cdp_soc_t *)pdev->soc,
7866  				       req->peer_addr);
7867  		break;
7868  	case TXRX_SOC_CFG_PARAMS:
7869  		dp_print_soc_cfg_params(pdev->soc);
7870  		break;
7871  	case TXRX_PDEV_CFG_PARAMS:
7872  		dp_print_pdev_cfg_params(pdev);
7873  		break;
7874  	case TXRX_NAPI_STATS:
7875  		dp_print_napi_stats(pdev->soc);
7876  		break;
7877  	case TXRX_SOC_INTERRUPT_STATS:
7878  		dp_print_soc_interrupt_stats(pdev->soc);
7879  		break;
7880  	case TXRX_SOC_FSE_STATS:
7881  		if (soc->cdp_soc.ol_ops->dp_print_fisa_stats)
7882  			soc->cdp_soc.ol_ops->dp_print_fisa_stats(
7883  						CDP_FISA_STATS_ID_DUMP_HW_FST);
7884  		break;
7885  	case TXRX_HAL_REG_WRITE_STATS:
7886  		dp_print_reg_write_stats(pdev->soc);
7887  		break;
7888  	case TXRX_SOC_REO_HW_DESC_DUMP:
7889  		dp_get_rx_reo_queue_info((struct cdp_soc_t *)pdev->soc,
7890  					 vdev->vdev_id);
7891  		break;
7892  	case TXRX_SOC_WBM_IDLE_HPTP_DUMP:
7893  		dp_dump_wbm_idle_hptp(pdev->soc, pdev);
7894  		break;
7895  	case TXRX_SRNG_USAGE_WM_STATS:
7896  		/* Dump usage watermark stats for all SRNGs */
7897  		dp_dump_srng_high_wm_stats(soc, DP_SRNG_WM_MASK_ALL);
7898  		break;
7899  	case TXRX_PEER_STATS:
7900  		dp_print_per_link_stats((struct cdp_soc_t *)pdev->soc,
7901  					vdev->vdev_id);
7902  		break;
7903  	default:
7904  		dp_info("Wrong Input For TxRx Host Stats");
7905  		dp_txrx_stats_help();
7906  		break;
7907  	}
7908  	return 0;
7909  }
7910  
7911  /**
7912   * dp_pdev_tid_stats_ingress_inc() - increment ingress_stack counter
7913   * @pdev: pdev handle
7914   * @val: increase in value
7915   *
7916   * Return: void
7917   */
7918  static void
dp_pdev_tid_stats_ingress_inc(struct dp_pdev * pdev,uint32_t val)7919  dp_pdev_tid_stats_ingress_inc(struct dp_pdev *pdev, uint32_t val)
7920  {
7921  	pdev->stats.tid_stats.ingress_stack += val;
7922  }
7923  
7924  /**
7925   * dp_pdev_tid_stats_osif_drop() - increment osif_drop counter
7926   * @pdev: pdev handle
7927   * @val: increase in value
7928   *
7929   * Return: void
7930   */
7931  static void
dp_pdev_tid_stats_osif_drop(struct dp_pdev * pdev,uint32_t val)7932  dp_pdev_tid_stats_osif_drop(struct dp_pdev *pdev, uint32_t val)
7933  {
7934  	pdev->stats.tid_stats.osif_drop += val;
7935  }
7936  
7937  /**
7938   * dp_get_fw_peer_stats()- function to print peer stats
7939   * @soc: soc handle
7940   * @pdev_id: id of the pdev handle
7941   * @mac_addr: mac address of the peer
7942   * @cap: Type of htt stats requested
7943   * @is_wait: if set, wait on completion from firmware response
7944   *
7945   * Currently Supporting only MAC ID based requests Only
7946   *	1: HTT_PEER_STATS_REQ_MODE_NO_QUERY
7947   *	2: HTT_PEER_STATS_REQ_MODE_QUERY_TQM
7948   *	3: HTT_PEER_STATS_REQ_MODE_FLUSH_TQM
7949   *
7950   * Return: QDF_STATUS
7951   */
7952  static QDF_STATUS
dp_get_fw_peer_stats(struct cdp_soc_t * soc,uint8_t pdev_id,uint8_t * mac_addr,uint32_t cap,uint32_t is_wait)7953  dp_get_fw_peer_stats(struct cdp_soc_t *soc, uint8_t pdev_id,
7954  		     uint8_t *mac_addr,
7955  		     uint32_t cap, uint32_t is_wait)
7956  {
7957  	int i;
7958  	uint32_t config_param0 = 0;
7959  	uint32_t config_param1 = 0;
7960  	uint32_t config_param2 = 0;
7961  	uint32_t config_param3 = 0;
7962  	struct dp_pdev *pdev =
7963  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
7964  						   pdev_id);
7965  
7966  	if (!pdev)
7967  		return QDF_STATUS_E_FAILURE;
7968  
7969  	HTT_DBG_EXT_STATS_PEER_INFO_IS_MAC_ADDR_SET(config_param0, 1);
7970  	config_param0 |= (1 << (cap + 1));
7971  
7972  	for (i = 0; i < HTT_PEER_STATS_MAX_TLV; i++) {
7973  		config_param1 |= (1 << i);
7974  	}
7975  
7976  	config_param2 |= (mac_addr[0] & 0x000000ff);
7977  	config_param2 |= ((mac_addr[1] << 8) & 0x0000ff00);
7978  	config_param2 |= ((mac_addr[2] << 16) & 0x00ff0000);
7979  	config_param2 |= ((mac_addr[3] << 24) & 0xff000000);
7980  
7981  	config_param3 |= (mac_addr[4] & 0x000000ff);
7982  	config_param3 |= ((mac_addr[5] << 8) & 0x0000ff00);
7983  
7984  	if (is_wait) {
7985  		qdf_event_reset(&pdev->fw_peer_stats_event);
7986  		dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO,
7987  					  config_param0, config_param1,
7988  					  config_param2, config_param3,
7989  					  0, DBG_STATS_COOKIE_DP_STATS, 0);
7990  		qdf_wait_single_event(&pdev->fw_peer_stats_event,
7991  				      DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC);
7992  	} else {
7993  		dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO,
7994  					  config_param0, config_param1,
7995  					  config_param2, config_param3,
7996  					  0, DBG_STATS_COOKIE_DEFAULT, 0);
7997  	}
7998  
7999  	return QDF_STATUS_SUCCESS;
8000  
8001  }
8002  
8003  /* This struct definition will be removed from here
8004   * once it get added in FW headers*/
8005  struct httstats_cmd_req {
8006      uint32_t    config_param0;
8007      uint32_t    config_param1;
8008      uint32_t    config_param2;
8009      uint32_t    config_param3;
8010      int cookie;
8011      u_int8_t    stats_id;
8012  };
8013  
8014  /**
8015   * dp_get_htt_stats: function to process the httstas request
8016   * @soc: DP soc handle
8017   * @pdev_id: id of pdev handle
8018   * @data: pointer to request data
8019   * @data_len: length for request data
8020   *
8021   * Return: QDF_STATUS
8022   */
8023  static QDF_STATUS
dp_get_htt_stats(struct cdp_soc_t * soc,uint8_t pdev_id,void * data,uint32_t data_len)8024  dp_get_htt_stats(struct cdp_soc_t *soc, uint8_t pdev_id, void *data,
8025  		 uint32_t data_len)
8026  {
8027  	struct httstats_cmd_req *req = (struct httstats_cmd_req *)data;
8028  	struct dp_pdev *pdev =
8029  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
8030  						   pdev_id);
8031  
8032  	if (!pdev)
8033  		return QDF_STATUS_E_FAILURE;
8034  
8035  	QDF_ASSERT(data_len == sizeof(struct httstats_cmd_req));
8036  	dp_h2t_ext_stats_msg_send(pdev, req->stats_id,
8037  				req->config_param0, req->config_param1,
8038  				req->config_param2, req->config_param3,
8039  				req->cookie, DBG_STATS_COOKIE_DEFAULT, 0);
8040  
8041  	return QDF_STATUS_SUCCESS;
8042  }
8043  
8044  /**
8045   * dp_set_pdev_tidmap_prty_wifi3() - update tidmap priority in pdev
8046   * @pdev: DP_PDEV handle
8047   * @prio: tidmap priority value passed by the user
8048   *
8049   * Return: QDF_STATUS_SUCCESS on success
8050   */
dp_set_pdev_tidmap_prty_wifi3(struct dp_pdev * pdev,uint8_t prio)8051  static QDF_STATUS dp_set_pdev_tidmap_prty_wifi3(struct dp_pdev *pdev,
8052  						uint8_t prio)
8053  {
8054  	struct dp_soc *soc = pdev->soc;
8055  
8056  	soc->tidmap_prty = prio;
8057  
8058  	hal_tx_set_tidmap_prty(soc->hal_soc, prio);
8059  	return QDF_STATUS_SUCCESS;
8060  }
8061  
8062  /**
8063   * dp_get_peer_param: function to get parameters in peer
8064   * @cdp_soc: DP soc handle
8065   * @vdev_id: id of vdev handle
8066   * @peer_mac: peer mac address
8067   * @param: parameter type to be set
8068   * @val: address of buffer
8069   *
8070   * Return: val
8071   */
dp_get_peer_param(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_param_type param,cdp_config_param_type * val)8072  static QDF_STATUS dp_get_peer_param(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
8073  				    uint8_t *peer_mac,
8074  				    enum cdp_peer_param_type param,
8075  				    cdp_config_param_type *val)
8076  {
8077  	return QDF_STATUS_SUCCESS;
8078  }
8079  
8080  #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT)
8081  static inline void
dp_check_map_link_id_band(struct dp_peer * peer)8082  dp_check_map_link_id_band(struct dp_peer *peer)
8083  {
8084  	if (peer->link_id_valid)
8085  		dp_map_link_id_band(peer);
8086  }
8087  
8088  /**
8089   * dp_map_local_link_id_band() - map local link id band
8090   * @peer: dp peer handle
8091   *
8092   * Return: None
8093   */
8094  static inline
dp_map_local_link_id_band(struct dp_peer * peer)8095  void dp_map_local_link_id_band(struct dp_peer *peer)
8096  {
8097  	struct dp_txrx_peer *txrx_peer = NULL;
8098  	enum dp_bands band;
8099  
8100  	txrx_peer = dp_get_txrx_peer(peer);
8101  	if (txrx_peer && peer->local_link_id) {
8102  		band = dp_freq_to_band(peer->freq);
8103  		txrx_peer->ll_band[peer->local_link_id] = band;
8104  	} else {
8105  		dp_info("txrx_peer NULL or local link id not set: %u "
8106  			QDF_MAC_ADDR_FMT, peer->local_link_id,
8107  			QDF_MAC_ADDR_REF(peer->mac_addr.raw));
8108  	}
8109  }
8110  #else
8111  static inline void
dp_check_map_link_id_band(struct dp_peer * peer)8112  dp_check_map_link_id_band(struct dp_peer *peer)
8113  {
8114  }
8115  
8116  static inline
dp_map_local_link_id_band(struct dp_peer * peer)8117  void dp_map_local_link_id_band(struct dp_peer *peer)
8118  {
8119  }
8120  #endif
8121  
8122  /**
8123   * dp_set_peer_freq() - Set peer frequency
8124   * @cdp_soc: DP soc handle
8125   * @vdev_id: id of vdev handle
8126   * @peer_mac: peer mac address
8127   * @param: parameter type to be set
8128   * @val: value of parameter to be set
8129   *
8130   * Return: QDF_STATUS_SUCCESS for success. error code for failure.
8131   */
8132  static inline QDF_STATUS
dp_set_peer_freq(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_param_type param,cdp_config_param_type val)8133  dp_set_peer_freq(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
8134  		 uint8_t *peer_mac, enum cdp_peer_param_type param,
8135  		 cdp_config_param_type val)
8136  {
8137  	struct dp_peer *peer = NULL;
8138  	struct cdp_peer_info peer_info = { 0 };
8139  
8140  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac,
8141  				 false, CDP_LINK_PEER_TYPE);
8142  
8143  	peer = dp_peer_hash_find_wrapper((struct dp_soc *)cdp_soc,
8144  					 &peer_info, DP_MOD_ID_CDP);
8145  	if (!peer) {
8146  		dp_err("peer NULL,MAC " QDF_MAC_ADDR_FMT ", vdev_id %u",
8147  		       QDF_MAC_ADDR_REF(peer_mac), vdev_id);
8148  
8149  		return QDF_STATUS_E_FAILURE;
8150  	}
8151  
8152  	peer->freq = val.cdp_peer_param_freq;
8153  	dp_check_map_link_id_band(peer);
8154  	dp_map_local_link_id_band(peer);
8155  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8156  
8157  	dp_info("Peer " QDF_MAC_ADDR_FMT " vdev_id %u, frequency %u",
8158  		QDF_MAC_ADDR_REF(peer_mac), vdev_id,
8159  		peer->freq);
8160  
8161  	return QDF_STATUS_SUCCESS;
8162  }
8163  
8164  /**
8165   * dp_set_peer_param: function to set parameters in peer
8166   * @cdp_soc: DP soc handle
8167   * @vdev_id: id of vdev handle
8168   * @peer_mac: peer mac address
8169   * @param: parameter type to be set
8170   * @val: value of parameter to be set
8171   *
8172   * Return: 0 for success. nonzero for failure.
8173   */
dp_set_peer_param(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_param_type param,cdp_config_param_type val)8174  static QDF_STATUS dp_set_peer_param(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
8175  				    uint8_t *peer_mac,
8176  				    enum cdp_peer_param_type param,
8177  				    cdp_config_param_type val)
8178  {
8179  	QDF_STATUS status = QDF_STATUS_SUCCESS;
8180  	struct dp_peer *peer =
8181  			dp_peer_get_tgt_peer_hash_find((struct dp_soc *)cdp_soc,
8182  						       peer_mac, 0, vdev_id,
8183  						       DP_MOD_ID_CDP);
8184  	struct dp_txrx_peer *txrx_peer;
8185  
8186  	if (!peer)
8187  		return QDF_STATUS_E_FAILURE;
8188  
8189  	txrx_peer = peer->txrx_peer;
8190  	if (!txrx_peer) {
8191  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8192  		return QDF_STATUS_E_FAILURE;
8193  	}
8194  
8195  	switch (param) {
8196  	case CDP_CONFIG_NAWDS:
8197  		txrx_peer->nawds_enabled = val.cdp_peer_param_nawds;
8198  		break;
8199  	case CDP_CONFIG_ISOLATION:
8200  		dp_info("Peer " QDF_MAC_ADDR_FMT " vdev_id %d, isolation %d",
8201  			QDF_MAC_ADDR_REF(peer_mac), vdev_id,
8202  			val.cdp_peer_param_isolation);
8203  		dp_set_peer_isolation(txrx_peer, val.cdp_peer_param_isolation);
8204  		break;
8205  	case CDP_CONFIG_IN_TWT:
8206  		txrx_peer->in_twt = !!(val.cdp_peer_param_in_twt);
8207  		break;
8208  	case CDP_CONFIG_PEER_FREQ:
8209  		status =  dp_set_peer_freq(cdp_soc, vdev_id,
8210  					   peer_mac, param, val);
8211  		break;
8212  	default:
8213  		break;
8214  	}
8215  
8216  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8217  
8218  	return status;
8219  }
8220  
8221  #ifdef WLAN_FEATURE_11BE_MLO
8222  /**
8223   * dp_set_mld_peer_param: function to set parameters in MLD peer
8224   * @cdp_soc: DP soc handle
8225   * @vdev_id: id of vdev handle
8226   * @peer_mac: peer mac address
8227   * @param: parameter type to be set
8228   * @val: value of parameter to be set
8229   *
8230   * Return: 0 for success. nonzero for failure.
8231   */
dp_set_mld_peer_param(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_param_type param,cdp_config_param_type val)8232  static QDF_STATUS dp_set_mld_peer_param(struct cdp_soc_t *cdp_soc,
8233  					uint8_t vdev_id,
8234  					uint8_t *peer_mac,
8235  					enum cdp_peer_param_type param,
8236  					cdp_config_param_type val)
8237  {
8238  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
8239  	struct dp_peer *peer;
8240  	struct dp_txrx_peer *txrx_peer;
8241  	QDF_STATUS status = QDF_STATUS_SUCCESS;
8242  
8243  	peer = dp_mld_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
8244  					  DP_MOD_ID_CDP);
8245  	if (!peer)
8246  		return QDF_STATUS_E_FAILURE;
8247  
8248  	txrx_peer = peer->txrx_peer;
8249  	if (!txrx_peer) {
8250  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8251  		return QDF_STATUS_E_FAILURE;
8252  	}
8253  
8254  	switch (param) {
8255  	case CDP_CONFIG_MLD_PEER_VDEV:
8256  		status = dp_mld_peer_change_vdev(soc, peer, val.new_vdev_id);
8257  		break;
8258  	default:
8259  		break;
8260  	}
8261  
8262  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8263  
8264  	return status;
8265  }
8266  
8267  /**
8268   * dp_set_peer_param_wrapper: wrapper function to set parameters in
8269   *			      legacy/link/MLD peer
8270   * @cdp_soc: DP soc handle
8271   * @vdev_id: id of vdev handle
8272   * @peer_mac: peer mac address
8273   * @param: parameter type to be set
8274   * @val: value of parameter to be set
8275   *
8276   * Return: 0 for success. nonzero for failure.
8277   */
8278  static QDF_STATUS
dp_set_peer_param_wrapper(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_param_type param,cdp_config_param_type val)8279  dp_set_peer_param_wrapper(struct cdp_soc_t *cdp_soc,  uint8_t vdev_id,
8280  			  uint8_t *peer_mac, enum cdp_peer_param_type param,
8281  			  cdp_config_param_type val)
8282  {
8283  	QDF_STATUS status;
8284  
8285  	switch (param) {
8286  	case CDP_CONFIG_MLD_PEER_VDEV:
8287  		status = dp_set_mld_peer_param(cdp_soc, vdev_id, peer_mac,
8288  					       param, val);
8289  		break;
8290  	default:
8291  		status = dp_set_peer_param(cdp_soc, vdev_id, peer_mac,
8292  					   param, val);
8293  		break;
8294  	}
8295  
8296  	return status;
8297  }
8298  #endif
8299  
8300  /**
8301   * dp_get_pdev_param() - function to get parameters from pdev
8302   * @cdp_soc: DP soc handle
8303   * @pdev_id: id of pdev handle
8304   * @param: parameter type to be get
8305   * @val: buffer for value
8306   *
8307   * Return: status
8308   */
dp_get_pdev_param(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,enum cdp_pdev_param_type param,cdp_config_param_type * val)8309  static QDF_STATUS dp_get_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
8310  				    enum cdp_pdev_param_type param,
8311  				    cdp_config_param_type *val)
8312  {
8313  	struct cdp_pdev *pdev = (struct cdp_pdev *)
8314  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc,
8315  						   pdev_id);
8316  	if (!pdev)
8317  		return QDF_STATUS_E_FAILURE;
8318  
8319  	switch (param) {
8320  	case CDP_CONFIG_VOW:
8321  		val->cdp_pdev_param_cfg_vow =
8322  				((struct dp_pdev *)pdev)->vow_stats;
8323  		break;
8324  	case CDP_TX_PENDING:
8325  		val->cdp_pdev_param_tx_pending = dp_get_tx_pending(pdev);
8326  		break;
8327  	case CDP_FILTER_MCAST_DATA:
8328  		val->cdp_pdev_param_fltr_mcast =
8329  				dp_monitor_pdev_get_filter_mcast_data(pdev);
8330  		break;
8331  	case CDP_FILTER_NO_DATA:
8332  		val->cdp_pdev_param_fltr_none =
8333  				dp_monitor_pdev_get_filter_non_data(pdev);
8334  		break;
8335  	case CDP_FILTER_UCAST_DATA:
8336  		val->cdp_pdev_param_fltr_ucast =
8337  				dp_monitor_pdev_get_filter_ucast_data(pdev);
8338  		break;
8339  	case CDP_MONITOR_CHANNEL:
8340  		val->cdp_pdev_param_monitor_chan =
8341  			dp_monitor_get_chan_num((struct dp_pdev *)pdev);
8342  		break;
8343  	case CDP_MONITOR_FREQUENCY:
8344  		val->cdp_pdev_param_mon_freq =
8345  			dp_monitor_get_chan_freq((struct dp_pdev *)pdev);
8346  		break;
8347  	case CDP_CONFIG_RXDMA_BUF_RING_SIZE:
8348  		val->cdp_rxdma_buf_ring_size =
8349  			wlan_cfg_get_rx_dma_buf_ring_size(((struct dp_pdev *)pdev)->wlan_cfg_ctx);
8350  		break;
8351  	case CDP_CONFIG_DELAY_STATS:
8352  		val->cdp_pdev_param_cfg_delay_stats =
8353  				((struct dp_pdev *)pdev)->delay_stats_flag;
8354  		break;
8355  	default:
8356  		return QDF_STATUS_E_FAILURE;
8357  	}
8358  
8359  	return QDF_STATUS_SUCCESS;
8360  }
8361  
8362  /**
8363   * dp_set_pdev_param() - function to set parameters in pdev
8364   * @cdp_soc: DP soc handle
8365   * @pdev_id: id of pdev handle
8366   * @param: parameter type to be set
8367   * @val: value of parameter to be set
8368   *
8369   * Return: 0 for success. nonzero for failure.
8370   */
dp_set_pdev_param(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,enum cdp_pdev_param_type param,cdp_config_param_type val)8371  static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
8372  				    enum cdp_pdev_param_type param,
8373  				    cdp_config_param_type val)
8374  {
8375  	int target_type;
8376  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
8377  	struct dp_pdev *pdev =
8378  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc,
8379  						   pdev_id);
8380  	enum reg_wifi_band chan_band;
8381  
8382  	if (!pdev)
8383  		return QDF_STATUS_E_FAILURE;
8384  
8385  	target_type = hal_get_target_type(soc->hal_soc);
8386  	switch (target_type) {
8387  	case TARGET_TYPE_QCA6750:
8388  	case TARGET_TYPE_WCN6450:
8389  		pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC0_LMAC_ID;
8390  		pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID;
8391  		pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID;
8392  		break;
8393  	case TARGET_TYPE_KIWI:
8394  	case TARGET_TYPE_MANGO:
8395  	case TARGET_TYPE_PEACH:
8396  		pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC0_LMAC_ID;
8397  		pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID;
8398  		pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID;
8399  		break;
8400  	default:
8401  		pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MAC1_LMAC_ID;
8402  		pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MAC0_LMAC_ID;
8403  		pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MAC0_LMAC_ID;
8404  		break;
8405  	}
8406  
8407  	switch (param) {
8408  	case CDP_CONFIG_TX_CAPTURE:
8409  		return dp_monitor_config_debug_sniffer(pdev,
8410  						val.cdp_pdev_param_tx_capture);
8411  	case CDP_CONFIG_DEBUG_SNIFFER:
8412  		return dp_monitor_config_debug_sniffer(pdev,
8413  						val.cdp_pdev_param_dbg_snf);
8414  	case CDP_CONFIG_BPR_ENABLE:
8415  		return dp_monitor_set_bpr_enable(pdev,
8416  						 val.cdp_pdev_param_bpr_enable);
8417  	case CDP_CONFIG_PRIMARY_RADIO:
8418  		pdev->is_primary = val.cdp_pdev_param_primary_radio;
8419  		break;
8420  	case CDP_CONFIG_CAPTURE_LATENCY:
8421  		pdev->latency_capture_enable = val.cdp_pdev_param_cptr_latcy;
8422  		break;
8423  	case CDP_INGRESS_STATS:
8424  		dp_pdev_tid_stats_ingress_inc(pdev,
8425  					      val.cdp_pdev_param_ingrs_stats);
8426  		break;
8427  	case CDP_OSIF_DROP:
8428  		dp_pdev_tid_stats_osif_drop(pdev,
8429  					    val.cdp_pdev_param_osif_drop);
8430  		break;
8431  	case CDP_CONFIG_ENH_RX_CAPTURE:
8432  		return dp_monitor_config_enh_rx_capture(pdev,
8433  						val.cdp_pdev_param_en_rx_cap);
8434  	case CDP_CONFIG_ENH_TX_CAPTURE:
8435  		return dp_monitor_config_enh_tx_capture(pdev,
8436  						val.cdp_pdev_param_en_tx_cap);
8437  	case CDP_CONFIG_HMMC_TID_OVERRIDE:
8438  		pdev->hmmc_tid_override_en = val.cdp_pdev_param_hmmc_tid_ovrd;
8439  		break;
8440  	case CDP_CONFIG_HMMC_TID_VALUE:
8441  		pdev->hmmc_tid = val.cdp_pdev_param_hmmc_tid;
8442  		break;
8443  	case CDP_CHAN_NOISE_FLOOR:
8444  		pdev->chan_noise_floor = val.cdp_pdev_param_chn_noise_flr;
8445  		break;
8446  	case CDP_TIDMAP_PRTY:
8447  		dp_set_pdev_tidmap_prty_wifi3(pdev,
8448  					      val.cdp_pdev_param_tidmap_prty);
8449  		break;
8450  	case CDP_FILTER_NEIGH_PEERS:
8451  		dp_monitor_set_filter_neigh_peers(pdev,
8452  					val.cdp_pdev_param_fltr_neigh_peers);
8453  		break;
8454  	case CDP_MONITOR_CHANNEL:
8455  		dp_monitor_set_chan_num(pdev, val.cdp_pdev_param_monitor_chan);
8456  		break;
8457  	case CDP_MONITOR_FREQUENCY:
8458  		chan_band = wlan_reg_freq_to_band(val.cdp_pdev_param_mon_freq);
8459  		dp_monitor_set_chan_freq(pdev, val.cdp_pdev_param_mon_freq);
8460  		dp_monitor_set_chan_band(pdev, chan_band);
8461  		break;
8462  	case CDP_CONFIG_BSS_COLOR:
8463  		dp_monitor_set_bsscolor(pdev, val.cdp_pdev_param_bss_color);
8464  		break;
8465  	case CDP_SET_ATF_STATS_ENABLE:
8466  		dp_monitor_set_atf_stats_enable(pdev,
8467  					val.cdp_pdev_param_atf_stats_enable);
8468  		break;
8469  	case CDP_CONFIG_SPECIAL_VAP:
8470  		dp_monitor_pdev_config_scan_spcl_vap(pdev,
8471  					val.cdp_pdev_param_config_special_vap);
8472  		dp_monitor_vdev_set_monitor_mode_buf_rings(pdev);
8473  		break;
8474  	case CDP_RESET_SCAN_SPCL_VAP_STATS_ENABLE:
8475  		dp_monitor_pdev_reset_scan_spcl_vap_stats_enable(pdev,
8476  				val.cdp_pdev_param_reset_scan_spcl_vap_stats_enable);
8477  		break;
8478  	case CDP_CONFIG_ENHANCED_STATS_ENABLE:
8479  		pdev->enhanced_stats_en = val.cdp_pdev_param_enhanced_stats_enable;
8480  		break;
8481  	case CDP_ISOLATION:
8482  		pdev->isolation = val.cdp_pdev_param_isolation;
8483  		break;
8484  	case CDP_CONFIG_UNDECODED_METADATA_CAPTURE_ENABLE:
8485  		return dp_monitor_config_undecoded_metadata_capture(pdev,
8486  				val.cdp_pdev_param_undecoded_metadata_enable);
8487  		break;
8488  	case CDP_CONFIG_RXDMA_BUF_RING_SIZE:
8489  		wlan_cfg_set_rx_dma_buf_ring_size(pdev->wlan_cfg_ctx,
8490  						  val.cdp_rxdma_buf_ring_size);
8491  		break;
8492  	case CDP_CONFIG_VOW:
8493  		pdev->vow_stats = val.cdp_pdev_param_cfg_vow;
8494  		break;
8495  	default:
8496  		return QDF_STATUS_E_INVAL;
8497  	}
8498  	return QDF_STATUS_SUCCESS;
8499  }
8500  
8501  #ifdef QCA_UNDECODED_METADATA_SUPPORT
8502  static
dp_set_pdev_phyrx_error_mask(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,uint32_t mask,uint32_t mask_cont)8503  QDF_STATUS dp_set_pdev_phyrx_error_mask(struct cdp_soc_t *cdp_soc,
8504  					uint8_t pdev_id, uint32_t mask,
8505  					uint32_t mask_cont)
8506  {
8507  	struct dp_pdev *pdev =
8508  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc,
8509  						   pdev_id);
8510  
8511  	if (!pdev)
8512  		return QDF_STATUS_E_FAILURE;
8513  
8514  	return dp_monitor_config_undecoded_metadata_phyrx_error_mask(pdev,
8515  				mask, mask_cont);
8516  }
8517  
8518  static
dp_get_pdev_phyrx_error_mask(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,uint32_t * mask,uint32_t * mask_cont)8519  QDF_STATUS dp_get_pdev_phyrx_error_mask(struct cdp_soc_t *cdp_soc,
8520  					uint8_t pdev_id, uint32_t *mask,
8521  					uint32_t *mask_cont)
8522  {
8523  	struct dp_pdev *pdev =
8524  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc,
8525  						   pdev_id);
8526  
8527  	if (!pdev)
8528  		return QDF_STATUS_E_FAILURE;
8529  
8530  	return dp_monitor_get_undecoded_metadata_phyrx_error_mask(pdev,
8531  				mask, mask_cont);
8532  }
8533  #endif
8534  
8535  #ifdef QCA_PEER_EXT_STATS
dp_rx_update_peer_delay_stats(struct dp_soc * soc,qdf_nbuf_t nbuf)8536  static void dp_rx_update_peer_delay_stats(struct dp_soc *soc,
8537  					  qdf_nbuf_t nbuf)
8538  {
8539  	struct dp_peer *peer = NULL;
8540  	uint16_t peer_id, ring_id;
8541  	uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
8542  	struct dp_peer_delay_stats *delay_stats = NULL;
8543  
8544  	peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf);
8545  	if (peer_id > soc->max_peer_id)
8546  		return;
8547  
8548  	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_CDP);
8549  	if (qdf_unlikely(!peer))
8550  		return;
8551  
8552  	if (qdf_unlikely(!peer->txrx_peer)) {
8553  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8554  		return;
8555  	}
8556  
8557  	if (qdf_likely(peer->txrx_peer->delay_stats)) {
8558  		delay_stats = peer->txrx_peer->delay_stats;
8559  		ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
8560  		dp_rx_compute_tid_delay(&delay_stats->delay_tid_stats[tid][ring_id],
8561  					nbuf);
8562  	}
8563  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
8564  }
8565  #else
dp_rx_update_peer_delay_stats(struct dp_soc * soc,qdf_nbuf_t nbuf)8566  static inline void dp_rx_update_peer_delay_stats(struct dp_soc *soc,
8567  						 qdf_nbuf_t nbuf)
8568  {
8569  }
8570  #endif
8571  
8572  /**
8573   * dp_calculate_delay_stats() - function to get rx delay stats
8574   * @cdp_soc: DP soc handle
8575   * @vdev_id: id of DP vdev handle
8576   * @nbuf: skb
8577   *
8578   * Return: QDF_STATUS
8579   */
8580  static QDF_STATUS
dp_calculate_delay_stats(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,qdf_nbuf_t nbuf)8581  dp_calculate_delay_stats(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8582  			 qdf_nbuf_t nbuf)
8583  {
8584  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
8585  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
8586  						     DP_MOD_ID_CDP);
8587  
8588  	if (!vdev)
8589  		return QDF_STATUS_SUCCESS;
8590  
8591  	if (vdev->pdev->delay_stats_flag)
8592  		dp_rx_compute_delay(vdev, nbuf);
8593  	else
8594  		dp_rx_update_peer_delay_stats(soc, nbuf);
8595  
8596  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
8597  	return QDF_STATUS_SUCCESS;
8598  }
8599  
8600  /**
8601   * dp_get_vdev_param() - function to get parameters from vdev
8602   * @cdp_soc: DP soc handle
8603   * @vdev_id: id of DP vdev handle
8604   * @param: parameter type to get value
8605   * @val: buffer address
8606   *
8607   * Return: status
8608   */
dp_get_vdev_param(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_vdev_param_type param,cdp_config_param_type * val)8609  static QDF_STATUS dp_get_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8610  				    enum cdp_vdev_param_type param,
8611  				    cdp_config_param_type *val)
8612  {
8613  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
8614  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
8615  						     DP_MOD_ID_CDP);
8616  
8617  	if (!vdev)
8618  		return QDF_STATUS_E_FAILURE;
8619  
8620  	switch (param) {
8621  	case CDP_ENABLE_WDS:
8622  		val->cdp_vdev_param_wds = vdev->wds_enabled;
8623  		break;
8624  	case CDP_ENABLE_MEC:
8625  		val->cdp_vdev_param_mec = vdev->mec_enabled;
8626  		break;
8627  	case CDP_ENABLE_DA_WAR:
8628  		val->cdp_vdev_param_da_war = vdev->pdev->soc->da_war_enabled;
8629  		break;
8630  	case CDP_ENABLE_IGMP_MCAST_EN:
8631  		val->cdp_vdev_param_igmp_mcast_en = vdev->igmp_mcast_enhanc_en;
8632  		break;
8633  	case CDP_ENABLE_MCAST_EN:
8634  		val->cdp_vdev_param_mcast_en = vdev->mcast_enhancement_en;
8635  		break;
8636  	case CDP_ENABLE_HLOS_TID_OVERRIDE:
8637  		val->cdp_vdev_param_hlos_tid_override =
8638  			    dp_vdev_get_hlos_tid_override((struct cdp_vdev *)vdev);
8639  		break;
8640  	case CDP_ENABLE_PEER_AUTHORIZE:
8641  		val->cdp_vdev_param_peer_authorize =
8642  			    vdev->peer_authorize;
8643  		break;
8644  	case CDP_TX_ENCAP_TYPE:
8645  		val->cdp_vdev_param_tx_encap = vdev->tx_encap_type;
8646  		break;
8647  	case CDP_ENABLE_CIPHER:
8648  		val->cdp_vdev_param_cipher_en = vdev->sec_type;
8649  		break;
8650  #ifdef WLAN_SUPPORT_MESH_LATENCY
8651  	case CDP_ENABLE_PEER_TID_LATENCY:
8652  		val->cdp_vdev_param_peer_tid_latency_enable =
8653  			vdev->peer_tid_latency_enabled;
8654  		break;
8655  	case CDP_SET_VAP_MESH_TID:
8656  		val->cdp_vdev_param_mesh_tid =
8657  				vdev->mesh_tid_latency_config.latency_tid;
8658  		break;
8659  #endif
8660  	case CDP_DROP_3ADDR_MCAST:
8661  		val->cdp_drop_3addr_mcast = vdev->drop_3addr_mcast;
8662  		break;
8663  	case CDP_SET_MCAST_VDEV:
8664  		soc->arch_ops.txrx_get_vdev_mcast_param(soc, vdev, val);
8665  		break;
8666  #ifdef QCA_SUPPORT_WDS_EXTENDED
8667  	case CDP_DROP_TX_MCAST:
8668  		val->cdp_drop_tx_mcast = vdev->drop_tx_mcast;
8669  		break;
8670  #endif
8671  
8672  #ifdef MESH_MODE_SUPPORT
8673  	case CDP_MESH_RX_FILTER:
8674  		val->cdp_vdev_param_mesh_rx_filter = vdev->mesh_rx_filter;
8675  		break;
8676  	case CDP_MESH_MODE:
8677  		val->cdp_vdev_param_mesh_mode = vdev->mesh_vdev;
8678  		break;
8679  #endif
8680  	case CDP_ENABLE_NAWDS:
8681  		val->cdp_vdev_param_nawds = vdev->nawds_enabled;
8682  		break;
8683  
8684  	case CDP_ENABLE_WRAP:
8685  		val->cdp_vdev_param_wrap = vdev->wrap_vdev;
8686  		break;
8687  
8688  #ifdef DP_TRAFFIC_END_INDICATION
8689  	case CDP_ENABLE_TRAFFIC_END_INDICATION:
8690  		val->cdp_vdev_param_traffic_end_ind = vdev->traffic_end_ind_en;
8691  		break;
8692  #endif
8693  
8694  	default:
8695  		dp_cdp_err("%pK: param value %d is wrong",
8696  			   soc, param);
8697  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
8698  		return QDF_STATUS_E_FAILURE;
8699  	}
8700  
8701  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
8702  	return QDF_STATUS_SUCCESS;
8703  }
8704  
8705  /**
8706   * dp_set_vdev_param() - function to set parameters in vdev
8707   * @cdp_soc: DP soc handle
8708   * @vdev_id: id of DP vdev handle
8709   * @param: parameter type to get value
8710   * @val: value
8711   *
8712   * Return: QDF_STATUS
8713   */
8714  static QDF_STATUS
dp_set_vdev_param(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_vdev_param_type param,cdp_config_param_type val)8715  dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8716  		  enum cdp_vdev_param_type param, cdp_config_param_type val)
8717  {
8718  	struct dp_soc *dsoc = (struct dp_soc *)cdp_soc;
8719  	struct dp_vdev *vdev =
8720  		dp_vdev_get_ref_by_id(dsoc, vdev_id, DP_MOD_ID_CDP);
8721  	uint32_t var = 0;
8722  
8723  	if (!vdev)
8724  		return QDF_STATUS_E_FAILURE;
8725  
8726  	switch (param) {
8727  	case CDP_ENABLE_WDS:
8728  		dp_cdp_err("%pK: wds_enable %d for vdev(%pK) id(%d)",
8729  			   dsoc, val.cdp_vdev_param_wds, vdev, vdev->vdev_id);
8730  		vdev->wds_enabled = val.cdp_vdev_param_wds;
8731  		break;
8732  	case CDP_ENABLE_MEC:
8733  		dp_cdp_err("%pK: mec_enable %d for vdev(%pK) id(%d)",
8734  			   dsoc, val.cdp_vdev_param_mec, vdev, vdev->vdev_id);
8735  		vdev->mec_enabled = val.cdp_vdev_param_mec;
8736  		break;
8737  	case CDP_ENABLE_DA_WAR:
8738  		dp_cdp_err("%pK: da_war_enable %d for vdev(%pK) id(%d)",
8739  			   dsoc, val.cdp_vdev_param_da_war, vdev, vdev->vdev_id);
8740  		vdev->pdev->soc->da_war_enabled = val.cdp_vdev_param_da_war;
8741  		dp_wds_flush_ast_table_wifi3(((struct cdp_soc_t *)
8742  					     vdev->pdev->soc));
8743  		break;
8744  	case CDP_ENABLE_NAWDS:
8745  		vdev->nawds_enabled = val.cdp_vdev_param_nawds;
8746  		break;
8747  	case CDP_ENABLE_MCAST_EN:
8748  		vdev->mcast_enhancement_en = val.cdp_vdev_param_mcast_en;
8749  		break;
8750  	case CDP_ENABLE_IGMP_MCAST_EN:
8751  		vdev->igmp_mcast_enhanc_en = val.cdp_vdev_param_igmp_mcast_en;
8752  		break;
8753  	case CDP_ENABLE_PROXYSTA:
8754  		vdev->proxysta_vdev = val.cdp_vdev_param_proxysta;
8755  		break;
8756  	case CDP_UPDATE_TDLS_FLAGS:
8757  		vdev->tdls_link_connected = val.cdp_vdev_param_tdls_flags;
8758  		break;
8759  	case CDP_CFG_WDS_AGING_TIMER:
8760  		var = val.cdp_vdev_param_aging_tmr;
8761  		if (!var)
8762  			qdf_timer_stop(&vdev->pdev->soc->ast_aging_timer);
8763  		else if (var != vdev->wds_aging_timer_val)
8764  			qdf_timer_mod(&vdev->pdev->soc->ast_aging_timer, var);
8765  
8766  		vdev->wds_aging_timer_val = var;
8767  		break;
8768  	case CDP_ENABLE_AP_BRIDGE:
8769  		if (wlan_op_mode_sta != vdev->opmode)
8770  			vdev->ap_bridge_enabled = val.cdp_vdev_param_ap_brdg_en;
8771  		else
8772  			vdev->ap_bridge_enabled = false;
8773  		break;
8774  	case CDP_ENABLE_CIPHER:
8775  		vdev->sec_type = val.cdp_vdev_param_cipher_en;
8776  		break;
8777  	case CDP_ENABLE_QWRAP_ISOLATION:
8778  		vdev->isolation_vdev = val.cdp_vdev_param_qwrap_isolation;
8779  		break;
8780  	case CDP_UPDATE_MULTIPASS:
8781  		vdev->multipass_en = val.cdp_vdev_param_update_multipass;
8782  		dp_info("vdev %d Multipass enable %d", vdev_id,
8783  			vdev->multipass_en);
8784  		break;
8785  	case CDP_TX_ENCAP_TYPE:
8786  		vdev->tx_encap_type = val.cdp_vdev_param_tx_encap;
8787  		break;
8788  	case CDP_RX_DECAP_TYPE:
8789  		vdev->rx_decap_type = val.cdp_vdev_param_rx_decap;
8790  		break;
8791  	case CDP_TID_VDEV_PRTY:
8792  		vdev->tidmap_prty = val.cdp_vdev_param_tidmap_prty;
8793  		break;
8794  	case CDP_TIDMAP_TBL_ID:
8795  		vdev->tidmap_tbl_id = val.cdp_vdev_param_tidmap_tbl_id;
8796  		break;
8797  #ifdef MESH_MODE_SUPPORT
8798  	case CDP_MESH_RX_FILTER:
8799  		dp_vdev_set_mesh_rx_filter((struct cdp_vdev *)vdev,
8800  					   val.cdp_vdev_param_mesh_rx_filter);
8801  		break;
8802  	case CDP_MESH_MODE:
8803  		dp_vdev_set_mesh_mode((struct cdp_vdev *)vdev,
8804  				      val.cdp_vdev_param_mesh_mode);
8805  		break;
8806  #endif
8807  	case CDP_ENABLE_HLOS_TID_OVERRIDE:
8808  		dp_info("vdev_id %d enable hlod tid override %d", vdev_id,
8809  			val.cdp_vdev_param_hlos_tid_override);
8810  		dp_vdev_set_hlos_tid_override(vdev,
8811  				val.cdp_vdev_param_hlos_tid_override);
8812  		break;
8813  #ifdef QCA_SUPPORT_WDS_EXTENDED
8814  	case CDP_CFG_WDS_EXT:
8815  		if (vdev->opmode == wlan_op_mode_ap)
8816  			vdev->wds_ext_enabled = val.cdp_vdev_param_wds_ext;
8817  		break;
8818  	case CDP_DROP_TX_MCAST:
8819  		dp_info("vdev_id %d drop tx mcast :%d", vdev_id,
8820  			val.cdp_drop_tx_mcast);
8821  		vdev->drop_tx_mcast = val.cdp_drop_tx_mcast;
8822  		break;
8823  #endif
8824  	case CDP_ENABLE_PEER_AUTHORIZE:
8825  		vdev->peer_authorize = val.cdp_vdev_param_peer_authorize;
8826  		break;
8827  #ifdef WLAN_SUPPORT_MESH_LATENCY
8828  	case CDP_ENABLE_PEER_TID_LATENCY:
8829  		dp_info("vdev_id %d enable peer tid latency %d", vdev_id,
8830  			val.cdp_vdev_param_peer_tid_latency_enable);
8831  		vdev->peer_tid_latency_enabled =
8832  			val.cdp_vdev_param_peer_tid_latency_enable;
8833  		break;
8834  	case CDP_SET_VAP_MESH_TID:
8835  		dp_info("vdev_id %d enable peer tid latency %d", vdev_id,
8836  			val.cdp_vdev_param_mesh_tid);
8837  		vdev->mesh_tid_latency_config.latency_tid
8838  				= val.cdp_vdev_param_mesh_tid;
8839  		break;
8840  #endif
8841  #ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE
8842  	case CDP_SKIP_BAR_UPDATE_AP:
8843  		dp_info("vdev_id %d skip BAR update: %u", vdev_id,
8844  			val.cdp_skip_bar_update);
8845  		vdev->skip_bar_update = val.cdp_skip_bar_update;
8846  		vdev->skip_bar_update_last_ts = 0;
8847  		break;
8848  #endif
8849  	case CDP_DROP_3ADDR_MCAST:
8850  		dp_info("vdev_id %d drop 3 addr mcast :%d", vdev_id,
8851  			val.cdp_drop_3addr_mcast);
8852  		vdev->drop_3addr_mcast = val.cdp_drop_3addr_mcast;
8853  		break;
8854  	case CDP_ENABLE_WRAP:
8855  		vdev->wrap_vdev = val.cdp_vdev_param_wrap;
8856  		break;
8857  #ifdef DP_TRAFFIC_END_INDICATION
8858  	case CDP_ENABLE_TRAFFIC_END_INDICATION:
8859  		vdev->traffic_end_ind_en = val.cdp_vdev_param_traffic_end_ind;
8860  		break;
8861  #endif
8862  #ifdef FEATURE_DIRECT_LINK
8863  	case CDP_VDEV_TX_TO_FW:
8864  		dp_info("vdev_id %d to_fw :%d", vdev_id, val.cdp_vdev_tx_to_fw);
8865  		vdev->to_fw = val.cdp_vdev_tx_to_fw;
8866  		break;
8867  #endif
8868  	case CDP_VDEV_SET_MAC_ADDR:
8869  		dp_info("set mac addr, old mac addr" QDF_MAC_ADDR_FMT
8870  			" new mac addr: " QDF_MAC_ADDR_FMT " for vdev %d",
8871  			QDF_MAC_ADDR_REF(vdev->mac_addr.raw),
8872  			QDF_MAC_ADDR_REF(val.mac_addr), vdev->vdev_id);
8873  		qdf_mem_copy(&vdev->mac_addr.raw[0], val.mac_addr,
8874  			     QDF_MAC_ADDR_SIZE);
8875  		break;
8876  	default:
8877  		break;
8878  	}
8879  
8880  	dp_tx_vdev_update_search_flags((struct dp_vdev *)vdev);
8881  	dsoc->arch_ops.txrx_set_vdev_param(dsoc, vdev, param, val);
8882  
8883  	/* Update PDEV flags as VDEV flags are updated */
8884  	dp_pdev_update_fast_rx_flag(dsoc, vdev->pdev);
8885  	dp_vdev_unref_delete(dsoc, vdev, DP_MOD_ID_CDP);
8886  
8887  	return QDF_STATUS_SUCCESS;
8888  }
8889  
8890  #if defined(FEATURE_WLAN_TDLS) && defined(WLAN_FEATURE_11BE_MLO)
8891  /**
8892   * dp_update_mlo_vdev_for_tdls() - update mlo vdev configuration
8893   *                                 for TDLS
8894   * @cdp_soc: DP soc handle
8895   * @vdev_id: id of DP vdev handle
8896   * @param: parameter type for vdev
8897   * @val: value
8898   *
8899   * If TDLS connection is from secondary vdev, then update TX bank register
8900   * info for primary vdev as well.
8901   * If TDLS connection is from primary vdev, same as before.
8902   *
8903   * Return: None
8904   */
8905  static void
dp_update_mlo_vdev_for_tdls(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_vdev_param_type param,cdp_config_param_type val)8906  dp_update_mlo_vdev_for_tdls(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8907  			    enum cdp_vdev_param_type param,
8908  			    cdp_config_param_type val)
8909  {
8910  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
8911  	struct dp_peer *peer;
8912  	struct dp_peer *tmp_peer;
8913  	struct dp_peer *mld_peer;
8914  	struct dp_vdev *vdev = NULL;
8915  	struct dp_vdev *pri_vdev = NULL;
8916  	uint8_t pri_vdev_id = CDP_INVALID_VDEV_ID;
8917  
8918  	if (param != CDP_UPDATE_TDLS_FLAGS)
8919  		return;
8920  
8921  	dp_info("update TDLS flag for vdev_id %d, val %d",
8922  		vdev_id, val.cdp_vdev_param_tdls_flags);
8923  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_MISC);
8924  	/* only check for STA mode vdev */
8925  	if (!vdev || vdev->opmode != wlan_op_mode_sta) {
8926  		dp_info("vdev is not as expected for TDLS");
8927  		goto comp_ret;
8928  	}
8929  
8930  	/* Find primary vdev_id */
8931  	qdf_spin_lock_bh(&vdev->peer_list_lock);
8932  	TAILQ_FOREACH_SAFE(peer, &vdev->peer_list,
8933  			   peer_list_elem,
8934  			   tmp_peer) {
8935  		if (dp_peer_get_ref(soc, peer, DP_MOD_ID_CONFIG) ==
8936  					QDF_STATUS_SUCCESS) {
8937  			/* do check only if MLO link peer exist */
8938  			if (IS_MLO_DP_LINK_PEER(peer)) {
8939  				mld_peer = DP_GET_MLD_PEER_FROM_PEER(peer);
8940  				pri_vdev_id = mld_peer->vdev->vdev_id;
8941  				dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
8942  				break;
8943  			}
8944  			dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
8945  		}
8946  	}
8947  	qdf_spin_unlock_bh(&vdev->peer_list_lock);
8948  
8949  	if (pri_vdev_id != CDP_INVALID_VDEV_ID)
8950  		pri_vdev = dp_vdev_get_ref_by_id(soc, pri_vdev_id,
8951  						 DP_MOD_ID_MISC);
8952  
8953  	/* If current vdev is not same as primary vdev */
8954  	if (pri_vdev && pri_vdev != vdev) {
8955  		dp_info("primary vdev [%d] %pK different from vdev [%d] %pK",
8956  			pri_vdev->vdev_id, pri_vdev,
8957  			vdev->vdev_id, vdev);
8958  		dp_set_vdev_param(cdp_soc, pri_vdev->vdev_id,
8959  				  CDP_UPDATE_TDLS_FLAGS, val);
8960  	}
8961  
8962  comp_ret:
8963  	if (pri_vdev)
8964  		dp_vdev_unref_delete(soc, pri_vdev, DP_MOD_ID_MISC);
8965  	if (vdev)
8966  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_MISC);
8967  }
8968  
8969  static QDF_STATUS
dp_set_vdev_param_wrapper(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_vdev_param_type param,cdp_config_param_type val)8970  dp_set_vdev_param_wrapper(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8971  			  enum cdp_vdev_param_type param,
8972  			  cdp_config_param_type val)
8973  {
8974  	dp_update_mlo_vdev_for_tdls(cdp_soc, vdev_id, param, val);
8975  
8976  	return dp_set_vdev_param(cdp_soc, vdev_id, param, val);
8977  }
8978  #else
8979  static QDF_STATUS
dp_set_vdev_param_wrapper(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_vdev_param_type param,cdp_config_param_type val)8980  dp_set_vdev_param_wrapper(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
8981  			  enum cdp_vdev_param_type param,
8982  			  cdp_config_param_type val)
8983  {
8984  	return dp_set_vdev_param(cdp_soc, vdev_id, param, val);
8985  }
8986  #endif
8987  
8988  /**
8989   * dp_rx_peer_metadata_ver_update() - update rx peer metadata version and
8990   *                                    corresponding filed shift and mask
8991   * @soc: Handle to DP Soc structure
8992   * @peer_md_ver: RX peer metadata version value
8993   *
8994   * Return: None
8995   */
8996  static void
dp_rx_peer_metadata_ver_update(struct dp_soc * soc,uint8_t peer_md_ver)8997  dp_rx_peer_metadata_ver_update(struct dp_soc *soc, uint8_t peer_md_ver)
8998  {
8999  	dp_info("rx_peer_metadata version %d", peer_md_ver);
9000  
9001  	switch (peer_md_ver) {
9002  	case 0: /* htt_rx_peer_metadata_v0 */
9003  		soc->htt_peer_id_s = HTT_RX_PEER_META_DATA_V0_PEER_ID_S;
9004  		soc->htt_peer_id_m = HTT_RX_PEER_META_DATA_V0_PEER_ID_M;
9005  		soc->htt_vdev_id_s = HTT_RX_PEER_META_DATA_V0_VDEV_ID_S;
9006  		soc->htt_vdev_id_m = HTT_RX_PEER_META_DATA_V0_VDEV_ID_M;
9007  		break;
9008  	case 1: /* htt_rx_peer_metadata_v1 */
9009  		soc->htt_peer_id_s = HTT_RX_PEER_META_DATA_V1_PEER_ID_S;
9010  		soc->htt_peer_id_m = HTT_RX_PEER_META_DATA_V1_PEER_ID_M;
9011  		soc->htt_vdev_id_s = HTT_RX_PEER_META_DATA_V1_VDEV_ID_S;
9012  		soc->htt_vdev_id_m = HTT_RX_PEER_META_DATA_V1_VDEV_ID_M;
9013  		soc->htt_mld_peer_valid_s =
9014  				HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S;
9015  		soc->htt_mld_peer_valid_m =
9016  				HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_M;
9017  		break;
9018  	case 2: /* htt_rx_peer_metadata_v1a */
9019  		soc->htt_peer_id_s = HTT_RX_PEER_META_DATA_V1A_PEER_ID_S;
9020  		soc->htt_peer_id_m = HTT_RX_PEER_META_DATA_V1A_PEER_ID_M;
9021  		soc->htt_vdev_id_s = HTT_RX_PEER_META_DATA_V1A_VDEV_ID_S;
9022  		soc->htt_vdev_id_m = HTT_RX_PEER_META_DATA_V1A_VDEV_ID_M;
9023  		soc->htt_mld_peer_valid_s =
9024  				HTT_RX_PEER_META_DATA_V1A_ML_PEER_VALID_S;
9025  		soc->htt_mld_peer_valid_m =
9026  				HTT_RX_PEER_META_DATA_V1A_ML_PEER_VALID_M;
9027  		break;
9028  	case 3: /* htt_rx_peer_metadata_v1b */
9029  		soc->htt_peer_id_s = HTT_RX_PEER_META_DATA_V1B_PEER_ID_S;
9030  		soc->htt_peer_id_m = HTT_RX_PEER_META_DATA_V1B_PEER_ID_M;
9031  		soc->htt_vdev_id_s = HTT_RX_PEER_META_DATA_V1B_VDEV_ID_S;
9032  		soc->htt_vdev_id_m = HTT_RX_PEER_META_DATA_V1B_VDEV_ID_M;
9033  		soc->htt_mld_peer_valid_s =
9034  				HTT_RX_PEER_META_DATA_V1B_ML_PEER_VALID_S;
9035  		soc->htt_mld_peer_valid_m =
9036  				HTT_RX_PEER_META_DATA_V1B_ML_PEER_VALID_M;
9037  		break;
9038  	default:
9039  		dp_err("invliad rx_peer_metadata version %d", peer_md_ver);
9040  		break;
9041  	}
9042  
9043  	soc->rx_peer_metadata_ver = peer_md_ver;
9044  }
9045  
9046  /**
9047   * dp_set_psoc_param: function to set parameters in psoc
9048   * @cdp_soc: DP soc handle
9049   * @param: parameter type to be set
9050   * @val: value of parameter to be set
9051   *
9052   * Return: QDF_STATUS
9053   */
9054  static QDF_STATUS
dp_set_psoc_param(struct cdp_soc_t * cdp_soc,enum cdp_psoc_param_type param,cdp_config_param_type val)9055  dp_set_psoc_param(struct cdp_soc_t *cdp_soc,
9056  		  enum cdp_psoc_param_type param, cdp_config_param_type val)
9057  {
9058  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
9059  	struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = soc->wlan_cfg_ctx;
9060  
9061  	switch (param) {
9062  	case CDP_ENABLE_RATE_STATS:
9063  		soc->peerstats_enabled = val.cdp_psoc_param_en_rate_stats;
9064  		break;
9065  	case CDP_SET_NSS_CFG:
9066  		wlan_cfg_set_dp_soc_nss_cfg(wlan_cfg_ctx,
9067  					    val.cdp_psoc_param_en_nss_cfg);
9068  		/*
9069  		 * TODO: masked out based on the per offloaded radio
9070  		 */
9071  		switch (val.cdp_psoc_param_en_nss_cfg) {
9072  		case dp_nss_cfg_default:
9073  			break;
9074  		case dp_nss_cfg_first_radio:
9075  		/*
9076  		 * This configuration is valid for single band radio which
9077  		 * is also NSS offload.
9078  		 */
9079  		case dp_nss_cfg_dbdc:
9080  		case dp_nss_cfg_dbtc:
9081  			wlan_cfg_set_num_tx_desc_pool(wlan_cfg_ctx, 0);
9082  			wlan_cfg_set_num_tx_ext_desc_pool(wlan_cfg_ctx, 0);
9083  			wlan_cfg_set_num_tx_desc(wlan_cfg_ctx, 0);
9084  			wlan_cfg_set_num_tx_spl_desc(soc->wlan_cfg_ctx, 0);
9085  			wlan_cfg_set_num_tx_ext_desc(wlan_cfg_ctx, 0);
9086  			break;
9087  		default:
9088  			dp_cdp_err("%pK: Invalid offload config %d",
9089  				   soc, val.cdp_psoc_param_en_nss_cfg);
9090  		}
9091  
9092  			dp_cdp_err("%pK: nss-wifi<0> nss config is enabled"
9093  				   , soc);
9094  		break;
9095  	case CDP_SET_PREFERRED_HW_MODE:
9096  		soc->preferred_hw_mode = val.cdp_psoc_param_preferred_hw_mode;
9097  		break;
9098  	case CDP_IPA_ENABLE:
9099  		soc->wlan_cfg_ctx->ipa_enabled = val.cdp_ipa_enabled;
9100  		break;
9101  	case CDP_CFG_VDEV_STATS_HW_OFFLOAD:
9102  		wlan_cfg_set_vdev_stats_hw_offload_config(wlan_cfg_ctx,
9103  				val.cdp_psoc_param_vdev_stats_hw_offload);
9104  		break;
9105  	case CDP_SAWF_ENABLE:
9106  		wlan_cfg_set_sawf_config(wlan_cfg_ctx, val.cdp_sawf_enabled);
9107  		break;
9108  	case CDP_UMAC_RST_SKEL_ENABLE:
9109  		dp_umac_rst_skel_enable_update(soc, val.cdp_umac_rst_skel);
9110  		break;
9111  	case CDP_UMAC_RESET_STATS:
9112  		dp_umac_reset_stats_print(soc);
9113  		break;
9114  	case CDP_SAWF_STATS:
9115  		wlan_cfg_set_sawf_stats_config(wlan_cfg_ctx,
9116  					       val.cdp_sawf_stats);
9117  		break;
9118  	case CDP_CFG_RX_PEER_METADATA_VER:
9119  		dp_rx_peer_metadata_ver_update(
9120  				soc, val.cdp_peer_metadata_ver);
9121  		break;
9122  	case CDP_CFG_TX_DESC_NUM:
9123  		wlan_cfg_set_num_tx_desc(wlan_cfg_ctx,
9124  					 val.cdp_tx_desc_num);
9125  		break;
9126  	case CDP_CFG_TX_EXT_DESC_NUM:
9127  		wlan_cfg_set_num_tx_ext_desc(wlan_cfg_ctx,
9128  					     val.cdp_tx_ext_desc_num);
9129  		break;
9130  	case CDP_CFG_TX_RING_SIZE:
9131  		wlan_cfg_set_tx_ring_size(wlan_cfg_ctx,
9132  					  val.cdp_tx_ring_size);
9133  		break;
9134  	case CDP_CFG_TX_COMPL_RING_SIZE:
9135  		wlan_cfg_set_tx_comp_ring_size(wlan_cfg_ctx,
9136  					       val.cdp_tx_comp_ring_size);
9137  		break;
9138  	case CDP_CFG_RX_SW_DESC_NUM:
9139  		wlan_cfg_set_dp_soc_rx_sw_desc_num(wlan_cfg_ctx,
9140  						   val.cdp_rx_sw_desc_num);
9141  		break;
9142  	case CDP_CFG_REO_DST_RING_SIZE:
9143  		wlan_cfg_set_reo_dst_ring_size(wlan_cfg_ctx,
9144  					       val.cdp_reo_dst_ring_size);
9145  		break;
9146  	case CDP_CFG_RXDMA_REFILL_RING_SIZE:
9147  		wlan_cfg_set_dp_soc_rxdma_refill_ring_size(wlan_cfg_ctx,
9148  					val.cdp_rxdma_refill_ring_size);
9149  		break;
9150  #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
9151  	case CDP_CFG_RX_REFILL_POOL_NUM:
9152  		wlan_cfg_set_rx_refill_buf_pool_size(wlan_cfg_ctx,
9153  						val.cdp_rx_refill_buf_pool_size);
9154  		break;
9155  #endif
9156  	case CDP_CFG_AST_INDICATION_DISABLE:
9157  		wlan_cfg_set_ast_indication_disable
9158  			(wlan_cfg_ctx, val.cdp_ast_indication_disable);
9159  		break;
9160  	case CDP_CONFIG_DP_DEBUG_LOG:
9161  		soc->dp_debug_log_en = val.cdp_psoc_param_dp_debug_log;
9162  		break;
9163  	case CDP_MONITOR_FLAG:
9164  		soc->mon_flags = val.cdp_monitor_flag;
9165  		dp_info("monior interface flags: 0x%x", soc->mon_flags);
9166  		break;
9167  	default:
9168  		break;
9169  	}
9170  
9171  	return QDF_STATUS_SUCCESS;
9172  }
9173  
9174  #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
9175  /**
9176   * dp_get_mldev_mode: function to get mlo operation mode
9177   * @soc: soc structure for data path
9178   *
9179   * Return: uint8_t
9180   */
dp_get_mldev_mode(struct dp_soc * soc)9181  static uint8_t dp_get_mldev_mode(struct dp_soc *soc)
9182  {
9183  	return soc->mld_mode_ap;
9184  }
9185  #else
dp_get_mldev_mode(struct dp_soc * cdp_soc)9186  static uint8_t dp_get_mldev_mode(struct dp_soc *cdp_soc)
9187  {
9188  	return MLD_MODE_INVALID;
9189  }
9190  #endif
9191  
9192  /**
9193   * dp_get_psoc_param: function to get parameters in soc
9194   * @cdp_soc: DP soc handle
9195   * @param: parameter type to be get
9196   * @val: address of buffer
9197   *
9198   * Return: status
9199   */
dp_get_psoc_param(struct cdp_soc_t * cdp_soc,enum cdp_psoc_param_type param,cdp_config_param_type * val)9200  static QDF_STATUS dp_get_psoc_param(struct cdp_soc_t *cdp_soc,
9201  				    enum cdp_psoc_param_type param,
9202  				    cdp_config_param_type *val)
9203  {
9204  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
9205  	struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx;
9206  
9207  	if (!soc)
9208  		return QDF_STATUS_E_FAILURE;
9209  
9210  	wlan_cfg_ctx = soc->wlan_cfg_ctx;
9211  
9212  	switch (param) {
9213  	case CDP_ENABLE_RATE_STATS:
9214  		val->cdp_psoc_param_en_rate_stats = soc->peerstats_enabled;
9215  		break;
9216  	case CDP_CFG_PEER_EXT_STATS:
9217  		val->cdp_psoc_param_pext_stats =
9218  			wlan_cfg_is_peer_ext_stats_enabled(wlan_cfg_ctx);
9219  		break;
9220  	case CDP_CFG_VDEV_STATS_HW_OFFLOAD:
9221  		val->cdp_psoc_param_vdev_stats_hw_offload =
9222  			wlan_cfg_get_vdev_stats_hw_offload_config(wlan_cfg_ctx);
9223  		break;
9224  	case CDP_UMAC_RST_SKEL_ENABLE:
9225  		val->cdp_umac_rst_skel = dp_umac_rst_skel_enable_get(soc);
9226  		break;
9227  	case CDP_TXRX_HAL_SOC_HDL:
9228  		val->hal_soc_hdl = soc->hal_soc;
9229  		break;
9230  	case CDP_CFG_TX_DESC_NUM:
9231  		val->cdp_tx_desc_num = wlan_cfg_get_num_tx_desc(wlan_cfg_ctx);
9232  		break;
9233  	case CDP_CFG_TX_EXT_DESC_NUM:
9234  		val->cdp_tx_ext_desc_num =
9235  			wlan_cfg_get_num_tx_ext_desc(wlan_cfg_ctx);
9236  		break;
9237  	case CDP_CFG_TX_RING_SIZE:
9238  		val->cdp_tx_ring_size = wlan_cfg_tx_ring_size(wlan_cfg_ctx);
9239  		break;
9240  	case CDP_CFG_TX_COMPL_RING_SIZE:
9241  		val->cdp_tx_comp_ring_size =
9242  			wlan_cfg_tx_comp_ring_size(wlan_cfg_ctx);
9243  		break;
9244  	case CDP_CFG_RX_SW_DESC_NUM:
9245  		val->cdp_rx_sw_desc_num =
9246  			wlan_cfg_get_dp_soc_rx_sw_desc_num(wlan_cfg_ctx);
9247  		break;
9248  	case CDP_CFG_REO_DST_RING_SIZE:
9249  		val->cdp_reo_dst_ring_size =
9250  			wlan_cfg_get_reo_dst_ring_size(wlan_cfg_ctx);
9251  		break;
9252  	case CDP_CFG_RXDMA_REFILL_RING_SIZE:
9253  		val->cdp_rxdma_refill_ring_size =
9254  			wlan_cfg_get_dp_soc_rxdma_refill_ring_size(wlan_cfg_ctx);
9255  		break;
9256  #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
9257  	case CDP_CFG_RX_REFILL_POOL_NUM:
9258  		val->cdp_rx_refill_buf_pool_size =
9259  			wlan_cfg_get_rx_refill_buf_pool_size(wlan_cfg_ctx);
9260  		break;
9261  #endif
9262  	case CDP_CFG_FISA_PARAMS:
9263  		val->fisa_params.fisa_fst_size = wlan_cfg_get_rx_flow_search_table_size(soc->wlan_cfg_ctx);
9264  		val->fisa_params.rx_flow_max_search =
9265  			wlan_cfg_rx_fst_get_max_search(soc->wlan_cfg_ctx);
9266  		val->fisa_params.rx_toeplitz_hash_key =
9267  			wlan_cfg_rx_fst_get_hash_key(soc->wlan_cfg_ctx);
9268  		break;
9269  	case CDP_RX_PKT_TLV_SIZE:
9270  		val->rx_pkt_tlv_size = soc->rx_pkt_tlv_size;
9271  		break;
9272  	case CDP_CFG_GET_MLO_OPER_MODE:
9273  		val->cdp_psoc_param_mlo_oper_mode = dp_get_mldev_mode(soc);
9274  		break;
9275  	case CDP_CFG_PEER_JITTER_STATS:
9276  		val->cdp_psoc_param_jitter_stats =
9277  			wlan_cfg_is_peer_jitter_stats_enabled(soc->wlan_cfg_ctx);
9278  		break;
9279  	case CDP_CONFIG_DP_DEBUG_LOG:
9280  		val->cdp_psoc_param_dp_debug_log = soc->dp_debug_log_en;
9281  		break;
9282  	case CDP_MONITOR_FLAG:
9283  		val->cdp_monitor_flag = soc->mon_flags;
9284  		break;
9285  	default:
9286  		dp_warn("Invalid param: %u", param);
9287  		break;
9288  	}
9289  
9290  	return QDF_STATUS_SUCCESS;
9291  }
9292  
9293  /**
9294   * dp_set_vdev_dscp_tid_map_wifi3() - Update Map ID selected for particular vdev
9295   * @cdp_soc: CDP SOC handle
9296   * @vdev_id: id of DP_VDEV handle
9297   * @map_id:ID of map that needs to be updated
9298   *
9299   * Return: QDF_STATUS
9300   */
dp_set_vdev_dscp_tid_map_wifi3(ol_txrx_soc_handle cdp_soc,uint8_t vdev_id,uint8_t map_id)9301  static QDF_STATUS dp_set_vdev_dscp_tid_map_wifi3(ol_txrx_soc_handle cdp_soc,
9302  						 uint8_t vdev_id,
9303  						 uint8_t map_id)
9304  {
9305  	cdp_config_param_type val;
9306  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
9307  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
9308  						     DP_MOD_ID_CDP);
9309  	if (vdev) {
9310  		vdev->dscp_tid_map_id = map_id;
9311  		val.cdp_vdev_param_dscp_tid_map_id = map_id;
9312  		soc->arch_ops.txrx_set_vdev_param(soc,
9313  						  vdev,
9314  						  CDP_UPDATE_DSCP_TO_TID_MAP,
9315  						  val);
9316  		/* Update flag for transmit tid classification */
9317  		if (vdev->dscp_tid_map_id < soc->num_hw_dscp_tid_map)
9318  			vdev->skip_sw_tid_classification |=
9319  				DP_TX_HW_DSCP_TID_MAP_VALID;
9320  		else
9321  			vdev->skip_sw_tid_classification &=
9322  				~DP_TX_HW_DSCP_TID_MAP_VALID;
9323  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
9324  		return QDF_STATUS_SUCCESS;
9325  	}
9326  
9327  	return QDF_STATUS_E_FAILURE;
9328  }
9329  
9330  #ifdef DP_RATETABLE_SUPPORT
dp_txrx_get_ratekbps(int preamb,int mcs,int htflag,int gintval)9331  static int dp_txrx_get_ratekbps(int preamb, int mcs,
9332  				int htflag, int gintval)
9333  {
9334  	uint32_t rix;
9335  	uint16_t ratecode;
9336  	enum cdp_punctured_modes punc_mode = NO_PUNCTURE;
9337  
9338  	return dp_getrateindex((uint32_t)gintval, (uint16_t)mcs, 1,
9339  			       (uint8_t)preamb, 1, punc_mode,
9340  			       &rix, &ratecode);
9341  }
9342  #else
dp_txrx_get_ratekbps(int preamb,int mcs,int htflag,int gintval)9343  static int dp_txrx_get_ratekbps(int preamb, int mcs,
9344  				int htflag, int gintval)
9345  {
9346  	return 0;
9347  }
9348  #endif
9349  
9350  /**
9351   * dp_txrx_get_pdev_stats() - Returns cdp_pdev_stats
9352   * @soc: DP soc handle
9353   * @pdev_id: id of DP pdev handle
9354   * @pdev_stats: buffer to copy to
9355   *
9356   * Return: status success/failure
9357   */
9358  static QDF_STATUS
dp_txrx_get_pdev_stats(struct cdp_soc_t * soc,uint8_t pdev_id,struct cdp_pdev_stats * pdev_stats)9359  dp_txrx_get_pdev_stats(struct cdp_soc_t *soc, uint8_t pdev_id,
9360  		       struct cdp_pdev_stats *pdev_stats)
9361  {
9362  	struct dp_pdev *pdev =
9363  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
9364  						   pdev_id);
9365  	if (!pdev)
9366  		return QDF_STATUS_E_FAILURE;
9367  
9368  	dp_aggregate_pdev_stats(pdev);
9369  
9370  	qdf_mem_copy(pdev_stats, &pdev->stats, sizeof(struct cdp_pdev_stats));
9371  	return QDF_STATUS_SUCCESS;
9372  }
9373  
9374  /**
9375   * dp_txrx_update_vdev_me_stats() - Update vdev ME stats sent from CDP
9376   * @vdev: DP vdev handle
9377   * @buf: buffer containing specific stats structure
9378   * @xmit_type: xmit type of packet - MLD/Link
9379   *
9380   * Return: void
9381   */
dp_txrx_update_vdev_me_stats(struct dp_vdev * vdev,void * buf,uint8_t xmit_type)9382  static void dp_txrx_update_vdev_me_stats(struct dp_vdev *vdev,
9383  					 void *buf, uint8_t xmit_type)
9384  {
9385  	struct cdp_tx_ingress_stats *host_stats = NULL;
9386  
9387  	if (!buf) {
9388  		dp_cdp_err("%pK: Invalid host stats buf", vdev->pdev->soc);
9389  		return;
9390  	}
9391  	host_stats = (struct cdp_tx_ingress_stats *)buf;
9392  
9393  	DP_STATS_INC_PKT(vdev, tx_i[xmit_type].mcast_en.mcast_pkt,
9394  			 host_stats->mcast_en.mcast_pkt.num,
9395  			 host_stats->mcast_en.mcast_pkt.bytes);
9396  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.dropped_map_error,
9397  		     host_stats->mcast_en.dropped_map_error);
9398  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.dropped_self_mac,
9399  		     host_stats->mcast_en.dropped_self_mac);
9400  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.dropped_send_fail,
9401  		     host_stats->mcast_en.dropped_send_fail);
9402  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.ucast,
9403  		     host_stats->mcast_en.ucast);
9404  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.fail_seg_alloc,
9405  		     host_stats->mcast_en.fail_seg_alloc);
9406  	DP_STATS_INC(vdev, tx_i[xmit_type].mcast_en.clone_fail,
9407  		     host_stats->mcast_en.clone_fail);
9408  }
9409  
9410  /**
9411   * dp_txrx_update_vdev_igmp_me_stats() - Update vdev IGMP ME stats sent from CDP
9412   * @vdev: DP vdev handle
9413   * @buf: buffer containing specific stats structure
9414   * @xmit_type: xmit type of packet -  MLD/Link
9415   *
9416   * Return: void
9417   */
dp_txrx_update_vdev_igmp_me_stats(struct dp_vdev * vdev,void * buf,uint8_t xmit_type)9418  static void dp_txrx_update_vdev_igmp_me_stats(struct dp_vdev *vdev,
9419  					      void *buf, uint8_t xmit_type)
9420  {
9421  	struct cdp_tx_ingress_stats *host_stats = NULL;
9422  
9423  	if (!buf) {
9424  		dp_cdp_err("%pK: Invalid host stats buf", vdev->pdev->soc);
9425  		return;
9426  	}
9427  	host_stats = (struct cdp_tx_ingress_stats *)buf;
9428  
9429  	DP_STATS_INC(vdev, tx_i[xmit_type].igmp_mcast_en.igmp_rcvd,
9430  		     host_stats->igmp_mcast_en.igmp_rcvd);
9431  	DP_STATS_INC(vdev, tx_i[xmit_type].igmp_mcast_en.igmp_ucast_converted,
9432  		     host_stats->igmp_mcast_en.igmp_ucast_converted);
9433  }
9434  
9435  /**
9436   * dp_txrx_update_vdev_host_stats() - Update stats sent through CDP
9437   * @soc_hdl: DP soc handle
9438   * @vdev_id: id of DP vdev handle
9439   * @buf: buffer containing specific stats structure
9440   * @stats_id: stats type
9441   * @xmit_type: xmit type of packet - MLD/Link
9442   *
9443   * Return: QDF_STATUS
9444   */
dp_txrx_update_vdev_host_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,void * buf,uint16_t stats_id,uint8_t xmit_type)9445  static QDF_STATUS dp_txrx_update_vdev_host_stats(struct cdp_soc_t *soc_hdl,
9446  						 uint8_t vdev_id,
9447  						 void *buf,
9448  						 uint16_t stats_id,
9449  						 uint8_t xmit_type)
9450  {
9451  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
9452  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
9453  						     DP_MOD_ID_CDP);
9454  
9455  	if (!vdev) {
9456  		dp_cdp_err("%pK: Invalid vdev handle", soc);
9457  		return QDF_STATUS_E_FAILURE;
9458  	}
9459  
9460  	switch (stats_id) {
9461  	case DP_VDEV_STATS_PKT_CNT_ONLY:
9462  		break;
9463  	case DP_VDEV_STATS_TX_ME:
9464  		dp_txrx_update_vdev_me_stats(vdev, buf, xmit_type);
9465  		dp_txrx_update_vdev_igmp_me_stats(vdev, buf, xmit_type);
9466  		break;
9467  	default:
9468  		qdf_info("Invalid stats_id %d", stats_id);
9469  		break;
9470  	}
9471  
9472  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
9473  	return QDF_STATUS_SUCCESS;
9474  }
9475  
9476  /**
9477   * dp_txrx_get_peer_stats_wrapper() - will get cdp_peer_stats
9478   * @soc: soc handle
9479   * @peer_stats: destination buffer to copy to
9480   * @peer_info: peer info
9481   *
9482   * Return: status success/failure
9483   */
9484  static QDF_STATUS
dp_txrx_get_peer_stats_wrapper(struct cdp_soc_t * soc,struct cdp_peer_stats * peer_stats,struct cdp_peer_info peer_info)9485  dp_txrx_get_peer_stats_wrapper(struct cdp_soc_t *soc,
9486  			       struct cdp_peer_stats *peer_stats,
9487  			       struct cdp_peer_info peer_info)
9488  {
9489  	struct dp_peer *peer = NULL;
9490  
9491  	peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info,
9492  					 DP_MOD_ID_CDP);
9493  
9494  	qdf_mem_zero(peer_stats, sizeof(struct cdp_peer_stats));
9495  
9496  	if (!peer)
9497  		return QDF_STATUS_E_FAILURE;
9498  
9499  	dp_get_peer_stats(peer, peer_stats);
9500  
9501  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
9502  
9503  	return QDF_STATUS_SUCCESS;
9504  }
9505  
9506  /**
9507   * dp_txrx_get_peer_stats() - will get cdp_peer_stats
9508   * @soc: soc handle
9509   * @vdev_id: id of vdev handle
9510   * @peer_mac: peer mac address of DP_PEER handle
9511   * @peer_stats: destination buffer to copy to
9512   *
9513   * Return: status success/failure
9514   */
9515  static QDF_STATUS
dp_txrx_get_peer_stats(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac,struct cdp_peer_stats * peer_stats)9516  dp_txrx_get_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id,
9517  		       uint8_t *peer_mac, struct cdp_peer_stats *peer_stats)
9518  {
9519  	struct cdp_peer_info peer_info = { 0 };
9520  
9521  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false,
9522  				 CDP_WILD_PEER_TYPE);
9523  
9524  	return dp_txrx_get_peer_stats_wrapper(soc, peer_stats, peer_info);
9525  }
9526  
9527  /**
9528   * dp_txrx_get_peer_stats_based_on_peer_type() - get peer stats based on the
9529   * peer type
9530   * @soc: soc handle
9531   * @vdev_id: id of vdev handle
9532   * @peer_mac: mac of DP_PEER handle
9533   * @peer_stats: buffer to copy to
9534   * @peer_type: type of peer
9535   *
9536   * Return: status success/failure
9537   */
9538  static QDF_STATUS
dp_txrx_get_peer_stats_based_on_peer_type(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac,struct cdp_peer_stats * peer_stats,enum cdp_peer_type peer_type)9539  dp_txrx_get_peer_stats_based_on_peer_type(struct cdp_soc_t *soc, uint8_t vdev_id,
9540  					  uint8_t *peer_mac,
9541  					  struct cdp_peer_stats *peer_stats,
9542  					  enum cdp_peer_type peer_type)
9543  {
9544  	struct cdp_peer_info peer_info = { 0 };
9545  
9546  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false,
9547  				 peer_type);
9548  
9549  	return dp_txrx_get_peer_stats_wrapper(soc, peer_stats, peer_info);
9550  }
9551  
9552  #if defined WLAN_FEATURE_11BE_MLO && defined DP_MLO_LINK_STATS_SUPPORT
9553  /**
9554   * dp_get_per_link_peer_stats() - Get per link stats
9555   * @peer: DP peer
9556   * @peer_stats: buffer to copy to
9557   * @peer_type: Peer type
9558   * @num_link: Number of ML links
9559   *
9560   * Return: status success/failure
9561   */
dp_get_per_link_peer_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats,enum cdp_peer_type peer_type,uint8_t num_link)9562  QDF_STATUS dp_get_per_link_peer_stats(struct dp_peer *peer,
9563  				      struct cdp_peer_stats *peer_stats,
9564  				      enum cdp_peer_type peer_type,
9565  				      uint8_t num_link)
9566  {
9567  	uint8_t i, min_num_links;
9568  	struct dp_peer *link_peer;
9569  	struct dp_mld_link_peers link_peers_info;
9570  	struct dp_soc *soc = peer->vdev->pdev->soc;
9571  
9572  	dp_get_peer_calibr_stats(peer, peer_stats);
9573  	dp_get_peer_basic_stats(peer, peer_stats);
9574  	dp_get_peer_tx_per(peer_stats);
9575  
9576  	if (IS_MLO_DP_MLD_PEER(peer)) {
9577  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
9578  						    &link_peers_info,
9579  						    DP_MOD_ID_GENERIC_STATS);
9580  		if (link_peers_info.num_links > num_link)
9581  			dp_info("Req stats of %d link. less than total link %d",
9582  				num_link, link_peers_info.num_links);
9583  
9584  		min_num_links = num_link < link_peers_info.num_links ?
9585  				num_link : link_peers_info.num_links;
9586  		for (i = 0; i < min_num_links; i++) {
9587  			link_peer = link_peers_info.link_peers[i];
9588  			if (qdf_unlikely(!link_peer))
9589  				continue;
9590  			dp_get_peer_per_pkt_stats(link_peer, peer_stats);
9591  			dp_get_peer_extd_stats(link_peer, peer_stats);
9592  		}
9593  		dp_release_link_peers_ref(&link_peers_info,
9594  					  DP_MOD_ID_GENERIC_STATS);
9595  	} else {
9596  		dp_get_peer_per_pkt_stats(peer, peer_stats);
9597  		dp_get_peer_extd_stats(peer, peer_stats);
9598  	}
9599  	return QDF_STATUS_SUCCESS;
9600  }
9601  #else
dp_get_per_link_peer_stats(struct dp_peer * peer,struct cdp_peer_stats * peer_stats,enum cdp_peer_type peer_type,uint8_t num_link)9602  QDF_STATUS dp_get_per_link_peer_stats(struct dp_peer *peer,
9603  				      struct cdp_peer_stats *peer_stats,
9604  				      enum cdp_peer_type peer_type,
9605  				      uint8_t num_link)
9606  {
9607  	dp_err("Per link stats not supported");
9608  	return QDF_STATUS_E_INVAL;
9609  }
9610  #endif
9611  
9612  /**
9613   * dp_txrx_get_per_link_peer_stats() - Get per link peer stats
9614   * @soc: soc handle
9615   * @vdev_id: id of vdev handle
9616   * @peer_mac: peer mac address
9617   * @peer_stats: buffer to copy to
9618   * @peer_type: Peer type
9619   * @num_link: Number of ML links
9620   *
9621   * NOTE: For peer_type = CDP_MLD_PEER_TYPE peer_stats should point to
9622   *       buffer of size = (sizeof(*peer_stats) * num_link)
9623   *
9624   * Return: status success/failure
9625   */
9626  static QDF_STATUS
dp_txrx_get_per_link_peer_stats(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac,struct cdp_peer_stats * peer_stats,enum cdp_peer_type peer_type,uint8_t num_link)9627  dp_txrx_get_per_link_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id,
9628  				uint8_t *peer_mac,
9629  				struct cdp_peer_stats *peer_stats,
9630  				enum cdp_peer_type peer_type, uint8_t num_link)
9631  {
9632  	QDF_STATUS status;
9633  	struct dp_peer *peer = NULL;
9634  	struct cdp_peer_info peer_info = { 0 };
9635  
9636  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false,
9637  				 peer_type);
9638  
9639  	peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info,
9640  					 DP_MOD_ID_GENERIC_STATS);
9641  	if (!peer)
9642  		return QDF_STATUS_E_FAILURE;
9643  
9644  	qdf_mem_zero(peer_stats, sizeof(struct cdp_peer_stats));
9645  
9646  	status = dp_get_per_link_peer_stats(peer, peer_stats, peer_type,
9647  					    num_link);
9648  
9649  	dp_peer_unref_delete(peer, DP_MOD_ID_GENERIC_STATS);
9650  
9651  	return status;
9652  }
9653  
9654  /**
9655   * dp_txrx_get_peer_stats_param() - will return specified cdp_peer_stats
9656   * @soc: soc handle
9657   * @vdev_id: vdev_id of vdev object
9658   * @peer_mac: mac address of the peer
9659   * @type: enum of required stats
9660   * @buf: buffer to hold the value
9661   *
9662   * Return: status success/failure
9663   */
9664  static QDF_STATUS
dp_txrx_get_peer_stats_param(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac,enum cdp_peer_stats_type type,cdp_peer_stats_param_t * buf)9665  dp_txrx_get_peer_stats_param(struct cdp_soc_t *soc, uint8_t vdev_id,
9666  			     uint8_t *peer_mac, enum cdp_peer_stats_type type,
9667  			     cdp_peer_stats_param_t *buf)
9668  {
9669  	QDF_STATUS ret;
9670  	struct dp_peer *peer = NULL;
9671  	struct cdp_peer_info peer_info = { 0 };
9672  
9673  	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false,
9674  				 CDP_WILD_PEER_TYPE);
9675  
9676  	peer = dp_peer_hash_find_wrapper((struct dp_soc *)soc, &peer_info,
9677  				         DP_MOD_ID_CDP);
9678  
9679  	if (!peer) {
9680  		dp_peer_err("%pK: Invalid Peer for Mac " QDF_MAC_ADDR_FMT,
9681  			    soc, QDF_MAC_ADDR_REF(peer_mac));
9682  		return QDF_STATUS_E_FAILURE;
9683  	}
9684  
9685  	if (type >= cdp_peer_per_pkt_stats_min &&
9686  	    type < cdp_peer_per_pkt_stats_max) {
9687  		ret = dp_txrx_get_peer_per_pkt_stats_param(peer, type, buf);
9688  	} else if (type >= cdp_peer_extd_stats_min &&
9689  		   type < cdp_peer_extd_stats_max) {
9690  		ret = dp_txrx_get_peer_extd_stats_param(peer, type, buf);
9691  	} else {
9692  		dp_err("%pK: Invalid stat type requested", soc);
9693  		ret = QDF_STATUS_E_FAILURE;
9694  	}
9695  
9696  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
9697  
9698  	return ret;
9699  }
9700  
9701  /**
9702   * dp_txrx_reset_peer_stats() - reset cdp_peer_stats for particular peer
9703   * @soc_hdl: soc handle
9704   * @vdev_id: id of vdev handle
9705   * @peer_mac: mac of DP_PEER handle
9706   *
9707   * Return: QDF_STATUS
9708   */
9709  #ifdef WLAN_FEATURE_11BE_MLO
9710  static QDF_STATUS
dp_txrx_reset_peer_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac)9711  dp_txrx_reset_peer_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
9712  			 uint8_t *peer_mac)
9713  {
9714  	QDF_STATUS status = QDF_STATUS_SUCCESS;
9715  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
9716  	struct dp_peer *peer =
9717  			dp_peer_get_tgt_peer_hash_find(soc, peer_mac, 0,
9718  						       vdev_id, DP_MOD_ID_CDP);
9719  
9720  	if (!peer)
9721  		return QDF_STATUS_E_FAILURE;
9722  
9723  	DP_STATS_CLR(peer);
9724  	dp_txrx_peer_stats_clr(peer->txrx_peer);
9725  
9726  	if (IS_MLO_DP_MLD_PEER(peer)) {
9727  		uint8_t i;
9728  		struct dp_peer *link_peer;
9729  		struct dp_soc *link_peer_soc;
9730  		struct dp_mld_link_peers link_peers_info;
9731  
9732  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
9733  						    &link_peers_info,
9734  						    DP_MOD_ID_CDP);
9735  		for (i = 0; i < link_peers_info.num_links; i++) {
9736  			link_peer = link_peers_info.link_peers[i];
9737  			link_peer_soc = link_peer->vdev->pdev->soc;
9738  
9739  			DP_STATS_CLR(link_peer);
9740  			dp_monitor_peer_reset_stats(link_peer_soc, link_peer);
9741  		}
9742  
9743  		dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
9744  	} else {
9745  		dp_monitor_peer_reset_stats(soc, peer);
9746  	}
9747  
9748  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
9749  
9750  	return status;
9751  }
9752  #else
9753  static QDF_STATUS
dp_txrx_reset_peer_stats(struct cdp_soc_t * soc,uint8_t vdev_id,uint8_t * peer_mac)9754  dp_txrx_reset_peer_stats(struct cdp_soc_t *soc, uint8_t vdev_id,
9755  			 uint8_t *peer_mac)
9756  {
9757  	QDF_STATUS status = QDF_STATUS_SUCCESS;
9758  	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
9759  						      peer_mac, 0, vdev_id,
9760  						      DP_MOD_ID_CDP);
9761  
9762  	if (!peer)
9763  		return QDF_STATUS_E_FAILURE;
9764  
9765  	DP_STATS_CLR(peer);
9766  	dp_txrx_peer_stats_clr(peer->txrx_peer);
9767  	dp_monitor_peer_reset_stats((struct dp_soc *)soc, peer);
9768  
9769  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
9770  
9771  	return status;
9772  }
9773  #endif
9774  
9775  /**
9776   * dp_txrx_get_vdev_stats() - Update buffer with cdp_vdev_stats
9777   * @soc_hdl: CDP SoC handle
9778   * @vdev_id: vdev Id
9779   * @buf: buffer for vdev stats
9780   * @is_aggregate: are aggregate stats being collected
9781   *
9782   * Return: QDF_STATUS
9783   */
9784  QDF_STATUS
dp_txrx_get_vdev_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,void * buf,bool is_aggregate)9785  dp_txrx_get_vdev_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
9786  		       void *buf, bool is_aggregate)
9787  {
9788  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
9789  	struct cdp_vdev_stats *vdev_stats;
9790  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
9791  						     DP_MOD_ID_CDP);
9792  
9793  	if (!vdev)
9794  		return QDF_STATUS_E_RESOURCES;
9795  
9796  	vdev_stats = (struct cdp_vdev_stats *)buf;
9797  
9798  	if (is_aggregate) {
9799  		dp_aggregate_vdev_stats(vdev, buf, DP_XMIT_LINK);
9800  	} else {
9801  		dp_copy_vdev_stats_to_tgt_buf(vdev_stats,
9802  						    &vdev->stats, DP_XMIT_LINK);
9803  	}
9804  
9805  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
9806  	return QDF_STATUS_SUCCESS;
9807  }
9808  
9809  /**
9810   * dp_get_total_per() - get total per
9811   * @soc: DP soc handle
9812   * @pdev_id: id of DP_PDEV handle
9813   *
9814   * Return: % error rate using retries per packet and success packets
9815   */
dp_get_total_per(struct cdp_soc_t * soc,uint8_t pdev_id)9816  static int dp_get_total_per(struct cdp_soc_t *soc, uint8_t pdev_id)
9817  {
9818  	struct dp_pdev *pdev =
9819  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
9820  						   pdev_id);
9821  
9822  	if (!pdev)
9823  		return 0;
9824  
9825  	dp_aggregate_pdev_stats(pdev);
9826  	if ((pdev->stats.tx.tx_success.num + pdev->stats.tx.retries) == 0)
9827  		return 0;
9828  	return qdf_do_div((pdev->stats.tx.retries * 100),
9829  		((pdev->stats.tx.tx_success.num) + (pdev->stats.tx.retries)));
9830  }
9831  
9832  /**
9833   * dp_txrx_stats_publish() - publish pdev stats into a buffer
9834   * @soc: DP soc handle
9835   * @pdev_id: id of DP_PDEV handle
9836   * @buf: to hold pdev_stats
9837   *
9838   * Return: int
9839   */
9840  static int
dp_txrx_stats_publish(struct cdp_soc_t * soc,uint8_t pdev_id,struct cdp_stats_extd * buf)9841  dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id,
9842  		      struct cdp_stats_extd *buf)
9843  {
9844  	struct cdp_txrx_stats_req req = {0,};
9845  	QDF_STATUS status;
9846  	struct dp_pdev *pdev =
9847  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
9848  						   pdev_id);
9849  
9850  	if (!pdev)
9851  		return TXRX_STATS_LEVEL_OFF;
9852  
9853  	if (pdev->pending_fw_stats_response) {
9854  		dp_warn("pdev%d: prev req pending\n", pdev->pdev_id);
9855  		return TXRX_STATS_LEVEL_OFF;
9856  	}
9857  
9858  	dp_aggregate_pdev_stats(pdev);
9859  
9860  	pdev->pending_fw_stats_response = true;
9861  	req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_TX;
9862  	req.cookie_val = DBG_STATS_COOKIE_DP_STATS;
9863  	pdev->fw_stats_tlv_bitmap_rcvd = 0;
9864  	qdf_event_reset(&pdev->fw_stats_event);
9865  	status = dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0,
9866  					   req.param1, req.param2, req.param3, 0,
9867  					   req.cookie_val, 0);
9868  
9869  	if (status != QDF_STATUS_SUCCESS) {
9870  		dp_warn("pdev%d: tx stats req failed\n", pdev->pdev_id);
9871  		pdev->pending_fw_stats_response = false;
9872  		return TXRX_STATS_LEVEL_OFF;
9873  	}
9874  
9875  	req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_RX;
9876  	req.cookie_val = DBG_STATS_COOKIE_DP_STATS;
9877  	status = dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0,
9878  					   req.param1, req.param2, req.param3, 0,
9879  					   req.cookie_val, 0);
9880  	if (status != QDF_STATUS_SUCCESS) {
9881  		dp_warn("pdev%d: rx stats req failed\n", pdev->pdev_id);
9882  		pdev->pending_fw_stats_response = false;
9883  		return TXRX_STATS_LEVEL_OFF;
9884  	}
9885  
9886  	/* The event may have already been signaled. Wait only if it's pending */
9887  	if (!pdev->fw_stats_event.done) {
9888  		status =
9889  			qdf_wait_single_event(&pdev->fw_stats_event,
9890  					      DP_MAX_SLEEP_TIME);
9891  
9892  		if (status != QDF_STATUS_SUCCESS) {
9893  			if (status == QDF_STATUS_E_TIMEOUT)
9894  				dp_warn("pdev%d: fw stats timeout. TLVs rcvd 0x%llx\n",
9895  					     pdev->pdev_id,
9896  					     pdev->fw_stats_tlv_bitmap_rcvd);
9897  			pdev->pending_fw_stats_response = false;
9898  			return TXRX_STATS_LEVEL_OFF;
9899  		}
9900  	}
9901  
9902  	qdf_mem_copy(buf, &pdev->stats, sizeof(struct cdp_pdev_stats));
9903  	pdev->pending_fw_stats_response = false;
9904  
9905  	return TXRX_STATS_LEVEL;
9906  }
9907  
9908  /**
9909   * dp_get_obss_stats() - Get Pdev OBSS stats from Fw
9910   * @soc: DP soc handle
9911   * @pdev_id: id of DP_PDEV handle
9912   * @buf: to hold pdev obss stats
9913   * @req: Pointer to CDP TxRx stats
9914   *
9915   * Return: status
9916   */
9917  static QDF_STATUS
dp_get_obss_stats(struct cdp_soc_t * soc,uint8_t pdev_id,struct cdp_pdev_obss_pd_stats_tlv * buf,struct cdp_txrx_stats_req * req)9918  dp_get_obss_stats(struct cdp_soc_t *soc, uint8_t pdev_id,
9919  		  struct cdp_pdev_obss_pd_stats_tlv *buf,
9920  		  struct cdp_txrx_stats_req *req)
9921  {
9922  	QDF_STATUS status;
9923  	struct dp_pdev *pdev =
9924  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
9925  						   pdev_id);
9926  
9927  	if (!pdev)
9928  		return QDF_STATUS_E_INVAL;
9929  
9930  	if (pdev->pending_fw_obss_stats_response)
9931  		return QDF_STATUS_E_AGAIN;
9932  
9933  	pdev->pending_fw_obss_stats_response = true;
9934  	req->stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS;
9935  	req->cookie_val = DBG_STATS_COOKIE_HTT_OBSS;
9936  	qdf_event_reset(&pdev->fw_obss_stats_event);
9937  	status = dp_h2t_ext_stats_msg_send(pdev, req->stats, req->param0,
9938  					   req->param1, req->param2,
9939  					   req->param3, 0, req->cookie_val,
9940  					   req->mac_id);
9941  	if (QDF_IS_STATUS_ERROR(status)) {
9942  		pdev->pending_fw_obss_stats_response = false;
9943  		return status;
9944  	}
9945  	status =
9946  		qdf_wait_single_event(&pdev->fw_obss_stats_event,
9947  				      DP_MAX_SLEEP_TIME);
9948  
9949  	if (status != QDF_STATUS_SUCCESS) {
9950  		if (status == QDF_STATUS_E_TIMEOUT)
9951  			qdf_debug("TIMEOUT_OCCURS");
9952  		pdev->pending_fw_obss_stats_response = false;
9953  		return QDF_STATUS_E_TIMEOUT;
9954  	}
9955  	qdf_mem_copy(buf, &pdev->stats.htt_tx_pdev_stats.obss_pd_stats_tlv,
9956  		     sizeof(struct cdp_pdev_obss_pd_stats_tlv));
9957  	pdev->pending_fw_obss_stats_response = false;
9958  	return status;
9959  }
9960  
9961  /**
9962   * dp_clear_pdev_obss_pd_stats() - Clear pdev obss stats
9963   * @soc: DP soc handle
9964   * @pdev_id: id of DP_PDEV handle
9965   * @req: Pointer to CDP TxRx stats request mac_id will be
9966   *	 pre-filled and should not be overwritten
9967   *
9968   * Return: status
9969   */
9970  static QDF_STATUS
dp_clear_pdev_obss_pd_stats(struct cdp_soc_t * soc,uint8_t pdev_id,struct cdp_txrx_stats_req * req)9971  dp_clear_pdev_obss_pd_stats(struct cdp_soc_t *soc, uint8_t pdev_id,
9972  			    struct cdp_txrx_stats_req *req)
9973  {
9974  	struct dp_pdev *pdev =
9975  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
9976  						   pdev_id);
9977  	uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT;
9978  
9979  	if (!pdev)
9980  		return QDF_STATUS_E_INVAL;
9981  
9982  	/*
9983  	 * For HTT_DBG_EXT_STATS_RESET command, FW need to config
9984  	 * from param0 to param3 according to below rule:
9985  	 *
9986  	 * PARAM:
9987  	 *   - config_param0 : start_offset (stats type)
9988  	 *   - config_param1 : stats bmask from start offset
9989  	 *   - config_param2 : stats bmask from start offset + 32
9990  	 *   - config_param3 : stats bmask from start offset + 64
9991  	 */
9992  	req->stats = (enum cdp_stats)HTT_DBG_EXT_STATS_RESET;
9993  	req->param0 = HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS;
9994  	req->param1 = 0x00000001;
9995  
9996  	return dp_h2t_ext_stats_msg_send(pdev, req->stats, req->param0,
9997  				  req->param1, req->param2, req->param3, 0,
9998  				cookie_val, req->mac_id);
9999  }
10000  
10001  /**
10002   * dp_set_pdev_dscp_tid_map_wifi3() - update dscp tid map in pdev
10003   * @soc_handle: soc handle
10004   * @pdev_id: id of DP_PDEV handle
10005   * @map_id: ID of map that needs to be updated
10006   * @tos: index value in map
10007   * @tid: tid value passed by the user
10008   *
10009   * Return: QDF_STATUS
10010   */
10011  static QDF_STATUS
dp_set_pdev_dscp_tid_map_wifi3(struct cdp_soc_t * soc_handle,uint8_t pdev_id,uint8_t map_id,uint8_t tos,uint8_t tid)10012  dp_set_pdev_dscp_tid_map_wifi3(struct cdp_soc_t *soc_handle,
10013  			       uint8_t pdev_id,
10014  			       uint8_t map_id,
10015  			       uint8_t tos, uint8_t tid)
10016  {
10017  	uint8_t dscp;
10018  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
10019  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
10020  
10021  	if (!pdev)
10022  		return QDF_STATUS_E_FAILURE;
10023  
10024  	dscp = (tos >> DP_IP_DSCP_SHIFT) & DP_IP_DSCP_MASK;
10025  	pdev->dscp_tid_map[map_id][dscp] = tid;
10026  
10027  	if (map_id < soc->num_hw_dscp_tid_map)
10028  		hal_tx_update_dscp_tid(soc->hal_soc, tid,
10029  				       map_id, dscp);
10030  	else
10031  		return QDF_STATUS_E_FAILURE;
10032  
10033  	return QDF_STATUS_SUCCESS;
10034  }
10035  
10036  #ifdef WLAN_SYSFS_DP_STATS
10037  /**
10038   * dp_sysfs_event_trigger() - Trigger event to wait for firmware
10039   * stats request response.
10040   * @soc: soc handle
10041   * @cookie_val: cookie value
10042   *
10043   * Return: QDF_STATUS
10044   */
10045  static QDF_STATUS
dp_sysfs_event_trigger(struct dp_soc * soc,uint32_t cookie_val)10046  dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val)
10047  {
10048  	QDF_STATUS status = QDF_STATUS_SUCCESS;
10049  	/* wait for firmware response for sysfs stats request */
10050  	if (cookie_val == DBG_SYSFS_STATS_COOKIE) {
10051  		if (!soc) {
10052  			dp_cdp_err("soc is NULL");
10053  			return QDF_STATUS_E_FAILURE;
10054  		}
10055  		/* wait for event completion */
10056  		status = qdf_wait_single_event(&soc->sysfs_config->sysfs_txrx_fw_request_done,
10057  					       WLAN_SYSFS_STAT_REQ_WAIT_MS);
10058  		if (status == QDF_STATUS_SUCCESS)
10059  			dp_cdp_info("sysfs_txrx_fw_request_done event completed");
10060  		else if (status == QDF_STATUS_E_TIMEOUT)
10061  			dp_cdp_warn("sysfs_txrx_fw_request_done event expired");
10062  		else
10063  			dp_cdp_warn("sysfs_txrx_fw_request_done event error code %d", status);
10064  	}
10065  
10066  	return status;
10067  }
10068  #else /* WLAN_SYSFS_DP_STATS */
10069  static QDF_STATUS
dp_sysfs_event_trigger(struct dp_soc * soc,uint32_t cookie_val)10070  dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val)
10071  {
10072  	return QDF_STATUS_SUCCESS;
10073  }
10074  #endif /* WLAN_SYSFS_DP_STATS */
10075  
10076  /**
10077   * dp_fw_stats_process() - Process TXRX FW stats request.
10078   * @vdev: DP VDEV handle
10079   * @req: stats request
10080   *
10081   * Return: QDF_STATUS
10082   */
10083  static QDF_STATUS
dp_fw_stats_process(struct dp_vdev * vdev,struct cdp_txrx_stats_req * req)10084  dp_fw_stats_process(struct dp_vdev *vdev,
10085  		    struct cdp_txrx_stats_req *req)
10086  {
10087  	struct dp_pdev *pdev = NULL;
10088  	struct dp_soc *soc = NULL;
10089  	uint32_t stats = req->stats;
10090  	uint8_t mac_id = req->mac_id;
10091  	uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT;
10092  
10093  	if (!vdev) {
10094  		DP_TRACE(NONE, "VDEV not found");
10095  		return QDF_STATUS_E_FAILURE;
10096  	}
10097  
10098  	pdev = vdev->pdev;
10099  	if (!pdev) {
10100  		DP_TRACE(NONE, "PDEV not found");
10101  		return QDF_STATUS_E_FAILURE;
10102  	}
10103  
10104  	soc = pdev->soc;
10105  	if (!soc) {
10106  		DP_TRACE(NONE, "soc not found");
10107  		return QDF_STATUS_E_FAILURE;
10108  	}
10109  
10110  	/* In case request is from host sysfs for displaying stats on console */
10111  	if (req->cookie_val == DBG_SYSFS_STATS_COOKIE)
10112  		cookie_val = DBG_SYSFS_STATS_COOKIE;
10113  
10114  	/*
10115  	 * For HTT_DBG_EXT_STATS_RESET command, FW need to config
10116  	 * from param0 to param3 according to below rule:
10117  	 *
10118  	 * PARAM:
10119  	 *   - config_param0 : start_offset (stats type)
10120  	 *   - config_param1 : stats bmask from start offset
10121  	 *   - config_param2 : stats bmask from start offset + 32
10122  	 *   - config_param3 : stats bmask from start offset + 64
10123  	 */
10124  	if (req->stats == CDP_TXRX_STATS_0) {
10125  		req->param0 = HTT_DBG_EXT_STATS_PDEV_TX;
10126  		req->param1 = 0xFFFFFFFF;
10127  		req->param2 = 0xFFFFFFFF;
10128  		req->param3 = 0xFFFFFFFF;
10129  	} else if (req->stats == (uint8_t)HTT_DBG_EXT_STATS_PDEV_TX_MU) {
10130  		req->param0 = HTT_DBG_EXT_STATS_SET_VDEV_MASK(vdev->vdev_id);
10131  	}
10132  
10133  	if (req->stats == (uint8_t)HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT) {
10134  		dp_h2t_ext_stats_msg_send(pdev,
10135  					  HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT,
10136  					  req->param0, req->param1, req->param2,
10137  					  req->param3, 0, cookie_val,
10138  					  mac_id);
10139  	} else {
10140  		dp_h2t_ext_stats_msg_send(pdev, stats, req->param0,
10141  					  req->param1, req->param2, req->param3,
10142  					  0, cookie_val, mac_id);
10143  	}
10144  
10145  	dp_sysfs_event_trigger(soc, cookie_val);
10146  
10147  	return QDF_STATUS_SUCCESS;
10148  }
10149  
10150  /**
10151   * dp_txrx_stats_request - function to map to firmware and host stats
10152   * @soc_handle: soc handle
10153   * @vdev_id: virtual device ID
10154   * @req: stats request
10155   *
10156   * Return: QDF_STATUS
10157   */
10158  static
dp_txrx_stats_request(struct cdp_soc_t * soc_handle,uint8_t vdev_id,struct cdp_txrx_stats_req * req)10159  QDF_STATUS dp_txrx_stats_request(struct cdp_soc_t *soc_handle,
10160  				 uint8_t vdev_id,
10161  				 struct cdp_txrx_stats_req *req)
10162  {
10163  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_handle);
10164  	int host_stats;
10165  	int fw_stats;
10166  	enum cdp_stats stats;
10167  	int num_stats;
10168  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
10169  						     DP_MOD_ID_CDP);
10170  	QDF_STATUS status = QDF_STATUS_E_INVAL;
10171  
10172  	if (!vdev || !req) {
10173  		dp_cdp_err("%pK: Invalid vdev/req instance", soc);
10174  		status = QDF_STATUS_E_INVAL;
10175  		goto fail0;
10176  	}
10177  
10178  	if (req->mac_id >= WLAN_CFG_MAC_PER_TARGET) {
10179  		dp_err("Invalid mac_id: %u request", req->mac_id);
10180  		status = QDF_STATUS_E_INVAL;
10181  		goto fail0;
10182  	}
10183  
10184  	stats = req->stats;
10185  	if (stats >= CDP_TXRX_MAX_STATS) {
10186  		status = QDF_STATUS_E_INVAL;
10187  		goto fail0;
10188  	}
10189  
10190  	/*
10191  	 * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available
10192  	 *			has to be updated if new FW HTT stats added
10193  	 */
10194  	if (stats > CDP_TXRX_STATS_HTT_MAX)
10195  		stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX;
10196  
10197  	num_stats  = QDF_ARRAY_SIZE(dp_stats_mapping_table);
10198  
10199  	if (stats >= num_stats) {
10200  		dp_cdp_err("%pK : Invalid stats option: %d", soc, stats);
10201  		status = QDF_STATUS_E_INVAL;
10202  		goto fail0;
10203  	}
10204  
10205  	req->stats = stats;
10206  	fw_stats = dp_stats_mapping_table[stats][STATS_FW];
10207  	host_stats = dp_stats_mapping_table[stats][STATS_HOST];
10208  
10209  	dp_info("stats: %u fw_stats_type: %d host_stats: %d",
10210  		stats, fw_stats, host_stats);
10211  
10212  	if (fw_stats != TXRX_FW_STATS_INVALID) {
10213  		/* update request with FW stats type */
10214  		req->stats = fw_stats;
10215  		status = dp_fw_stats_process(vdev, req);
10216  	} else if ((host_stats != TXRX_HOST_STATS_INVALID) &&
10217  			(host_stats <= TXRX_HOST_STATS_MAX))
10218  		status = dp_print_host_stats(vdev, req, soc);
10219  	else
10220  		dp_cdp_info("%pK: Wrong Input for TxRx Stats", soc);
10221  fail0:
10222  	if (vdev)
10223  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10224  	return status;
10225  }
10226  
10227  /**
10228   * dp_soc_notify_asserted_soc() - API to notify asserted soc info
10229   * @psoc: CDP soc handle
10230   *
10231   * Return: QDF_STATUS
10232   */
dp_soc_notify_asserted_soc(struct cdp_soc_t * psoc)10233  static QDF_STATUS dp_soc_notify_asserted_soc(struct cdp_soc_t *psoc)
10234  {
10235  	struct dp_soc *soc = (struct dp_soc *)psoc;
10236  
10237  	if (!soc) {
10238  		dp_cdp_err("%pK: soc is NULL", soc);
10239  		return QDF_STATUS_E_INVAL;
10240  	}
10241  
10242  	return dp_umac_reset_notify_asserted_soc(soc);
10243  }
10244  
10245  /**
10246   * dp_txrx_dump_stats() -  Dump statistics
10247   * @psoc: CDP soc handle
10248   * @value: Statistics option
10249   * @level: verbosity level
10250   */
dp_txrx_dump_stats(struct cdp_soc_t * psoc,uint16_t value,enum qdf_stats_verbosity_level level)10251  static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value,
10252  				     enum qdf_stats_verbosity_level level)
10253  {
10254  	struct dp_soc *soc =
10255  		(struct dp_soc *)psoc;
10256  	QDF_STATUS status = QDF_STATUS_SUCCESS;
10257  
10258  	if (!soc) {
10259  		dp_cdp_err("%pK: soc is NULL", soc);
10260  		return QDF_STATUS_E_INVAL;
10261  	}
10262  
10263  	switch (value) {
10264  	case CDP_TXRX_PATH_STATS:
10265  		dp_txrx_path_stats(soc);
10266  		dp_print_soc_interrupt_stats(soc);
10267  		dp_print_reg_write_stats(soc);
10268  		dp_pdev_print_tx_delay_stats(soc);
10269  		/* Dump usage watermark stats for core TX/RX SRNGs */
10270  		dp_dump_srng_high_wm_stats(soc,
10271  					   DP_SRNG_WM_MASK_REO_DST |
10272  					   DP_SRNG_WM_MASK_TX_COMP);
10273  		if (soc->cdp_soc.ol_ops->dp_print_fisa_stats)
10274  			soc->cdp_soc.ol_ops->dp_print_fisa_stats(
10275  						CDP_FISA_STATS_ID_ERR_STATS);
10276  		break;
10277  
10278  	case CDP_RX_RING_STATS:
10279  		dp_print_per_ring_stats(soc);
10280  		break;
10281  
10282  	case CDP_TXRX_TSO_STATS:
10283  		dp_print_tso_stats(soc, level);
10284  		break;
10285  
10286  	case CDP_DUMP_TX_FLOW_POOL_INFO:
10287  		if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH)
10288  			cdp_dump_flow_pool_info((struct cdp_soc_t *)soc);
10289  		else
10290  			dp_tx_dump_flow_pool_info_compact(soc);
10291  		break;
10292  
10293  	case CDP_DP_NAPI_STATS:
10294  		dp_print_napi_stats(soc);
10295  		break;
10296  
10297  	case CDP_TXRX_DESC_STATS:
10298  		/* TODO: NOT IMPLEMENTED */
10299  		break;
10300  
10301  	case CDP_DP_RX_FISA_STATS:
10302  		if (soc->cdp_soc.ol_ops->dp_print_fisa_stats)
10303  			soc->cdp_soc.ol_ops->dp_print_fisa_stats(
10304  						CDP_FISA_STATS_ID_DUMP_SW_FST);
10305  		break;
10306  
10307  	case CDP_DP_SWLM_STATS:
10308  		dp_print_swlm_stats(soc);
10309  		break;
10310  
10311  	case CDP_DP_TX_HW_LATENCY_STATS:
10312  		dp_pdev_print_tx_delay_stats(soc);
10313  		break;
10314  
10315  	default:
10316  		status = QDF_STATUS_E_INVAL;
10317  		break;
10318  	}
10319  
10320  	return status;
10321  
10322  }
10323  
10324  #ifdef WLAN_SYSFS_DP_STATS
10325  static
dp_sysfs_get_stat_type(struct dp_soc * soc,uint32_t * mac_id,uint32_t * stat_type)10326  void dp_sysfs_get_stat_type(struct dp_soc *soc, uint32_t *mac_id,
10327  			    uint32_t *stat_type)
10328  {
10329  	qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock);
10330  	*stat_type = soc->sysfs_config->stat_type_requested;
10331  	*mac_id   = soc->sysfs_config->mac_id;
10332  
10333  	qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock);
10334  }
10335  
10336  static
dp_sysfs_update_config_buf_params(struct dp_soc * soc,uint32_t curr_len,uint32_t max_buf_len,char * buf)10337  void dp_sysfs_update_config_buf_params(struct dp_soc *soc,
10338  				       uint32_t curr_len,
10339  				       uint32_t max_buf_len,
10340  				       char *buf)
10341  {
10342  	qdf_spinlock_acquire(&soc->sysfs_config->sysfs_write_user_buffer);
10343  	/* set sysfs_config parameters */
10344  	soc->sysfs_config->buf = buf;
10345  	soc->sysfs_config->curr_buffer_length = curr_len;
10346  	soc->sysfs_config->max_buffer_length = max_buf_len;
10347  	qdf_spinlock_release(&soc->sysfs_config->sysfs_write_user_buffer);
10348  }
10349  
10350  static
dp_sysfs_fill_stats(ol_txrx_soc_handle soc_hdl,char * buf,uint32_t buf_size)10351  QDF_STATUS dp_sysfs_fill_stats(ol_txrx_soc_handle soc_hdl,
10352  			       char *buf, uint32_t buf_size)
10353  {
10354  	uint32_t mac_id = 0;
10355  	uint32_t stat_type = 0;
10356  	uint32_t fw_stats = 0;
10357  	uint32_t host_stats = 0;
10358  	enum cdp_stats stats;
10359  	struct cdp_txrx_stats_req req;
10360  	uint32_t num_stats;
10361  	struct dp_soc *soc = NULL;
10362  
10363  	if (!soc_hdl) {
10364  		dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl);
10365  		return QDF_STATUS_E_INVAL;
10366  	}
10367  
10368  	soc = cdp_soc_t_to_dp_soc(soc_hdl);
10369  
10370  	if (!soc) {
10371  		dp_cdp_err("%pK: soc is NULL", soc);
10372  		return QDF_STATUS_E_INVAL;
10373  	}
10374  
10375  	dp_sysfs_get_stat_type(soc, &mac_id, &stat_type);
10376  
10377  	stats = stat_type;
10378  	if (stats >= CDP_TXRX_MAX_STATS) {
10379  		dp_cdp_info("sysfs stat type requested is invalid");
10380  		return QDF_STATUS_E_INVAL;
10381  	}
10382  	/*
10383  	 * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available
10384  	 *			has to be updated if new FW HTT stats added
10385  	 */
10386  	if (stats > CDP_TXRX_MAX_STATS)
10387  		stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX;
10388  
10389  	num_stats = QDF_ARRAY_SIZE(dp_stats_mapping_table);
10390  
10391  	if (stats >= num_stats) {
10392  		dp_cdp_err("%pK : Invalid stats option: %d, max num stats: %d",
10393  				soc, stats, num_stats);
10394  		return QDF_STATUS_E_INVAL;
10395  	}
10396  
10397  	/* build request */
10398  	fw_stats = dp_stats_mapping_table[stats][STATS_FW];
10399  	host_stats = dp_stats_mapping_table[stats][STATS_HOST];
10400  
10401  	req.stats = stat_type;
10402  	req.mac_id = mac_id;
10403  	/* request stats to be printed */
10404  	qdf_mutex_acquire(&soc->sysfs_config->sysfs_read_lock);
10405  
10406  	if (fw_stats != TXRX_FW_STATS_INVALID) {
10407  		/* update request with FW stats type */
10408  		req.cookie_val = DBG_SYSFS_STATS_COOKIE;
10409  	} else if ((host_stats != TXRX_HOST_STATS_INVALID) &&
10410  			(host_stats <= TXRX_HOST_STATS_MAX)) {
10411  		req.cookie_val = DBG_STATS_COOKIE_DEFAULT;
10412  		soc->sysfs_config->process_id = qdf_get_current_pid();
10413  		soc->sysfs_config->printing_mode = PRINTING_MODE_ENABLED;
10414  	}
10415  
10416  	dp_sysfs_update_config_buf_params(soc, 0, buf_size, buf);
10417  
10418  	dp_txrx_stats_request(soc_hdl, mac_id, &req);
10419  	soc->sysfs_config->process_id = 0;
10420  	soc->sysfs_config->printing_mode = PRINTING_MODE_DISABLED;
10421  
10422  	dp_sysfs_update_config_buf_params(soc, 0, 0, NULL);
10423  
10424  	qdf_mutex_release(&soc->sysfs_config->sysfs_read_lock);
10425  	return QDF_STATUS_SUCCESS;
10426  }
10427  
10428  static
dp_sysfs_set_stat_type(ol_txrx_soc_handle soc_hdl,uint32_t stat_type,uint32_t mac_id)10429  QDF_STATUS dp_sysfs_set_stat_type(ol_txrx_soc_handle soc_hdl,
10430  				  uint32_t stat_type, uint32_t mac_id)
10431  {
10432  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10433  
10434  	if (!soc_hdl) {
10435  		dp_cdp_err("%pK: soc is NULL", soc);
10436  		return QDF_STATUS_E_INVAL;
10437  	}
10438  
10439  	qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock);
10440  
10441  	soc->sysfs_config->stat_type_requested = stat_type;
10442  	soc->sysfs_config->mac_id = mac_id;
10443  
10444  	qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock);
10445  
10446  	return QDF_STATUS_SUCCESS;
10447  }
10448  
10449  static
dp_sysfs_initialize_stats(struct dp_soc * soc_hdl)10450  QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl)
10451  {
10452  	struct dp_soc *soc;
10453  	QDF_STATUS status;
10454  
10455  	if (!soc_hdl) {
10456  		dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl);
10457  		return QDF_STATUS_E_INVAL;
10458  	}
10459  
10460  	soc = soc_hdl;
10461  
10462  	soc->sysfs_config = qdf_mem_malloc(sizeof(struct sysfs_stats_config));
10463  	if (!soc->sysfs_config) {
10464  		dp_cdp_err("failed to allocate memory for sysfs_config no memory");
10465  		return QDF_STATUS_E_NOMEM;
10466  	}
10467  
10468  	status = qdf_event_create(&soc->sysfs_config->sysfs_txrx_fw_request_done);
10469  	/* create event for fw stats request from sysfs */
10470  	if (status != QDF_STATUS_SUCCESS) {
10471  		dp_cdp_err("failed to create event sysfs_txrx_fw_request_done");
10472  		qdf_mem_free(soc->sysfs_config);
10473  		soc->sysfs_config = NULL;
10474  		return QDF_STATUS_E_FAILURE;
10475  	}
10476  
10477  	qdf_spinlock_create(&soc->sysfs_config->rw_stats_lock);
10478  	qdf_mutex_create(&soc->sysfs_config->sysfs_read_lock);
10479  	qdf_spinlock_create(&soc->sysfs_config->sysfs_write_user_buffer);
10480  
10481  	return QDF_STATUS_SUCCESS;
10482  }
10483  
10484  static
dp_sysfs_deinitialize_stats(struct dp_soc * soc_hdl)10485  QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl)
10486  {
10487  	struct dp_soc *soc;
10488  	QDF_STATUS status;
10489  
10490  	if (!soc_hdl) {
10491  		dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl);
10492  		return QDF_STATUS_E_INVAL;
10493  	}
10494  
10495  	soc = soc_hdl;
10496  	if (!soc->sysfs_config) {
10497  		dp_cdp_err("soc->sysfs_config is NULL");
10498  		return QDF_STATUS_E_FAILURE;
10499  	}
10500  
10501  	status = qdf_event_destroy(&soc->sysfs_config->sysfs_txrx_fw_request_done);
10502  	if (status != QDF_STATUS_SUCCESS)
10503  		dp_cdp_err("Failed to destroy event sysfs_txrx_fw_request_done");
10504  
10505  	qdf_mutex_destroy(&soc->sysfs_config->sysfs_read_lock);
10506  	qdf_spinlock_destroy(&soc->sysfs_config->rw_stats_lock);
10507  	qdf_spinlock_destroy(&soc->sysfs_config->sysfs_write_user_buffer);
10508  
10509  	qdf_mem_free(soc->sysfs_config);
10510  
10511  	return QDF_STATUS_SUCCESS;
10512  }
10513  
10514  #else /* WLAN_SYSFS_DP_STATS */
10515  
10516  static
dp_sysfs_deinitialize_stats(struct dp_soc * soc_hdl)10517  QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl)
10518  {
10519  	return QDF_STATUS_SUCCESS;
10520  }
10521  
10522  static
dp_sysfs_initialize_stats(struct dp_soc * soc_hdl)10523  QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl)
10524  {
10525  	return QDF_STATUS_SUCCESS;
10526  }
10527  #endif /* WLAN_SYSFS_DP_STATS */
10528  
10529  /**
10530   * dp_txrx_clear_dump_stats() - clear dumpStats
10531   * @soc_hdl: soc handle
10532   * @pdev_id: pdev ID
10533   * @value: stats option
10534   *
10535   * Return: 0 - Success, non-zero - failure
10536   */
10537  static
dp_txrx_clear_dump_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t value)10538  QDF_STATUS dp_txrx_clear_dump_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
10539  				    uint8_t value)
10540  {
10541  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10542  	QDF_STATUS status = QDF_STATUS_SUCCESS;
10543  
10544  	if (!soc) {
10545  		dp_err("soc is NULL");
10546  		return QDF_STATUS_E_INVAL;
10547  	}
10548  
10549  	switch (value) {
10550  	case CDP_TXRX_TSO_STATS:
10551  		dp_txrx_clear_tso_stats(soc);
10552  		break;
10553  
10554  	case CDP_DP_TX_HW_LATENCY_STATS:
10555  		dp_pdev_clear_tx_delay_stats(soc);
10556  		break;
10557  
10558  	default:
10559  		status = QDF_STATUS_E_INVAL;
10560  		break;
10561  	}
10562  
10563  	return status;
10564  }
10565  
10566  static QDF_STATUS
dp_txrx_get_interface_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,void * buf,bool is_aggregate)10567  dp_txrx_get_interface_stats(struct cdp_soc_t *soc_hdl,
10568  			    uint8_t vdev_id,
10569  			    void *buf,
10570  			    bool is_aggregate)
10571  {
10572  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10573  
10574  	if (soc && soc->arch_ops.dp_get_interface_stats)
10575  		return soc->arch_ops.dp_get_interface_stats(soc_hdl,
10576  							    vdev_id,
10577  							    buf,
10578  							    is_aggregate);
10579  	return QDF_STATUS_E_FAILURE;
10580  }
10581  
10582  #ifdef QCA_LL_TX_FLOW_CONTROL_V2
10583  /**
10584   * dp_update_flow_control_parameters() - API to store datapath
10585   *                            config parameters
10586   * @soc: soc handle
10587   * @params: ini parameter handle
10588   *
10589   * Return: void
10590   */
10591  static inline
dp_update_flow_control_parameters(struct dp_soc * soc,struct cdp_config_params * params)10592  void dp_update_flow_control_parameters(struct dp_soc *soc,
10593  				struct cdp_config_params *params)
10594  {
10595  	soc->wlan_cfg_ctx->tx_flow_stop_queue_threshold =
10596  					params->tx_flow_stop_queue_threshold;
10597  	soc->wlan_cfg_ctx->tx_flow_start_queue_offset =
10598  					params->tx_flow_start_queue_offset;
10599  }
10600  #else
10601  static inline
dp_update_flow_control_parameters(struct dp_soc * soc,struct cdp_config_params * params)10602  void dp_update_flow_control_parameters(struct dp_soc *soc,
10603  				struct cdp_config_params *params)
10604  {
10605  }
10606  #endif
10607  
10608  #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
10609  /* Max packet limit for TX Comp packet loop (dp_tx_comp_handler) */
10610  #define DP_TX_COMP_LOOP_PKT_LIMIT_MAX 1024
10611  
10612  /* Max packet limit for RX REAP Loop (dp_rx_process) */
10613  #define DP_RX_REAP_LOOP_PKT_LIMIT_MAX 1024
10614  
10615  static
dp_update_rx_soft_irq_limit_params(struct dp_soc * soc,struct cdp_config_params * params)10616  void dp_update_rx_soft_irq_limit_params(struct dp_soc *soc,
10617  					struct cdp_config_params *params)
10618  {
10619  	soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit =
10620  				params->tx_comp_loop_pkt_limit;
10621  
10622  	if (params->tx_comp_loop_pkt_limit < DP_TX_COMP_LOOP_PKT_LIMIT_MAX)
10623  		soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check = true;
10624  	else
10625  		soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check = false;
10626  
10627  	soc->wlan_cfg_ctx->rx_reap_loop_pkt_limit =
10628  				params->rx_reap_loop_pkt_limit;
10629  
10630  	if (params->rx_reap_loop_pkt_limit < DP_RX_REAP_LOOP_PKT_LIMIT_MAX)
10631  		soc->wlan_cfg_ctx->rx_enable_eol_data_check = true;
10632  	else
10633  		soc->wlan_cfg_ctx->rx_enable_eol_data_check = false;
10634  
10635  	soc->wlan_cfg_ctx->rx_hp_oos_update_limit =
10636  				params->rx_hp_oos_update_limit;
10637  
10638  	dp_info("tx_comp_loop_pkt_limit %u tx_comp_enable_eol_data_check %u rx_reap_loop_pkt_limit %u rx_enable_eol_data_check %u rx_hp_oos_update_limit %u",
10639  		soc->wlan_cfg_ctx->tx_comp_loop_pkt_limit,
10640  		soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check,
10641  		soc->wlan_cfg_ctx->rx_reap_loop_pkt_limit,
10642  		soc->wlan_cfg_ctx->rx_enable_eol_data_check,
10643  		soc->wlan_cfg_ctx->rx_hp_oos_update_limit);
10644  }
10645  
10646  #else
10647  static inline
dp_update_rx_soft_irq_limit_params(struct dp_soc * soc,struct cdp_config_params * params)10648  void dp_update_rx_soft_irq_limit_params(struct dp_soc *soc,
10649  					struct cdp_config_params *params)
10650  { }
10651  
10652  #endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */
10653  
10654  /**
10655   * dp_update_config_parameters() - API to store datapath
10656   *                            config parameters
10657   * @psoc: soc handle
10658   * @params: ini parameter handle
10659   *
10660   * Return: status
10661   */
10662  static
dp_update_config_parameters(struct cdp_soc * psoc,struct cdp_config_params * params)10663  QDF_STATUS dp_update_config_parameters(struct cdp_soc *psoc,
10664  				struct cdp_config_params *params)
10665  {
10666  	struct dp_soc *soc = (struct dp_soc *)psoc;
10667  
10668  	if (!(soc)) {
10669  		dp_cdp_err("%pK: Invalid handle", soc);
10670  		return QDF_STATUS_E_INVAL;
10671  	}
10672  
10673  	soc->wlan_cfg_ctx->tso_enabled = params->tso_enable;
10674  	soc->wlan_cfg_ctx->lro_enabled = params->lro_enable;
10675  	soc->wlan_cfg_ctx->rx_hash = params->flow_steering_enable;
10676  	soc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload =
10677  				params->p2p_tcp_udp_checksumoffload;
10678  	soc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload =
10679  				params->nan_tcp_udp_checksumoffload;
10680  	soc->wlan_cfg_ctx->tcp_udp_checksumoffload =
10681  				params->tcp_udp_checksumoffload;
10682  	soc->wlan_cfg_ctx->napi_enabled = params->napi_enable;
10683  	soc->wlan_cfg_ctx->ipa_enabled = params->ipa_enable;
10684  	soc->wlan_cfg_ctx->gro_enabled = params->gro_enable;
10685  
10686  	dp_update_rx_soft_irq_limit_params(soc, params);
10687  	dp_update_flow_control_parameters(soc, params);
10688  
10689  	return QDF_STATUS_SUCCESS;
10690  }
10691  
10692  static struct cdp_wds_ops dp_ops_wds = {
10693  	.vdev_set_wds = dp_vdev_set_wds,
10694  #ifdef WDS_VENDOR_EXTENSION
10695  	.txrx_set_wds_rx_policy = dp_txrx_set_wds_rx_policy,
10696  	.txrx_wds_peer_tx_policy_update = dp_txrx_peer_wds_tx_policy_update,
10697  #endif
10698  };
10699  
10700  /**
10701   * dp_txrx_data_tx_cb_set() - set the callback for non standard tx
10702   * @soc_hdl: datapath soc handle
10703   * @vdev_id: virtual interface id
10704   * @callback: callback function
10705   * @ctxt: callback context
10706   *
10707   */
10708  static void
dp_txrx_data_tx_cb_set(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,ol_txrx_data_tx_cb callback,void * ctxt)10709  dp_txrx_data_tx_cb_set(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
10710  		       ol_txrx_data_tx_cb callback, void *ctxt)
10711  {
10712  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10713  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
10714  						     DP_MOD_ID_CDP);
10715  
10716  	if (!vdev)
10717  		return;
10718  
10719  	vdev->tx_non_std_data_callback.func = callback;
10720  	vdev->tx_non_std_data_callback.ctxt = ctxt;
10721  
10722  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10723  }
10724  
10725  /**
10726   * dp_pdev_get_dp_txrx_handle() - get dp handle from pdev
10727   * @soc: datapath soc handle
10728   * @pdev_id: id of datapath pdev handle
10729   *
10730   * Return: opaque pointer to dp txrx handle
10731   */
dp_pdev_get_dp_txrx_handle(struct cdp_soc_t * soc,uint8_t pdev_id)10732  static void *dp_pdev_get_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id)
10733  {
10734  	struct dp_pdev *pdev =
10735  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
10736  						   pdev_id);
10737  	if (qdf_unlikely(!pdev))
10738  		return NULL;
10739  
10740  	return pdev->dp_txrx_handle;
10741  }
10742  
10743  /**
10744   * dp_pdev_set_dp_txrx_handle() - set dp handle in pdev
10745   * @soc: datapath soc handle
10746   * @pdev_id: id of datapath pdev handle
10747   * @dp_txrx_hdl: opaque pointer for dp_txrx_handle
10748   *
10749   * Return: void
10750   */
10751  static void
dp_pdev_set_dp_txrx_handle(struct cdp_soc_t * soc,uint8_t pdev_id,void * dp_txrx_hdl)10752  dp_pdev_set_dp_txrx_handle(struct cdp_soc_t *soc, uint8_t pdev_id,
10753  			   void *dp_txrx_hdl)
10754  {
10755  	struct dp_pdev *pdev =
10756  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
10757  						   pdev_id);
10758  
10759  	if (!pdev)
10760  		return;
10761  
10762  	pdev->dp_txrx_handle = dp_txrx_hdl;
10763  }
10764  
10765  /**
10766   * dp_vdev_get_dp_ext_handle() - get dp handle from vdev
10767   * @soc_hdl: datapath soc handle
10768   * @vdev_id: vdev id
10769   *
10770   * Return: opaque pointer to dp txrx handle
10771   */
dp_vdev_get_dp_ext_handle(ol_txrx_soc_handle soc_hdl,uint8_t vdev_id)10772  static void *dp_vdev_get_dp_ext_handle(ol_txrx_soc_handle soc_hdl,
10773  				       uint8_t vdev_id)
10774  {
10775  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10776  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
10777  						     DP_MOD_ID_CDP);
10778  	void *dp_ext_handle;
10779  
10780  	if (!vdev)
10781  		return NULL;
10782  	dp_ext_handle = vdev->vdev_dp_ext_handle;
10783  
10784  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10785  	return dp_ext_handle;
10786  }
10787  
10788  /**
10789   * dp_vdev_set_dp_ext_handle() - set dp handle in vdev
10790   * @soc_hdl: datapath soc handle
10791   * @vdev_id: vdev id
10792   * @size: size of advance dp handle
10793   *
10794   * Return: QDF_STATUS
10795   */
10796  static QDF_STATUS
dp_vdev_set_dp_ext_handle(ol_txrx_soc_handle soc_hdl,uint8_t vdev_id,uint16_t size)10797  dp_vdev_set_dp_ext_handle(ol_txrx_soc_handle soc_hdl, uint8_t vdev_id,
10798  			  uint16_t size)
10799  {
10800  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10801  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
10802  						     DP_MOD_ID_CDP);
10803  	void *dp_ext_handle;
10804  
10805  	if (!vdev)
10806  		return QDF_STATUS_E_FAILURE;
10807  
10808  	dp_ext_handle = qdf_mem_malloc(size);
10809  
10810  	if (!dp_ext_handle) {
10811  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10812  		return QDF_STATUS_E_FAILURE;
10813  	}
10814  
10815  	vdev->vdev_dp_ext_handle = dp_ext_handle;
10816  
10817  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10818  	return QDF_STATUS_SUCCESS;
10819  }
10820  
10821  /**
10822   * dp_vdev_inform_ll_conn() - Inform vdev to add/delete a latency critical
10823   *			      connection for this vdev
10824   * @soc_hdl: CDP soc handle
10825   * @vdev_id: vdev ID
10826   * @action: Add/Delete action
10827   *
10828   * Return: QDF_STATUS.
10829   */
10830  static QDF_STATUS
dp_vdev_inform_ll_conn(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,enum vdev_ll_conn_actions action)10831  dp_vdev_inform_ll_conn(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
10832  		       enum vdev_ll_conn_actions action)
10833  {
10834  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10835  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
10836  						     DP_MOD_ID_CDP);
10837  
10838  	if (!vdev) {
10839  		dp_err("LL connection action for invalid vdev %d", vdev_id);
10840  		return QDF_STATUS_E_FAILURE;
10841  	}
10842  
10843  	switch (action) {
10844  	case CDP_VDEV_LL_CONN_ADD:
10845  		vdev->num_latency_critical_conn++;
10846  		break;
10847  
10848  	case CDP_VDEV_LL_CONN_DEL:
10849  		vdev->num_latency_critical_conn--;
10850  		break;
10851  
10852  	default:
10853  		dp_err("LL connection action invalid %d", action);
10854  		break;
10855  	}
10856  
10857  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
10858  	return QDF_STATUS_SUCCESS;
10859  }
10860  
10861  #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
10862  /**
10863   * dp_soc_set_swlm_enable() - Enable/Disable SWLM if initialized.
10864   * @soc_hdl: CDP Soc handle
10865   * @value: Enable/Disable value
10866   *
10867   * Return: QDF_STATUS
10868   */
dp_soc_set_swlm_enable(struct cdp_soc_t * soc_hdl,uint8_t value)10869  static QDF_STATUS dp_soc_set_swlm_enable(struct cdp_soc_t *soc_hdl,
10870  					 uint8_t value)
10871  {
10872  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10873  
10874  	if (!soc->swlm.is_init) {
10875  		dp_err("SWLM is not initialized");
10876  		return QDF_STATUS_E_FAILURE;
10877  	}
10878  
10879  	soc->swlm.is_enabled = !!value;
10880  
10881  	return QDF_STATUS_SUCCESS;
10882  }
10883  
10884  /**
10885   * dp_soc_is_swlm_enabled() - Check if SWLM is enabled.
10886   * @soc_hdl: CDP Soc handle
10887   *
10888   * Return: QDF_STATUS
10889   */
dp_soc_is_swlm_enabled(struct cdp_soc_t * soc_hdl)10890  static uint8_t dp_soc_is_swlm_enabled(struct cdp_soc_t *soc_hdl)
10891  {
10892  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
10893  
10894  	return soc->swlm.is_enabled;
10895  }
10896  #endif
10897  
10898  /**
10899   * dp_soc_get_dp_txrx_handle() - get context for external-dp from dp soc
10900   * @soc_handle: datapath soc handle
10901   *
10902   * Return: opaque pointer to external dp (non-core DP)
10903   */
dp_soc_get_dp_txrx_handle(struct cdp_soc * soc_handle)10904  static void *dp_soc_get_dp_txrx_handle(struct cdp_soc *soc_handle)
10905  {
10906  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
10907  
10908  	return soc->external_txrx_handle;
10909  }
10910  
10911  /**
10912   * dp_soc_set_dp_txrx_handle() - set external dp handle in soc
10913   * @soc_handle: datapath soc handle
10914   * @txrx_handle: opaque pointer to external dp (non-core DP)
10915   *
10916   * Return: void
10917   */
10918  static void
dp_soc_set_dp_txrx_handle(struct cdp_soc * soc_handle,void * txrx_handle)10919  dp_soc_set_dp_txrx_handle(struct cdp_soc *soc_handle, void *txrx_handle)
10920  {
10921  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
10922  
10923  	soc->external_txrx_handle = txrx_handle;
10924  }
10925  
10926  /**
10927   * dp_soc_map_pdev_to_lmac() - Save pdev_id to lmac_id mapping
10928   * @soc_hdl: datapath soc handle
10929   * @pdev_id: id of the datapath pdev handle
10930   * @lmac_id: lmac id
10931   *
10932   * Return: QDF_STATUS
10933   */
10934  static QDF_STATUS
dp_soc_map_pdev_to_lmac(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint32_t lmac_id)10935  dp_soc_map_pdev_to_lmac
10936  	(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
10937  	 uint32_t lmac_id)
10938  {
10939  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
10940  
10941  	wlan_cfg_set_hw_mac_idx(soc->wlan_cfg_ctx,
10942  				pdev_id,
10943  				lmac_id);
10944  
10945  	/*Set host PDEV ID for lmac_id*/
10946  	wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx,
10947  			      pdev_id,
10948  			      lmac_id);
10949  
10950  	return QDF_STATUS_SUCCESS;
10951  }
10952  
10953  /**
10954   * dp_soc_handle_pdev_mode_change() - Update pdev to lmac mapping
10955   * @soc_hdl: datapath soc handle
10956   * @pdev_id: id of the datapath pdev handle
10957   * @lmac_id: lmac id
10958   *
10959   * In the event of a dynamic mode change, update the pdev to lmac mapping
10960   *
10961   * Return: QDF_STATUS
10962   */
10963  static QDF_STATUS
dp_soc_handle_pdev_mode_change(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint32_t lmac_id)10964  dp_soc_handle_pdev_mode_change
10965  	(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
10966  	 uint32_t lmac_id)
10967  {
10968  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
10969  	struct dp_vdev *vdev = NULL;
10970  	uint8_t hw_pdev_id, mac_id;
10971  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc,
10972  								  pdev_id);
10973  	int nss_config = wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx);
10974  
10975  	if (qdf_unlikely(!pdev))
10976  		return QDF_STATUS_E_FAILURE;
10977  
10978  	pdev->lmac_id = lmac_id;
10979  	pdev->target_pdev_id =
10980  		dp_calculate_target_pdev_id_from_host_pdev_id(soc, pdev_id);
10981  	dp_info("mode change %d %d", pdev->pdev_id, pdev->lmac_id);
10982  
10983  	/*Set host PDEV ID for lmac_id*/
10984  	wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx,
10985  			      pdev->pdev_id,
10986  			      lmac_id);
10987  
10988  	hw_pdev_id =
10989  		dp_get_target_pdev_id_for_host_pdev_id(soc,
10990  						       pdev->pdev_id);
10991  
10992  	/*
10993  	 * When NSS offload is enabled, send pdev_id->lmac_id
10994  	 * and pdev_id to hw_pdev_id to NSS FW
10995  	 */
10996  	if (nss_config) {
10997  		mac_id = pdev->lmac_id;
10998  		if (soc->cdp_soc.ol_ops->pdev_update_lmac_n_target_pdev_id)
10999  			soc->cdp_soc.ol_ops->
11000  				pdev_update_lmac_n_target_pdev_id(
11001  				soc->ctrl_psoc,
11002  				&pdev_id, &mac_id, &hw_pdev_id);
11003  	}
11004  
11005  	qdf_spin_lock_bh(&pdev->vdev_list_lock);
11006  	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
11007  		DP_TX_TCL_METADATA_PDEV_ID_SET(vdev->htt_tcl_metadata,
11008  					       hw_pdev_id);
11009  		vdev->lmac_id = pdev->lmac_id;
11010  	}
11011  	qdf_spin_unlock_bh(&pdev->vdev_list_lock);
11012  
11013  	return QDF_STATUS_SUCCESS;
11014  }
11015  
11016  /**
11017   * dp_soc_set_pdev_status_down() - set pdev down/up status
11018   * @soc: datapath soc handle
11019   * @pdev_id: id of datapath pdev handle
11020   * @is_pdev_down: pdev down/up status
11021   *
11022   * Return: QDF_STATUS
11023   */
11024  static QDF_STATUS
dp_soc_set_pdev_status_down(struct cdp_soc_t * soc,uint8_t pdev_id,bool is_pdev_down)11025  dp_soc_set_pdev_status_down(struct cdp_soc_t *soc, uint8_t pdev_id,
11026  			    bool is_pdev_down)
11027  {
11028  	struct dp_pdev *pdev =
11029  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
11030  						   pdev_id);
11031  	if (!pdev)
11032  		return QDF_STATUS_E_FAILURE;
11033  
11034  	pdev->is_pdev_down = is_pdev_down;
11035  	return QDF_STATUS_SUCCESS;
11036  }
11037  
11038  /**
11039   * dp_get_cfg_capabilities() - get dp capabilities
11040   * @soc_handle: datapath soc handle
11041   * @dp_caps: enum for dp capabilities
11042   *
11043   * Return: bool to determine if dp caps is enabled
11044   */
11045  static bool
dp_get_cfg_capabilities(struct cdp_soc_t * soc_handle,enum cdp_capabilities dp_caps)11046  dp_get_cfg_capabilities(struct cdp_soc_t *soc_handle,
11047  			enum cdp_capabilities dp_caps)
11048  {
11049  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
11050  
11051  	return wlan_cfg_get_dp_caps(soc->wlan_cfg_ctx, dp_caps);
11052  }
11053  
11054  #ifdef FEATURE_AST
11055  static QDF_STATUS
dp_peer_teardown_wifi3(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * peer_mac)11056  dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
11057  		       uint8_t *peer_mac)
11058  {
11059  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11060  	QDF_STATUS status = QDF_STATUS_SUCCESS;
11061  	struct dp_peer *peer =
11062  			dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
11063  					       DP_MOD_ID_CDP);
11064  
11065  	/* Peer can be null for monitor vap mac address */
11066  	if (!peer) {
11067  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
11068  			  "%s: Invalid peer\n", __func__);
11069  		return QDF_STATUS_E_FAILURE;
11070  	}
11071  
11072  	dp_peer_update_state(soc, peer, DP_PEER_STATE_LOGICAL_DELETE);
11073  
11074  	qdf_spin_lock_bh(&soc->ast_lock);
11075  	dp_peer_send_wds_disconnect(soc, peer);
11076  	dp_peer_delete_ast_entries(soc, peer);
11077  	qdf_spin_unlock_bh(&soc->ast_lock);
11078  
11079  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
11080  	return status;
11081  }
11082  #endif
11083  
11084  #ifndef WLAN_SUPPORT_RX_TAG_STATISTICS
11085  /**
11086   * dp_dump_pdev_rx_protocol_tag_stats - dump the number of packets tagged for
11087   * given protocol type (RX_PROTOCOL_TAG_ALL indicates for all protocol)
11088   * @soc: cdp_soc handle
11089   * @pdev_id: id of cdp_pdev handle
11090   * @protocol_type: protocol type for which stats should be displayed
11091   *
11092   * Return: none
11093   */
11094  static inline void
dp_dump_pdev_rx_protocol_tag_stats(struct cdp_soc_t * soc,uint8_t pdev_id,uint16_t protocol_type)11095  dp_dump_pdev_rx_protocol_tag_stats(struct cdp_soc_t  *soc, uint8_t pdev_id,
11096  				   uint16_t protocol_type)
11097  {
11098  }
11099  #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */
11100  
11101  #ifndef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG
11102  /**
11103   * dp_update_pdev_rx_protocol_tag() - Add/remove a protocol tag that should be
11104   * applied to the desired protocol type packets
11105   * @soc: soc handle
11106   * @pdev_id: id of cdp_pdev handle
11107   * @enable_rx_protocol_tag: bitmask that indicates what protocol types
11108   * are enabled for tagging. zero indicates disable feature, non-zero indicates
11109   * enable feature
11110   * @protocol_type: new protocol type for which the tag is being added
11111   * @tag: user configured tag for the new protocol
11112   *
11113   * Return: Success
11114   */
11115  static inline QDF_STATUS
dp_update_pdev_rx_protocol_tag(struct cdp_soc_t * soc,uint8_t pdev_id,uint32_t enable_rx_protocol_tag,uint16_t protocol_type,uint16_t tag)11116  dp_update_pdev_rx_protocol_tag(struct cdp_soc_t  *soc, uint8_t pdev_id,
11117  			       uint32_t enable_rx_protocol_tag,
11118  			       uint16_t protocol_type,
11119  			       uint16_t tag)
11120  {
11121  	return QDF_STATUS_SUCCESS;
11122  }
11123  #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
11124  
11125  #ifndef WLAN_SUPPORT_RX_FLOW_TAG
11126  /**
11127   * dp_set_rx_flow_tag() - add/delete a flow
11128   * @cdp_soc: CDP soc handle
11129   * @pdev_id: id of cdp_pdev handle
11130   * @flow_info: flow tuple that is to be added to/deleted from flow search table
11131   *
11132   * Return: Success
11133   */
11134  static inline QDF_STATUS
dp_set_rx_flow_tag(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,struct cdp_rx_flow_info * flow_info)11135  dp_set_rx_flow_tag(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
11136  		   struct cdp_rx_flow_info *flow_info)
11137  {
11138  	return QDF_STATUS_SUCCESS;
11139  }
11140  /**
11141   * dp_dump_rx_flow_tag_stats() - dump the number of packets tagged for
11142   * given flow 5-tuple
11143   * @cdp_soc: soc handle
11144   * @pdev_id: id of cdp_pdev handle
11145   * @flow_info: flow 5-tuple for which stats should be displayed
11146   *
11147   * Return: Success
11148   */
11149  static inline QDF_STATUS
dp_dump_rx_flow_tag_stats(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,struct cdp_rx_flow_info * flow_info)11150  dp_dump_rx_flow_tag_stats(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
11151  			  struct cdp_rx_flow_info *flow_info)
11152  {
11153  	return QDF_STATUS_SUCCESS;
11154  }
11155  #endif /* WLAN_SUPPORT_RX_FLOW_TAG */
11156  
dp_peer_map_attach_wifi3(struct cdp_soc_t * soc_hdl,uint32_t max_peers,uint32_t max_ast_index,uint8_t peer_map_unmap_versions)11157  static QDF_STATUS dp_peer_map_attach_wifi3(struct cdp_soc_t  *soc_hdl,
11158  					   uint32_t max_peers,
11159  					   uint32_t max_ast_index,
11160  					   uint8_t peer_map_unmap_versions)
11161  {
11162  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11163  	QDF_STATUS status;
11164  
11165  	soc->max_peers = max_peers;
11166  
11167  	wlan_cfg_set_max_ast_idx(soc->wlan_cfg_ctx, max_ast_index);
11168  
11169  	status = soc->arch_ops.txrx_peer_map_attach(soc);
11170  	if (!QDF_IS_STATUS_SUCCESS(status)) {
11171  		dp_err("failure in allocating peer tables");
11172  		return QDF_STATUS_E_FAILURE;
11173  	}
11174  
11175  	dp_info("max_peers %u, calculated max_peers %u max_ast_index: %u",
11176  		max_peers, soc->max_peer_id, max_ast_index);
11177  
11178  	status = dp_peer_find_attach(soc);
11179  	if (!QDF_IS_STATUS_SUCCESS(status)) {
11180  		dp_err("Peer find attach failure");
11181  		goto fail;
11182  	}
11183  
11184  	soc->peer_map_unmap_versions = peer_map_unmap_versions;
11185  	soc->peer_map_attach_success = TRUE;
11186  
11187  	return QDF_STATUS_SUCCESS;
11188  fail:
11189  	soc->arch_ops.txrx_peer_map_detach(soc);
11190  
11191  	return status;
11192  }
11193  
dp_soc_set_param(struct cdp_soc_t * soc_hdl,enum cdp_soc_param_t param,uint32_t value)11194  static QDF_STATUS dp_soc_set_param(struct cdp_soc_t  *soc_hdl,
11195  				   enum cdp_soc_param_t param,
11196  				   uint32_t value)
11197  {
11198  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11199  
11200  	switch (param) {
11201  	case DP_SOC_PARAM_MSDU_EXCEPTION_DESC:
11202  		soc->num_msdu_exception_desc = value;
11203  		dp_info("num_msdu exception_desc %u",
11204  			value);
11205  		break;
11206  	case DP_SOC_PARAM_CMEM_FSE_SUPPORT:
11207  		if (wlan_cfg_is_fst_in_cmem_enabled(soc->wlan_cfg_ctx))
11208  			soc->fst_in_cmem = !!value;
11209  		dp_info("FW supports CMEM FSE %u", value);
11210  		break;
11211  	case DP_SOC_PARAM_MAX_AST_AGEOUT:
11212  		soc->max_ast_ageout_count = value;
11213  		dp_info("Max ast ageout count %u", soc->max_ast_ageout_count);
11214  		break;
11215  	case DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT:
11216  		soc->eapol_over_control_port = value;
11217  		dp_info("Eapol over control_port:%d",
11218  			soc->eapol_over_control_port);
11219  		break;
11220  	case DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT:
11221  		soc->multi_peer_grp_cmd_supported = value;
11222  		dp_info("Multi Peer group command support:%d",
11223  			soc->multi_peer_grp_cmd_supported);
11224  		break;
11225  	case DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT:
11226  		soc->features.rssi_dbm_conv_support = value;
11227  		dp_info("Rssi dbm conversion support:%u",
11228  			soc->features.rssi_dbm_conv_support);
11229  		break;
11230  	case DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT:
11231  		soc->features.umac_hw_reset_support = value;
11232  		dp_info("UMAC HW reset support :%u",
11233  			soc->features.umac_hw_reset_support);
11234  		break;
11235  	case DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT:
11236  		soc->features.multi_rx_reorder_q_setup_support = value;
11237  		dp_info("Multi rx reorder queue setup support: %u",
11238  			soc->features.multi_rx_reorder_q_setup_support);
11239  		break;
11240  	default:
11241  		dp_info("not handled param %d ", param);
11242  		break;
11243  	}
11244  
11245  	return QDF_STATUS_SUCCESS;
11246  }
11247  
dp_soc_set_rate_stats_ctx(struct cdp_soc_t * soc_handle,void * stats_ctx)11248  static void dp_soc_set_rate_stats_ctx(struct cdp_soc_t *soc_handle,
11249  				      void *stats_ctx)
11250  {
11251  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
11252  
11253  	soc->rate_stats_ctx = (struct cdp_soc_rate_stats_ctx *)stats_ctx;
11254  }
11255  
11256  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
11257  /**
11258   * dp_peer_flush_rate_stats_req() - Flush peer rate stats
11259   * @soc: Datapath SOC handle
11260   * @peer: Datapath peer
11261   * @arg: argument to iter function
11262   *
11263   * Return: QDF_STATUS
11264   */
11265  static void
dp_peer_flush_rate_stats_req(struct dp_soc * soc,struct dp_peer * peer,void * arg)11266  dp_peer_flush_rate_stats_req(struct dp_soc *soc, struct dp_peer *peer,
11267  			     void *arg)
11268  {
11269  	/* Skip self peer */
11270  	if (!qdf_mem_cmp(peer->mac_addr.raw, peer->vdev->mac_addr.raw,
11271  			 QDF_MAC_ADDR_SIZE))
11272  		return;
11273  
11274  	dp_wdi_event_handler(
11275  		WDI_EVENT_FLUSH_RATE_STATS_REQ,
11276  		soc, dp_monitor_peer_get_peerstats_ctx(soc, peer),
11277  		peer->peer_id,
11278  		WDI_NO_VAL, peer->vdev->pdev->pdev_id);
11279  }
11280  
11281  /**
11282   * dp_flush_rate_stats_req() - Flush peer rate stats in pdev
11283   * @soc_hdl: Datapath SOC handle
11284   * @pdev_id: pdev_id
11285   *
11286   * Return: QDF_STATUS
11287   */
dp_flush_rate_stats_req(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)11288  static QDF_STATUS dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl,
11289  					  uint8_t pdev_id)
11290  {
11291  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11292  	struct dp_pdev *pdev =
11293  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
11294  						   pdev_id);
11295  	if (!pdev)
11296  		return QDF_STATUS_E_FAILURE;
11297  
11298  	dp_pdev_iterate_peer(pdev, dp_peer_flush_rate_stats_req, NULL,
11299  			     DP_MOD_ID_CDP);
11300  
11301  	return QDF_STATUS_SUCCESS;
11302  }
11303  #else
11304  static inline QDF_STATUS
dp_flush_rate_stats_req(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)11305  dp_flush_rate_stats_req(struct cdp_soc_t *soc_hdl,
11306  			uint8_t pdev_id)
11307  {
11308  	return QDF_STATUS_SUCCESS;
11309  }
11310  #endif
11311  
11312  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
11313  #ifdef WLAN_FEATURE_11BE_MLO
11314  /**
11315   * dp_get_peer_extd_rate_link_stats() - function to get peer
11316   *				extended rate and link stats
11317   * @soc_hdl: dp soc handler
11318   * @mac_addr: mac address of peer
11319   *
11320   * Return: QDF_STATUS
11321   */
11322  static QDF_STATUS
dp_get_peer_extd_rate_link_stats(struct cdp_soc_t * soc_hdl,uint8_t * mac_addr)11323  dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr)
11324  {
11325  	uint8_t i;
11326  	struct dp_peer *link_peer;
11327  	struct dp_soc *link_peer_soc;
11328  	struct dp_mld_link_peers link_peers_info;
11329  	struct dp_peer *peer = NULL;
11330  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11331  	struct cdp_peer_info peer_info = { 0 };
11332  
11333  	if (!mac_addr) {
11334  		dp_err("NULL peer mac addr");
11335  		return QDF_STATUS_E_FAILURE;
11336  	}
11337  
11338  	DP_PEER_INFO_PARAMS_INIT(&peer_info, DP_VDEV_ALL, mac_addr, false,
11339  				 CDP_WILD_PEER_TYPE);
11340  
11341  	peer = dp_peer_hash_find_wrapper(soc, &peer_info, DP_MOD_ID_CDP);
11342  	if (!peer) {
11343  		dp_err("Peer is NULL");
11344  		return QDF_STATUS_E_FAILURE;
11345  	}
11346  
11347  	if (IS_MLO_DP_MLD_PEER(peer)) {
11348  		dp_get_link_peers_ref_from_mld_peer(soc, peer,
11349  						    &link_peers_info,
11350  						    DP_MOD_ID_CDP);
11351  		for (i = 0; i < link_peers_info.num_links; i++) {
11352  			link_peer = link_peers_info.link_peers[i];
11353  			link_peer_soc = link_peer->vdev->pdev->soc;
11354  			dp_wdi_event_handler(WDI_EVENT_FLUSH_RATE_STATS_REQ,
11355  					     link_peer_soc,
11356  					     dp_monitor_peer_get_peerstats_ctx
11357  					     (link_peer_soc, link_peer),
11358  					     link_peer->peer_id,
11359  					     WDI_NO_VAL,
11360  					     link_peer->vdev->pdev->pdev_id);
11361  		}
11362  		dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
11363  	} else {
11364  		dp_wdi_event_handler(
11365  				WDI_EVENT_FLUSH_RATE_STATS_REQ, soc,
11366  				dp_monitor_peer_get_peerstats_ctx(soc, peer),
11367  				peer->peer_id,
11368  				WDI_NO_VAL, peer->vdev->pdev->pdev_id);
11369  	}
11370  
11371  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
11372  	return QDF_STATUS_SUCCESS;
11373  }
11374  #else
11375  static QDF_STATUS
dp_get_peer_extd_rate_link_stats(struct cdp_soc_t * soc_hdl,uint8_t * mac_addr)11376  dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr)
11377  {
11378  	struct dp_peer *peer = NULL;
11379  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11380  
11381  	if (!mac_addr) {
11382  		dp_err("NULL peer mac addr");
11383  		return QDF_STATUS_E_FAILURE;
11384  	}
11385  
11386  	peer = dp_peer_find_hash_find(soc, mac_addr, 0,
11387  				      DP_VDEV_ALL, DP_MOD_ID_CDP);
11388  	if (!peer) {
11389  		dp_err("Peer is NULL");
11390  		return QDF_STATUS_E_FAILURE;
11391  	}
11392  
11393  	dp_wdi_event_handler(
11394  			WDI_EVENT_FLUSH_RATE_STATS_REQ, soc,
11395  			dp_monitor_peer_get_peerstats_ctx(soc, peer),
11396  			peer->peer_id,
11397  			WDI_NO_VAL, peer->vdev->pdev->pdev_id);
11398  
11399  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
11400  	return QDF_STATUS_SUCCESS;
11401  }
11402  #endif
11403  #else
11404  static inline QDF_STATUS
dp_get_peer_extd_rate_link_stats(struct cdp_soc_t * soc_hdl,uint8_t * mac_addr)11405  dp_get_peer_extd_rate_link_stats(struct cdp_soc_t *soc_hdl, uint8_t *mac_addr)
11406  {
11407  	return QDF_STATUS_SUCCESS;
11408  }
11409  #endif
11410  
dp_peer_get_peerstats_ctx(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mac_addr)11411  static void *dp_peer_get_peerstats_ctx(struct cdp_soc_t *soc_hdl,
11412  				       uint8_t vdev_id,
11413  				       uint8_t *mac_addr)
11414  {
11415  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
11416  	struct dp_peer *peer;
11417  	void *peerstats_ctx = NULL;
11418  
11419  	if (mac_addr) {
11420  		peer = dp_peer_find_hash_find(soc, mac_addr,
11421  					      0, vdev_id,
11422  					      DP_MOD_ID_CDP);
11423  		if (!peer)
11424  			return NULL;
11425  
11426  		if (!IS_MLO_DP_MLD_PEER(peer))
11427  			peerstats_ctx = dp_monitor_peer_get_peerstats_ctx(soc,
11428  									  peer);
11429  
11430  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
11431  	}
11432  
11433  	return peerstats_ctx;
11434  }
11435  
11436  #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
dp_peer_flush_rate_stats(struct cdp_soc_t * soc,uint8_t pdev_id,void * buf)11437  static QDF_STATUS dp_peer_flush_rate_stats(struct cdp_soc_t *soc,
11438  					   uint8_t pdev_id,
11439  					   void *buf)
11440  {
11441  	 dp_wdi_event_handler(WDI_EVENT_PEER_FLUSH_RATE_STATS,
11442  			      (struct dp_soc *)soc, buf, HTT_INVALID_PEER,
11443  			      WDI_NO_VAL, pdev_id);
11444  	return QDF_STATUS_SUCCESS;
11445  }
11446  #else
11447  static inline QDF_STATUS
dp_peer_flush_rate_stats(struct cdp_soc_t * soc,uint8_t pdev_id,void * buf)11448  dp_peer_flush_rate_stats(struct cdp_soc_t *soc,
11449  			 uint8_t pdev_id,
11450  			 void *buf)
11451  {
11452  	return QDF_STATUS_SUCCESS;
11453  }
11454  #endif
11455  
dp_soc_get_rate_stats_ctx(struct cdp_soc_t * soc_handle)11456  static void *dp_soc_get_rate_stats_ctx(struct cdp_soc_t *soc_handle)
11457  {
11458  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
11459  
11460  	return soc->rate_stats_ctx;
11461  }
11462  
11463  /**
11464   * dp_get_cfg() - get dp cfg
11465   * @soc: cdp soc handle
11466   * @cfg: cfg enum
11467   *
11468   * Return: cfg value
11469   */
dp_get_cfg(struct cdp_soc_t * soc,enum cdp_dp_cfg cfg)11470  static uint32_t dp_get_cfg(struct cdp_soc_t *soc, enum cdp_dp_cfg cfg)
11471  {
11472  	struct dp_soc *dpsoc = (struct dp_soc *)soc;
11473  	uint32_t value = 0;
11474  
11475  	switch (cfg) {
11476  	case cfg_dp_enable_data_stall:
11477  		value = dpsoc->wlan_cfg_ctx->enable_data_stall_detection;
11478  		break;
11479  	case cfg_dp_enable_p2p_ip_tcp_udp_checksum_offload:
11480  		value = dpsoc->wlan_cfg_ctx->p2p_tcp_udp_checksumoffload;
11481  		break;
11482  	case cfg_dp_enable_nan_ip_tcp_udp_checksum_offload:
11483  		value = dpsoc->wlan_cfg_ctx->nan_tcp_udp_checksumoffload;
11484  		break;
11485  	case cfg_dp_enable_ip_tcp_udp_checksum_offload:
11486  		value = dpsoc->wlan_cfg_ctx->tcp_udp_checksumoffload;
11487  		break;
11488  	case cfg_dp_disable_legacy_mode_csum_offload:
11489  		value = dpsoc->wlan_cfg_ctx->
11490  					legacy_mode_checksumoffload_disable;
11491  		break;
11492  	case cfg_dp_tso_enable:
11493  		value = dpsoc->wlan_cfg_ctx->tso_enabled;
11494  		break;
11495  	case cfg_dp_lro_enable:
11496  		value = dpsoc->wlan_cfg_ctx->lro_enabled;
11497  		break;
11498  	case cfg_dp_gro_enable:
11499  		value = dpsoc->wlan_cfg_ctx->gro_enabled;
11500  		break;
11501  	case cfg_dp_tc_based_dyn_gro_enable:
11502  		value = dpsoc->wlan_cfg_ctx->tc_based_dynamic_gro;
11503  		break;
11504  	case cfg_dp_tc_ingress_prio:
11505  		value = dpsoc->wlan_cfg_ctx->tc_ingress_prio;
11506  		break;
11507  	case cfg_dp_sg_enable:
11508  		value = dpsoc->wlan_cfg_ctx->sg_enabled;
11509  		break;
11510  	case cfg_dp_tx_flow_start_queue_offset:
11511  		value = dpsoc->wlan_cfg_ctx->tx_flow_start_queue_offset;
11512  		break;
11513  	case cfg_dp_tx_flow_stop_queue_threshold:
11514  		value = dpsoc->wlan_cfg_ctx->tx_flow_stop_queue_threshold;
11515  		break;
11516  	case cfg_dp_disable_intra_bss_fwd:
11517  		value = dpsoc->wlan_cfg_ctx->disable_intra_bss_fwd;
11518  		break;
11519  	case cfg_dp_pktlog_buffer_size:
11520  		value = dpsoc->wlan_cfg_ctx->pktlog_buffer_size;
11521  		break;
11522  	case cfg_dp_wow_check_rx_pending:
11523  		value = dpsoc->wlan_cfg_ctx->wow_check_rx_pending_enable;
11524  		break;
11525  	case cfg_dp_local_pkt_capture:
11526  		value = wlan_cfg_get_local_pkt_capture(dpsoc->wlan_cfg_ctx);
11527  		break;
11528  	default:
11529  		value =  0;
11530  	}
11531  
11532  	return value;
11533  }
11534  
11535  #ifdef PEER_FLOW_CONTROL
11536  /**
11537   * dp_tx_flow_ctrl_configure_pdev() - Configure flow control params
11538   * @soc_handle: datapath soc handle
11539   * @pdev_id: id of datapath pdev handle
11540   * @param: ol ath params
11541   * @value: value of the flag
11542   * @buff: Buffer to be passed
11543   *
11544   * Implemented this function same as legacy function. In legacy code, single
11545   * function is used to display stats and update pdev params.
11546   *
11547   * Return: 0 for success. nonzero for failure.
11548   */
dp_tx_flow_ctrl_configure_pdev(struct cdp_soc_t * soc_handle,uint8_t pdev_id,enum _dp_param_t param,uint32_t value,void * buff)11549  static uint32_t dp_tx_flow_ctrl_configure_pdev(struct cdp_soc_t *soc_handle,
11550  					       uint8_t pdev_id,
11551  					       enum _dp_param_t param,
11552  					       uint32_t value, void *buff)
11553  {
11554  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
11555  	struct dp_pdev *pdev =
11556  		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
11557  						   pdev_id);
11558  
11559  	if (qdf_unlikely(!pdev))
11560  		return 1;
11561  
11562  	soc = pdev->soc;
11563  	if (!soc)
11564  		return 1;
11565  
11566  	switch (param) {
11567  #ifdef QCA_ENH_V3_STATS_SUPPORT
11568  	case DP_PARAM_VIDEO_DELAY_STATS_FC:
11569  		if (value)
11570  			pdev->delay_stats_flag = true;
11571  		else
11572  			pdev->delay_stats_flag = false;
11573  		break;
11574  	case DP_PARAM_VIDEO_STATS_FC:
11575  		qdf_print("------- TID Stats ------\n");
11576  		dp_pdev_print_tid_stats(pdev);
11577  		qdf_print("------ Delay Stats ------\n");
11578  		dp_pdev_print_delay_stats(pdev);
11579  		qdf_print("------ Rx Error Stats ------\n");
11580  		dp_pdev_print_rx_error_stats(pdev);
11581  		break;
11582  #endif
11583  	case DP_PARAM_TOTAL_Q_SIZE:
11584  		{
11585  			uint32_t tx_min, tx_max;
11586  
11587  			tx_min = wlan_cfg_get_min_tx_desc(soc->wlan_cfg_ctx);
11588  			tx_max = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
11589  
11590  			if (!buff) {
11591  				if ((value >= tx_min) && (value <= tx_max)) {
11592  					pdev->num_tx_allowed = value;
11593  				} else {
11594  					dp_tx_info("%pK: Failed to update num_tx_allowed, Q_min = %d Q_max = %d",
11595  						   soc, tx_min, tx_max);
11596  					break;
11597  				}
11598  			} else {
11599  				*(int *)buff = pdev->num_tx_allowed;
11600  			}
11601  		}
11602  		break;
11603  	default:
11604  		dp_tx_info("%pK: not handled param %d ", soc, param);
11605  		break;
11606  	}
11607  
11608  	return 0;
11609  }
11610  #endif
11611  
11612  #ifdef DP_UMAC_HW_RESET_SUPPORT
11613  /**
11614   * dp_reset_interrupt_ring_masks() - Reset rx interrupt masks
11615   * @soc: dp soc handle
11616   *
11617   * Return: void
11618   */
dp_reset_interrupt_ring_masks(struct dp_soc * soc)11619  static void dp_reset_interrupt_ring_masks(struct dp_soc *soc)
11620  {
11621  	struct dp_intr_bkp *intr_bkp;
11622  	struct dp_intr *intr_ctx;
11623  	int num_ctxt = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx);
11624  	int i;
11625  
11626  	intr_bkp =
11627  	(struct dp_intr_bkp *)qdf_mem_malloc_atomic(sizeof(struct dp_intr_bkp) *
11628  			num_ctxt);
11629  
11630  	qdf_assert_always(intr_bkp);
11631  
11632  	soc->umac_reset_ctx.intr_ctx_bkp = intr_bkp;
11633  	for (i = 0; i < num_ctxt; i++) {
11634  		intr_ctx = &soc->intr_ctx[i];
11635  
11636  		intr_bkp->tx_ring_mask = intr_ctx->tx_ring_mask;
11637  		intr_bkp->rx_ring_mask = intr_ctx->rx_ring_mask;
11638  		intr_bkp->rx_mon_ring_mask = intr_ctx->rx_mon_ring_mask;
11639  		intr_bkp->rx_err_ring_mask = intr_ctx->rx_err_ring_mask;
11640  		intr_bkp->rx_wbm_rel_ring_mask = intr_ctx->rx_wbm_rel_ring_mask;
11641  		intr_bkp->reo_status_ring_mask = intr_ctx->reo_status_ring_mask;
11642  		intr_bkp->rxdma2host_ring_mask = intr_ctx->rxdma2host_ring_mask;
11643  		intr_bkp->host2rxdma_ring_mask = intr_ctx->host2rxdma_ring_mask;
11644  		intr_bkp->host2rxdma_mon_ring_mask =
11645  					intr_ctx->host2rxdma_mon_ring_mask;
11646  		intr_bkp->tx_mon_ring_mask = intr_ctx->tx_mon_ring_mask;
11647  
11648  		intr_ctx->tx_ring_mask = 0;
11649  		intr_ctx->rx_ring_mask = 0;
11650  		intr_ctx->rx_mon_ring_mask = 0;
11651  		intr_ctx->rx_err_ring_mask = 0;
11652  		intr_ctx->rx_wbm_rel_ring_mask = 0;
11653  		intr_ctx->reo_status_ring_mask = 0;
11654  		intr_ctx->rxdma2host_ring_mask = 0;
11655  		intr_ctx->host2rxdma_ring_mask = 0;
11656  		intr_ctx->host2rxdma_mon_ring_mask = 0;
11657  		intr_ctx->tx_mon_ring_mask = 0;
11658  
11659  		intr_bkp++;
11660  	}
11661  }
11662  
11663  /**
11664   * dp_restore_interrupt_ring_masks() - Restore rx interrupt masks
11665   * @soc: dp soc handle
11666   *
11667   * Return: void
11668   */
dp_restore_interrupt_ring_masks(struct dp_soc * soc)11669  static void dp_restore_interrupt_ring_masks(struct dp_soc *soc)
11670  {
11671  	struct dp_intr_bkp *intr_bkp = soc->umac_reset_ctx.intr_ctx_bkp;
11672  	struct dp_intr_bkp *intr_bkp_base = intr_bkp;
11673  	struct dp_intr *intr_ctx;
11674  	int num_ctxt = wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx);
11675  	int i;
11676  
11677  	if (!intr_bkp)
11678  		return;
11679  
11680  	for (i = 0; i < num_ctxt; i++) {
11681  		intr_ctx = &soc->intr_ctx[i];
11682  
11683  		intr_ctx->tx_ring_mask = intr_bkp->tx_ring_mask;
11684  		intr_ctx->rx_ring_mask = intr_bkp->rx_ring_mask;
11685  		intr_ctx->rx_mon_ring_mask = intr_bkp->rx_mon_ring_mask;
11686  		intr_ctx->rx_err_ring_mask = intr_bkp->rx_err_ring_mask;
11687  		intr_ctx->rx_wbm_rel_ring_mask = intr_bkp->rx_wbm_rel_ring_mask;
11688  		intr_ctx->reo_status_ring_mask = intr_bkp->reo_status_ring_mask;
11689  		intr_ctx->rxdma2host_ring_mask = intr_bkp->rxdma2host_ring_mask;
11690  		intr_ctx->host2rxdma_ring_mask = intr_bkp->host2rxdma_ring_mask;
11691  		intr_ctx->host2rxdma_mon_ring_mask =
11692  			intr_bkp->host2rxdma_mon_ring_mask;
11693  		intr_ctx->tx_mon_ring_mask = intr_bkp->tx_mon_ring_mask;
11694  
11695  		intr_bkp++;
11696  	}
11697  
11698  	qdf_mem_free(intr_bkp_base);
11699  	soc->umac_reset_ctx.intr_ctx_bkp = NULL;
11700  }
11701  
11702  /**
11703   * dp_resume_tx_hardstart() - Restore the old Tx hardstart functions
11704   * @soc: dp soc handle
11705   *
11706   * Return: void
11707   */
dp_resume_tx_hardstart(struct dp_soc * soc)11708  static void dp_resume_tx_hardstart(struct dp_soc *soc)
11709  {
11710  	struct dp_vdev *vdev;
11711  	struct ol_txrx_hardtart_ctxt ctxt = {0};
11712  	struct cdp_ctrl_objmgr_psoc *psoc = soc->ctrl_psoc;
11713  	int i;
11714  
11715  	for (i = 0; i < MAX_PDEV_CNT; i++) {
11716  		struct dp_pdev *pdev = soc->pdev_list[i];
11717  
11718  		if (!pdev)
11719  			continue;
11720  
11721  		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
11722  			uint8_t vdev_id = vdev->vdev_id;
11723  
11724  			dp_vdev_fetch_tx_handler(vdev, soc, &ctxt);
11725  			soc->cdp_soc.ol_ops->dp_update_tx_hardstart(psoc,
11726  								    vdev_id,
11727  								    &ctxt);
11728  		}
11729  	}
11730  }
11731  
11732  /**
11733   * dp_pause_tx_hardstart() - Register Tx hardstart functions to drop packets
11734   * @soc: dp soc handle
11735   *
11736   * Return: void
11737   */
dp_pause_tx_hardstart(struct dp_soc * soc)11738  static void dp_pause_tx_hardstart(struct dp_soc *soc)
11739  {
11740  	struct dp_vdev *vdev;
11741  	struct ol_txrx_hardtart_ctxt ctxt;
11742  	struct cdp_ctrl_objmgr_psoc *psoc = soc->ctrl_psoc;
11743  	int i;
11744  
11745  	ctxt.tx = &dp_tx_drop;
11746  	ctxt.tx_fast = &dp_tx_drop;
11747  	ctxt.tx_exception = &dp_tx_exc_drop;
11748  
11749  	for (i = 0; i < MAX_PDEV_CNT; i++) {
11750  		struct dp_pdev *pdev = soc->pdev_list[i];
11751  
11752  		if (!pdev)
11753  			continue;
11754  
11755  		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
11756  			uint8_t vdev_id = vdev->vdev_id;
11757  
11758  			soc->cdp_soc.ol_ops->dp_update_tx_hardstart(psoc,
11759  								    vdev_id,
11760  								    &ctxt);
11761  		}
11762  	}
11763  }
11764  
11765  /**
11766   * dp_unregister_notify_umac_pre_reset_fw_callback() - unregister notify_fw_cb
11767   * @soc: dp soc handle
11768   *
11769   * Return: void
11770   */
11771  static inline
dp_unregister_notify_umac_pre_reset_fw_callback(struct dp_soc * soc)11772  void dp_unregister_notify_umac_pre_reset_fw_callback(struct dp_soc *soc)
11773  {
11774  	soc->notify_fw_callback = NULL;
11775  }
11776  
11777  /**
11778   * dp_check_n_notify_umac_prereset_done() - Send pre reset done to firmware
11779   * @soc: dp soc handle
11780   *
11781   * Return: void
11782   */
11783  static inline
dp_check_n_notify_umac_prereset_done(struct dp_soc * soc)11784  void dp_check_n_notify_umac_prereset_done(struct dp_soc *soc)
11785  {
11786  	/* Some Cpu(s) is processing the umac rings*/
11787  	if (soc->service_rings_running)
11788  		return;
11789  
11790  	/* Unregister the callback */
11791  	dp_unregister_notify_umac_pre_reset_fw_callback(soc);
11792  
11793  	/* Check if notify was already sent by any other thread */
11794  	if (qdf_atomic_test_and_set_bit(DP_UMAC_RESET_NOTIFY_DONE,
11795  					&soc->service_rings_running))
11796  		return;
11797  
11798  	/* Notify the firmware that Umac pre reset is complete */
11799  	dp_umac_reset_notify_action_completion(soc,
11800  					       UMAC_RESET_ACTION_DO_PRE_RESET);
11801  }
11802  
11803  /**
11804   * dp_register_notify_umac_pre_reset_fw_callback() - register notify_fw_cb
11805   * @soc: dp soc handle
11806   *
11807   * Return: void
11808   */
11809  static inline
dp_register_notify_umac_pre_reset_fw_callback(struct dp_soc * soc)11810  void dp_register_notify_umac_pre_reset_fw_callback(struct dp_soc *soc)
11811  {
11812  	soc->notify_fw_callback = dp_check_n_notify_umac_prereset_done;
11813  }
11814  
11815  #ifdef DP_UMAC_HW_HARD_RESET
11816  /**
11817   * dp_set_umac_regs() - Reinitialize host umac registers
11818   * @soc: dp soc handle
11819   *
11820   * Return: void
11821   */
dp_set_umac_regs(struct dp_soc * soc)11822  static void dp_set_umac_regs(struct dp_soc *soc)
11823  {
11824  	int i;
11825  	struct hal_reo_params reo_params;
11826  
11827  	qdf_mem_zero(&reo_params, sizeof(reo_params));
11828  
11829  	if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) {
11830  		if (soc->arch_ops.reo_remap_config(soc, &reo_params.remap0,
11831  						   &reo_params.remap1,
11832  						   &reo_params.remap2))
11833  			reo_params.rx_hash_enabled = true;
11834  		else
11835  			reo_params.rx_hash_enabled = false;
11836  	}
11837  
11838  	reo_params.reo_qref = &soc->reo_qref;
11839  	hal_reo_setup(soc->hal_soc, &reo_params, 0);
11840  
11841  	soc->arch_ops.dp_cc_reg_cfg_init(soc, true);
11842  
11843  	for (i = 0; i < PCP_TID_MAP_MAX; i++)
11844  		hal_tx_update_pcp_tid_map(soc->hal_soc, soc->pcp_tid_map[i], i);
11845  
11846  	for (i = 0; i < MAX_PDEV_CNT; i++) {
11847  		struct dp_vdev *vdev = NULL;
11848  		struct dp_pdev *pdev = soc->pdev_list[i];
11849  
11850  		if (!pdev)
11851  			continue;
11852  
11853  		for (i = 0; i < soc->num_hw_dscp_tid_map; i++)
11854  			hal_tx_set_dscp_tid_map(soc->hal_soc,
11855  						pdev->dscp_tid_map[i], i);
11856  
11857  		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
11858  			soc->arch_ops.dp_bank_reconfig(soc, vdev);
11859  			soc->arch_ops.dp_reconfig_tx_vdev_mcast_ctrl(soc,
11860  								      vdev);
11861  		}
11862  	}
11863  }
11864  #else
dp_set_umac_regs(struct dp_soc * soc)11865  static void dp_set_umac_regs(struct dp_soc *soc)
11866  {
11867  }
11868  #endif
11869  
11870  /**
11871   * dp_reinit_rings() - Reinitialize host managed rings
11872   * @soc: dp soc handle
11873   *
11874   * Return: QDF_STATUS
11875   */
dp_reinit_rings(struct dp_soc * soc)11876  static void dp_reinit_rings(struct dp_soc *soc)
11877  {
11878  	unsigned long end;
11879  
11880  	dp_soc_srng_deinit(soc);
11881  	dp_hw_link_desc_ring_deinit(soc);
11882  
11883  	/* Busy wait for 2 ms to make sure the rings are in idle state
11884  	 * before we enable them again
11885  	 */
11886  	end = jiffies + msecs_to_jiffies(2);
11887  	while (time_before(jiffies, end))
11888  		;
11889  
11890  	dp_hw_link_desc_ring_init(soc);
11891  	dp_link_desc_ring_replenish(soc, WLAN_INVALID_PDEV_ID);
11892  	dp_soc_srng_init(soc);
11893  }
11894  
11895  /**
11896   * dp_umac_reset_action_trigger_recovery() - Handle FW Umac recovery trigger
11897   * @soc: dp soc handle
11898   *
11899   * Return: QDF_STATUS
11900   */
dp_umac_reset_action_trigger_recovery(struct dp_soc * soc)11901  static QDF_STATUS dp_umac_reset_action_trigger_recovery(struct dp_soc *soc)
11902  {
11903  	enum umac_reset_action action = UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY;
11904  
11905  	return dp_umac_reset_notify_action_completion(soc, action);
11906  }
11907  
11908  #ifdef WLAN_SUPPORT_PPEDS
11909  /**
11910   * dp_umac_reset_service_handle_n_notify_done()
11911   *	Handle Umac pre reset for direct switch
11912   * @soc: dp soc handle
11913   *
11914   * Return: QDF_STATUS
11915   */
dp_umac_reset_service_handle_n_notify_done(struct dp_soc * soc)11916  static QDF_STATUS dp_umac_reset_service_handle_n_notify_done(struct dp_soc *soc)
11917  {
11918  	if (!soc->arch_ops.txrx_soc_ppeds_enabled_check ||
11919  	    !soc->arch_ops.txrx_soc_ppeds_service_status_update ||
11920  	    !soc->arch_ops.txrx_soc_ppeds_interrupt_stop)
11921  		goto non_ppeds;
11922  
11923  	/*
11924  	 * Check if ppeds is enabled on SoC.
11925  	 */
11926  	if (!soc->arch_ops.txrx_soc_ppeds_enabled_check(soc))
11927  		goto non_ppeds;
11928  
11929  	/*
11930  	 * Start the UMAC pre reset done service.
11931  	 */
11932  	soc->arch_ops.txrx_soc_ppeds_service_status_update(soc, true);
11933  
11934  	dp_register_notify_umac_pre_reset_fw_callback(soc);
11935  
11936  	soc->arch_ops.txrx_soc_ppeds_interrupt_stop(soc);
11937  
11938  	dp_soc_ppeds_stop((struct cdp_soc_t *)soc);
11939  
11940  	/*
11941  	 * UMAC pre reset service complete
11942  	 */
11943  	soc->arch_ops.txrx_soc_ppeds_service_status_update(soc, false);
11944  
11945  	soc->umac_reset_ctx.nbuf_list = NULL;
11946  	return QDF_STATUS_SUCCESS;
11947  
11948  non_ppeds:
11949  	dp_register_notify_umac_pre_reset_fw_callback(soc);
11950  	dp_umac_reset_trigger_pre_reset_notify_cb(soc);
11951  	soc->umac_reset_ctx.nbuf_list = NULL;
11952  	return QDF_STATUS_SUCCESS;
11953  }
11954  
dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc * soc,qdf_nbuf_t * nbuf_list)11955  static inline void dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc *soc,
11956  							 qdf_nbuf_t *nbuf_list)
11957  {
11958  	if (!soc->arch_ops.txrx_soc_ppeds_enabled_check ||
11959  	    !soc->arch_ops.txrx_soc_ppeds_txdesc_pool_reset)
11960  		return;
11961  
11962  	/*
11963  	 * Deinit of PPEDS Tx desc rings.
11964  	 */
11965  	if (soc->arch_ops.txrx_soc_ppeds_enabled_check(soc))
11966  		soc->arch_ops.txrx_soc_ppeds_txdesc_pool_reset(soc, nbuf_list);
11967  }
11968  
dp_umac_reset_ppeds_start(struct dp_soc * soc)11969  static inline void dp_umac_reset_ppeds_start(struct dp_soc *soc)
11970  {
11971  	if (!soc->arch_ops.txrx_soc_ppeds_enabled_check ||
11972  	    !soc->arch_ops.txrx_soc_ppeds_start ||
11973  	    !soc->arch_ops.txrx_soc_ppeds_interrupt_start)
11974  		return;
11975  
11976  	/*
11977  	 * Start PPEDS node and enable interrupt.
11978  	 */
11979  	if (soc->arch_ops.txrx_soc_ppeds_enabled_check(soc)) {
11980  		soc->arch_ops.txrx_soc_ppeds_start(soc);
11981  		soc->arch_ops.txrx_soc_ppeds_interrupt_start(soc);
11982  	}
11983  }
11984  #else
dp_umac_reset_service_handle_n_notify_done(struct dp_soc * soc)11985  static QDF_STATUS dp_umac_reset_service_handle_n_notify_done(struct dp_soc *soc)
11986  {
11987  	dp_register_notify_umac_pre_reset_fw_callback(soc);
11988  	dp_umac_reset_trigger_pre_reset_notify_cb(soc);
11989  	soc->umac_reset_ctx.nbuf_list = NULL;
11990  	return QDF_STATUS_SUCCESS;
11991  }
11992  
dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc * soc,qdf_nbuf_t * nbuf_list)11993  static inline void dp_umac_reset_ppeds_txdesc_pool_reset(struct dp_soc *soc,
11994  							 qdf_nbuf_t *nbuf_list)
11995  {
11996  }
11997  
dp_umac_reset_ppeds_start(struct dp_soc * soc)11998  static inline void dp_umac_reset_ppeds_start(struct dp_soc *soc)
11999  {
12000  }
12001  #endif
12002  
12003  /**
12004   * dp_umac_reset_handle_pre_reset() - Handle Umac prereset interrupt from FW
12005   * @soc: dp soc handle
12006   *
12007   * Return: QDF_STATUS
12008   */
dp_umac_reset_handle_pre_reset(struct dp_soc * soc)12009  static QDF_STATUS dp_umac_reset_handle_pre_reset(struct dp_soc *soc)
12010  {
12011  	dp_reset_interrupt_ring_masks(soc);
12012  
12013  	dp_pause_tx_hardstart(soc);
12014  	dp_pause_reo_send_cmd(soc);
12015  	dp_umac_reset_service_handle_n_notify_done(soc);
12016  	return QDF_STATUS_SUCCESS;
12017  }
12018  
12019  /**
12020   * dp_umac_reset_handle_post_reset() - Handle Umac postreset interrupt from FW
12021   * @soc: dp soc handle
12022   *
12023   * Return: QDF_STATUS
12024   */
dp_umac_reset_handle_post_reset(struct dp_soc * soc)12025  static QDF_STATUS dp_umac_reset_handle_post_reset(struct dp_soc *soc)
12026  {
12027  	if (!soc->umac_reset_ctx.skel_enable) {
12028  		bool cleanup_needed;
12029  		qdf_nbuf_t *nbuf_list = &soc->umac_reset_ctx.nbuf_list;
12030  
12031  		dp_set_umac_regs(soc);
12032  
12033  		dp_reinit_rings(soc);
12034  
12035  		dp_rx_desc_reuse(soc, nbuf_list);
12036  
12037  		dp_cleanup_reo_cmd_module(soc);
12038  
12039  		dp_umac_reset_ppeds_txdesc_pool_reset(soc, nbuf_list);
12040  
12041  		cleanup_needed = dp_get_global_tx_desc_cleanup_flag(soc);
12042  
12043  		dp_tx_desc_pool_cleanup(soc, nbuf_list, cleanup_needed);
12044  
12045  		dp_reset_tid_q_setup(soc);
12046  	}
12047  
12048  	return dp_umac_reset_notify_action_completion(soc,
12049  					UMAC_RESET_ACTION_DO_POST_RESET_START);
12050  }
12051  
12052  /**
12053   * dp_umac_reset_handle_post_reset_complete() - Handle Umac postreset_complete
12054   *						interrupt from FW
12055   * @soc: dp soc handle
12056   *
12057   * Return: QDF_STATUS
12058   */
dp_umac_reset_handle_post_reset_complete(struct dp_soc * soc)12059  static QDF_STATUS dp_umac_reset_handle_post_reset_complete(struct dp_soc *soc)
12060  {
12061  	QDF_STATUS status;
12062  	qdf_nbuf_t nbuf_list = soc->umac_reset_ctx.nbuf_list;
12063  	uint8_t mac_id;
12064  
12065  	soc->umac_reset_ctx.nbuf_list = NULL;
12066  
12067  	soc->service_rings_running = 0;
12068  
12069  	dp_resume_reo_send_cmd(soc);
12070  
12071  	dp_umac_reset_ppeds_start(soc);
12072  
12073  	dp_restore_interrupt_ring_masks(soc);
12074  
12075  	dp_resume_tx_hardstart(soc);
12076  
12077  	dp_reset_global_tx_desc_cleanup_flag(soc);
12078  
12079  	status = dp_umac_reset_notify_action_completion(soc,
12080  				UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE);
12081  
12082  	while (nbuf_list) {
12083  		qdf_nbuf_t nbuf = nbuf_list->next;
12084  
12085  		qdf_nbuf_free(nbuf_list);
12086  		nbuf_list = nbuf;
12087  	}
12088  
12089  	/*
12090  	 * at pre-reset if in_use descriptors are not sufficient we replenish
12091  	 * only 1/3 of the ring. Try to replenish full ring here.
12092  	 */
12093  	for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) {
12094  		struct dp_srng *dp_rxdma_srng =
12095  					&soc->rx_refill_buf_ring[mac_id];
12096  		struct rx_desc_pool *rx_desc_pool = &soc->rx_desc_buf[mac_id];
12097  
12098  		dp_rx_buffers_lt_replenish_simple(soc, mac_id, dp_rxdma_srng,
12099  						  rx_desc_pool, true);
12100  	}
12101  
12102  	dp_umac_reset_info("Umac reset done on soc %pK\n trigger start : %u us "
12103  			   "trigger done : %u us prereset : %u us\n"
12104  			   "postreset : %u us \n postreset complete: %u us \n",
12105  			   soc,
12106  			   soc->umac_reset_ctx.ts.trigger_done -
12107  			   soc->umac_reset_ctx.ts.trigger_start,
12108  			   soc->umac_reset_ctx.ts.pre_reset_done -
12109  			   soc->umac_reset_ctx.ts.pre_reset_start,
12110  			   soc->umac_reset_ctx.ts.post_reset_done -
12111  			   soc->umac_reset_ctx.ts.post_reset_start,
12112  			   soc->umac_reset_ctx.ts.post_reset_complete_done -
12113  			   soc->umac_reset_ctx.ts.post_reset_complete_start);
12114  
12115  	return status;
12116  }
12117  #endif
12118  #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
12119  static void
dp_set_pkt_capture_mode(struct cdp_soc_t * soc_handle,bool val)12120  dp_set_pkt_capture_mode(struct cdp_soc_t *soc_handle, bool val)
12121  {
12122  	struct dp_soc *soc = (struct dp_soc *)soc_handle;
12123  
12124  	soc->wlan_cfg_ctx->pkt_capture_mode = val;
12125  }
12126  #endif
12127  
12128  #ifdef HW_TX_DELAY_STATS_ENABLE
12129  /**
12130   * dp_enable_disable_vdev_tx_delay_stats() - Start/Stop tx delay stats capture
12131   * @soc_hdl: DP soc handle
12132   * @vdev_id: vdev id
12133   * @value: value
12134   *
12135   * Return: None
12136   */
12137  static void
dp_enable_disable_vdev_tx_delay_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t value)12138  dp_enable_disable_vdev_tx_delay_stats(struct cdp_soc_t *soc_hdl,
12139  				      uint8_t vdev_id,
12140  				      uint8_t value)
12141  {
12142  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12143  	struct dp_vdev *vdev = NULL;
12144  
12145  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
12146  	if (!vdev)
12147  		return;
12148  
12149  	vdev->hw_tx_delay_stats_enabled = value;
12150  
12151  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
12152  }
12153  
12154  /**
12155   * dp_check_vdev_tx_delay_stats_enabled() - check the feature is enabled or not
12156   * @soc_hdl: DP soc handle
12157   * @vdev_id: vdev id
12158   *
12159   * Return: 1 if enabled, 0 if disabled
12160   */
12161  static uint8_t
dp_check_vdev_tx_delay_stats_enabled(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)12162  dp_check_vdev_tx_delay_stats_enabled(struct cdp_soc_t *soc_hdl,
12163  				     uint8_t vdev_id)
12164  {
12165  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12166  	struct dp_vdev *vdev;
12167  	uint8_t ret_val = 0;
12168  
12169  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
12170  	if (!vdev)
12171  		return ret_val;
12172  
12173  	ret_val = vdev->hw_tx_delay_stats_enabled;
12174  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
12175  
12176  	return ret_val;
12177  }
12178  #endif
12179  
12180  #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
12181  static void
dp_recovery_vdev_flush_peers(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,bool mlo_peers_only)12182  dp_recovery_vdev_flush_peers(struct cdp_soc_t *cdp_soc,
12183  			     uint8_t vdev_id,
12184  			     bool mlo_peers_only)
12185  {
12186  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
12187  	struct dp_vdev *vdev;
12188  
12189  	vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
12190  
12191  	if (!vdev)
12192  		return;
12193  
12194  	dp_vdev_flush_peers((struct cdp_vdev *)vdev, false, mlo_peers_only);
12195  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
12196  }
12197  #endif
12198  #ifdef QCA_GET_TSF_VIA_REG
12199  /**
12200   * dp_get_tsf_time() - get tsf time
12201   * @soc_hdl: Datapath soc handle
12202   * @tsf_id: TSF identifier
12203   * @mac_id: mac_id
12204   * @tsf: pointer to update tsf value
12205   * @tsf_sync_soc_time: pointer to update tsf sync time
12206   *
12207   * Return: None.
12208   */
12209  static inline void
dp_get_tsf_time(struct cdp_soc_t * soc_hdl,uint32_t tsf_id,uint32_t mac_id,uint64_t * tsf,uint64_t * tsf_sync_soc_time)12210  dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id,
12211  		uint64_t *tsf, uint64_t *tsf_sync_soc_time)
12212  {
12213  	hal_get_tsf_time(((struct dp_soc *)soc_hdl)->hal_soc, tsf_id, mac_id,
12214  			 tsf, tsf_sync_soc_time);
12215  }
12216  #else
12217  static inline void
dp_get_tsf_time(struct cdp_soc_t * soc_hdl,uint32_t tsf_id,uint32_t mac_id,uint64_t * tsf,uint64_t * tsf_sync_soc_time)12218  dp_get_tsf_time(struct cdp_soc_t *soc_hdl, uint32_t tsf_id, uint32_t mac_id,
12219  		uint64_t *tsf, uint64_t *tsf_sync_soc_time)
12220  {
12221  }
12222  #endif
12223  
12224  /**
12225   * dp_get_tsf2_scratch_reg() - get tsf2 offset from the scratch register
12226   * @soc_hdl: Datapath soc handle
12227   * @mac_id: mac_id
12228   * @value: pointer to update tsf2 offset value
12229   *
12230   * Return: None.
12231   */
12232  static inline void
dp_get_tsf2_scratch_reg(struct cdp_soc_t * soc_hdl,uint8_t mac_id,uint64_t * value)12233  dp_get_tsf2_scratch_reg(struct cdp_soc_t *soc_hdl, uint8_t mac_id,
12234  			uint64_t *value)
12235  {
12236  	hal_get_tsf2_offset(((struct dp_soc *)soc_hdl)->hal_soc, mac_id, value);
12237  }
12238  
12239  /**
12240   * dp_get_tqm_scratch_reg() - get tqm offset from the scratch register
12241   * @soc_hdl: Datapath soc handle
12242   * @value: pointer to update tqm offset value
12243   *
12244   * Return: None.
12245   */
12246  static inline void
dp_get_tqm_scratch_reg(struct cdp_soc_t * soc_hdl,uint64_t * value)12247  dp_get_tqm_scratch_reg(struct cdp_soc_t *soc_hdl, uint64_t *value)
12248  {
12249  	hal_get_tqm_offset(((struct dp_soc *)soc_hdl)->hal_soc, value);
12250  }
12251  
12252  /**
12253   * dp_set_tx_pause() - Pause or resume tx path
12254   * @soc_hdl: Datapath soc handle
12255   * @flag: set or clear is_tx_pause
12256   *
12257   * Return: None.
12258   */
12259  static inline
dp_set_tx_pause(struct cdp_soc_t * soc_hdl,bool flag)12260  void dp_set_tx_pause(struct cdp_soc_t *soc_hdl, bool flag)
12261  {
12262  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12263  
12264  	soc->is_tx_pause = flag;
12265  }
12266  
dp_rx_fisa_get_cmem_base(struct cdp_soc_t * soc_hdl,uint64_t size)12267  static inline uint64_t dp_rx_fisa_get_cmem_base(struct cdp_soc_t *soc_hdl,
12268  						uint64_t size)
12269  {
12270  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12271  
12272  	if (soc->arch_ops.dp_get_fst_cmem_base)
12273  		return soc->arch_ops.dp_get_fst_cmem_base(soc, size);
12274  
12275  	return 0;
12276  }
12277  
12278  #ifdef DP_TX_PACKET_INSPECT_FOR_ILP
12279  /**
12280   * dp_evaluate_update_tx_ilp_config() - Evaluate and update DP TX
12281   *                                      ILP configuration
12282   * @soc_hdl: CDP SOC handle
12283   * @num_msdu_idx_map: Number of HTT msdu index to qtype map in array
12284   * @msdu_idx_map_arr: Pointer to HTT msdu index to qtype map array
12285   *
12286   * This function will check: (a) TX ILP INI configuration,
12287   * (b) index 3 value in array same as HTT_MSDU_QTYPE_LATENCY_TOLERANT,
12288   * only if both (a) and (b) condition is met, then TX ILP feature is
12289   * considered to be enabled.
12290   *
12291   * Return: Final updated TX ILP enable result in dp_soc,
12292   *         true is enabled, false is not
12293   */
12294  static
dp_evaluate_update_tx_ilp_config(struct cdp_soc_t * soc_hdl,uint8_t num_msdu_idx_map,uint8_t * msdu_idx_map_arr)12295  bool dp_evaluate_update_tx_ilp_config(struct cdp_soc_t *soc_hdl,
12296  				      uint8_t num_msdu_idx_map,
12297  				      uint8_t *msdu_idx_map_arr)
12298  {
12299  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12300  	bool enable_tx_ilp = false;
12301  
12302  	/**
12303  	 * Check INI configuration firstly, if it's disabled,
12304  	 * then keep feature disabled.
12305  	 */
12306  	if (!wlan_cfg_get_tx_ilp_inspect_config(soc->wlan_cfg_ctx)) {
12307  		dp_info("TX ILP INI is disabled already");
12308  		goto update_tx_ilp;
12309  	}
12310  
12311  	/* Check if the msdu index to qtype map table is valid */
12312  	if (num_msdu_idx_map != HTT_MSDUQ_MAX_INDEX || !msdu_idx_map_arr) {
12313  		dp_info("Invalid msdu_idx qtype map num: 0x%x, arr_addr %pK",
12314  			num_msdu_idx_map, msdu_idx_map_arr);
12315  		goto update_tx_ilp;
12316  	}
12317  
12318  	dp_info("msdu_idx_map_arr idx 0x%x value 0x%x",
12319  		HTT_MSDUQ_INDEX_CUSTOM_PRIO_1,
12320  		msdu_idx_map_arr[HTT_MSDUQ_INDEX_CUSTOM_PRIO_1]);
12321  
12322  	if (HTT_MSDU_QTYPE_USER_SPECIFIED ==
12323  	    msdu_idx_map_arr[HTT_MSDUQ_INDEX_CUSTOM_PRIO_1])
12324  		enable_tx_ilp = true;
12325  
12326  update_tx_ilp:
12327  	soc->tx_ilp_enable = enable_tx_ilp;
12328  	dp_info("configure tx ilp enable %d", soc->tx_ilp_enable);
12329  
12330  	return soc->tx_ilp_enable;
12331  }
12332  #endif
12333  
12334  static struct cdp_cmn_ops dp_ops_cmn = {
12335  	.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
12336  	.txrx_vdev_attach = dp_vdev_attach_wifi3,
12337  	.txrx_vdev_detach = dp_vdev_detach_wifi3,
12338  	.txrx_pdev_attach = dp_pdev_attach_wifi3,
12339  	.txrx_pdev_post_attach = dp_pdev_post_attach_wifi3,
12340  	.txrx_pdev_detach = dp_pdev_detach_wifi3,
12341  	.txrx_pdev_deinit = dp_pdev_deinit_wifi3,
12342  	.txrx_peer_create = dp_peer_create_wifi3,
12343  	.txrx_peer_setup = dp_peer_setup_wifi3_wrapper,
12344  #ifdef FEATURE_AST
12345  	.txrx_peer_teardown = dp_peer_teardown_wifi3,
12346  #else
12347  	.txrx_peer_teardown = NULL,
12348  #endif
12349  	.txrx_peer_add_ast = dp_peer_add_ast_wifi3,
12350  	.txrx_peer_update_ast = dp_peer_update_ast_wifi3,
12351  	.txrx_peer_get_ast_info_by_soc = dp_peer_get_ast_info_by_soc_wifi3,
12352  	.txrx_peer_get_ast_info_by_pdev =
12353  		dp_peer_get_ast_info_by_pdevid_wifi3,
12354  	.txrx_peer_ast_delete_by_soc =
12355  		dp_peer_ast_entry_del_by_soc,
12356  	.txrx_peer_ast_delete_by_pdev =
12357  		dp_peer_ast_entry_del_by_pdev,
12358  	.txrx_peer_HMWDS_ast_delete = dp_peer_HMWDS_ast_entry_del,
12359  	.txrx_peer_delete = dp_peer_delete_wifi3,
12360  #ifdef DP_RX_UDP_OVER_PEER_ROAM
12361  	.txrx_update_roaming_peer = dp_update_roaming_peer_wifi3,
12362  #endif
12363  	.txrx_vdev_register = dp_vdev_register_wifi3,
12364  	.txrx_soc_detach = dp_soc_detach_wifi3,
12365  	.txrx_soc_deinit = dp_soc_deinit_wifi3,
12366  	.txrx_soc_init = dp_soc_init_wifi3,
12367  #ifndef QCA_HOST_MODE_WIFI_DISABLED
12368  	.txrx_tso_soc_attach = dp_tso_soc_attach,
12369  	.txrx_tso_soc_detach = dp_tso_soc_detach,
12370  	.tx_send = dp_tx_send,
12371  	.tx_send_exc = dp_tx_send_exception,
12372  #endif
12373  	.set_tx_pause = dp_set_tx_pause,
12374  	.txrx_pdev_init = dp_pdev_init_wifi3,
12375  	.txrx_get_vdev_mac_addr = dp_get_vdev_mac_addr_wifi3,
12376  	.txrx_get_ctrl_pdev_from_vdev = dp_get_ctrl_pdev_from_vdev_wifi3,
12377  	.txrx_ath_getstats = dp_get_device_stats,
12378  #ifndef WLAN_SOFTUMAC_SUPPORT
12379  	.addba_requestprocess = dp_addba_requestprocess_wifi3,
12380  	.addba_responsesetup = dp_addba_responsesetup_wifi3,
12381  	.addba_resp_tx_completion = dp_addba_resp_tx_completion_wifi3,
12382  	.delba_process = dp_delba_process_wifi3,
12383  	.set_addba_response = dp_set_addba_response,
12384  	.flush_cache_rx_queue = NULL,
12385  	.tid_update_ba_win_size = dp_rx_tid_update_ba_win_size,
12386  #endif
12387  	/* TODO: get API's for dscp-tid need to be added*/
12388  	.set_vdev_dscp_tid_map = dp_set_vdev_dscp_tid_map_wifi3,
12389  	.set_pdev_dscp_tid_map = dp_set_pdev_dscp_tid_map_wifi3,
12390  	.txrx_get_total_per = dp_get_total_per,
12391  	.txrx_stats_request = dp_txrx_stats_request,
12392  	.txrx_get_peer_mac_from_peer_id = dp_get_peer_mac_from_peer_id,
12393  	.display_stats = dp_txrx_dump_stats,
12394  	.notify_asserted_soc = dp_soc_notify_asserted_soc,
12395  	.txrx_intr_attach = dp_soc_interrupt_attach_wrapper,
12396  	.txrx_intr_detach = dp_soc_interrupt_detach_wrapper,
12397  	.txrx_ppeds_stop = dp_soc_ppeds_stop,
12398  	.set_key_sec_type = dp_set_key_sec_type_wifi3,
12399  	.update_config_parameters = dp_update_config_parameters,
12400  	/* TODO: Add other functions */
12401  	.txrx_data_tx_cb_set = dp_txrx_data_tx_cb_set,
12402  	.get_dp_txrx_handle = dp_pdev_get_dp_txrx_handle,
12403  	.set_dp_txrx_handle = dp_pdev_set_dp_txrx_handle,
12404  	.get_vdev_dp_ext_txrx_handle = dp_vdev_get_dp_ext_handle,
12405  	.set_vdev_dp_ext_txrx_handle = dp_vdev_set_dp_ext_handle,
12406  	.get_soc_dp_txrx_handle = dp_soc_get_dp_txrx_handle,
12407  	.set_soc_dp_txrx_handle = dp_soc_set_dp_txrx_handle,
12408  	.map_pdev_to_lmac = dp_soc_map_pdev_to_lmac,
12409  	.handle_mode_change = dp_soc_handle_pdev_mode_change,
12410  	.set_pdev_status_down = dp_soc_set_pdev_status_down,
12411  	.txrx_peer_reset_ast = dp_wds_reset_ast_wifi3,
12412  	.txrx_peer_reset_ast_table = dp_wds_reset_ast_table_wifi3,
12413  	.txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3,
12414  	.txrx_peer_map_attach = dp_peer_map_attach_wifi3,
12415  	.set_soc_param = dp_soc_set_param,
12416  	.txrx_get_os_rx_handles_from_vdev =
12417  					dp_get_os_rx_handles_from_vdev_wifi3,
12418  #ifndef WLAN_SOFTUMAC_SUPPORT
12419  	.set_pn_check = dp_set_pn_check_wifi3,
12420  	.txrx_set_ba_aging_timeout = dp_set_ba_aging_timeout,
12421  	.txrx_get_ba_aging_timeout = dp_get_ba_aging_timeout,
12422  	.delba_tx_completion = dp_delba_tx_completion_wifi3,
12423  	.set_pdev_pcp_tid_map = dp_set_pdev_pcp_tid_map_wifi3,
12424  	.set_vdev_pcp_tid_map = dp_set_vdev_pcp_tid_map_wifi3,
12425  #endif
12426  	.get_dp_capabilities = dp_get_cfg_capabilities,
12427  	.txrx_get_cfg = dp_get_cfg,
12428  	.set_rate_stats_ctx = dp_soc_set_rate_stats_ctx,
12429  	.get_rate_stats_ctx = dp_soc_get_rate_stats_ctx,
12430  	.txrx_peer_flush_rate_stats = dp_peer_flush_rate_stats,
12431  	.txrx_flush_rate_stats_request = dp_flush_rate_stats_req,
12432  	.txrx_peer_get_peerstats_ctx = dp_peer_get_peerstats_ctx,
12433  
12434  	.txrx_cp_peer_del_response = dp_cp_peer_del_resp_handler,
12435  #ifdef QCA_MULTIPASS_SUPPORT
12436  	.set_vlan_groupkey = dp_set_vlan_groupkey,
12437  #endif
12438  	.get_peer_mac_list = dp_get_peer_mac_list,
12439  	.get_peer_id = dp_get_peer_id,
12440  #ifdef QCA_SUPPORT_WDS_EXTENDED
12441  	.set_wds_ext_peer_rx = dp_wds_ext_set_peer_rx,
12442  	.get_wds_ext_peer_osif_handle = dp_wds_ext_get_peer_osif_handle,
12443  	.set_wds_ext_peer_bit = dp_wds_ext_set_peer_bit,
12444  #endif /* QCA_SUPPORT_WDS_EXTENDED */
12445  
12446  #if defined(FEATURE_RUNTIME_PM) || defined(DP_POWER_SAVE)
12447  	.txrx_drain = dp_drain_txrx,
12448  #endif
12449  #if defined(FEATURE_RUNTIME_PM)
12450  	.set_rtpm_tput_policy = dp_set_rtpm_tput_policy_requirement,
12451  #endif
12452  #ifdef WLAN_SYSFS_DP_STATS
12453  	.txrx_sysfs_fill_stats = dp_sysfs_fill_stats,
12454  	.txrx_sysfs_set_stat_type = dp_sysfs_set_stat_type,
12455  #endif /* WLAN_SYSFS_DP_STATS */
12456  #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
12457  	.set_pkt_capture_mode = dp_set_pkt_capture_mode,
12458  #endif
12459  #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
12460  	.txrx_recovery_vdev_flush_peers = dp_recovery_vdev_flush_peers,
12461  #endif
12462  	.txrx_umac_reset_deinit = dp_soc_umac_reset_deinit,
12463  	.txrx_umac_reset_init = dp_soc_umac_reset_init,
12464  	.txrx_get_tsf_time = dp_get_tsf_time,
12465  	.txrx_get_tsf2_offset = dp_get_tsf2_scratch_reg,
12466  	.txrx_get_tqm_offset = dp_get_tqm_scratch_reg,
12467  #ifdef WLAN_SUPPORT_RX_FISA
12468  	.get_fst_cmem_base = dp_rx_fisa_get_cmem_base,
12469  #endif
12470  #ifdef WLAN_SUPPORT_DPDK
12471  	.dpdk_get_ring_info = dp_dpdk_get_ring_info,
12472  	.cfgmgr_get_soc_info = dp_cfgmgr_get_soc_info,
12473  	.cfgmgr_get_vdev_info = dp_cfgmgr_get_vdev_info,
12474  	.cfgmgr_get_peer_info = dp_cfgmgr_get_peer_info,
12475  	.cfgmgr_get_vdev_create_evt_info = dp_cfgmgr_get_vdev_create_evt_info,
12476  	.cfgmgr_get_peer_create_evt_info = dp_cfgmgr_get_peer_create_evt_info,
12477  #endif
12478  };
12479  
12480  static struct cdp_ctrl_ops dp_ops_ctrl = {
12481  	.txrx_peer_authorize = dp_peer_authorize,
12482  	.txrx_peer_get_authorize = dp_peer_get_authorize,
12483  #ifdef VDEV_PEER_PROTOCOL_COUNT
12484  	.txrx_enable_peer_protocol_count = dp_enable_vdev_peer_protocol_count,
12485  	.txrx_set_peer_protocol_drop_mask =
12486  		dp_enable_vdev_peer_protocol_drop_mask,
12487  	.txrx_is_peer_protocol_count_enabled =
12488  		dp_is_vdev_peer_protocol_count_enabled,
12489  	.txrx_get_peer_protocol_drop_mask = dp_get_vdev_peer_protocol_drop_mask,
12490  #endif
12491  	.txrx_set_vdev_param = dp_set_vdev_param_wrapper,
12492  	.txrx_set_psoc_param = dp_set_psoc_param,
12493  	.txrx_get_psoc_param = dp_get_psoc_param,
12494  #ifndef WLAN_SOFTUMAC_SUPPORT
12495  	.txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest,
12496  	.txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest,
12497  #endif
12498  	.txrx_get_sec_type = dp_get_sec_type,
12499  	.txrx_wdi_event_sub = dp_wdi_event_sub,
12500  	.txrx_wdi_event_unsub = dp_wdi_event_unsub,
12501  	.txrx_set_pdev_param = dp_set_pdev_param,
12502  	.txrx_get_pdev_param = dp_get_pdev_param,
12503  #ifdef WLAN_FEATURE_11BE_MLO
12504  	.txrx_set_peer_param = dp_set_peer_param_wrapper,
12505  #else
12506  	.txrx_set_peer_param = dp_set_peer_param,
12507  #endif
12508  	.txrx_get_peer_param = dp_get_peer_param,
12509  #ifdef VDEV_PEER_PROTOCOL_COUNT
12510  	.txrx_peer_protocol_cnt = dp_peer_stats_update_protocol_cnt,
12511  #endif
12512  #ifdef WLAN_SUPPORT_MSCS
12513  	.txrx_record_mscs_params = dp_record_mscs_params,
12514  #endif
12515  	.set_key = dp_set_michael_key,
12516  	.txrx_get_vdev_param = dp_get_vdev_param,
12517  	.calculate_delay_stats = dp_calculate_delay_stats,
12518  #ifdef WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG
12519  	.txrx_update_pdev_rx_protocol_tag = dp_update_pdev_rx_protocol_tag,
12520  #ifdef WLAN_SUPPORT_RX_TAG_STATISTICS
12521  	.txrx_dump_pdev_rx_protocol_tag_stats =
12522  				dp_dump_pdev_rx_protocol_tag_stats,
12523  #endif /* WLAN_SUPPORT_RX_TAG_STATISTICS */
12524  #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
12525  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
12526  	.txrx_set_rx_flow_tag = dp_set_rx_flow_tag,
12527  	.txrx_dump_rx_flow_tag_stats = dp_dump_rx_flow_tag_stats,
12528  #endif /* WLAN_SUPPORT_RX_FLOW_TAG */
12529  #ifdef QCA_MULTIPASS_SUPPORT
12530  	.txrx_peer_set_vlan_id = dp_peer_set_vlan_id,
12531  #endif /*QCA_MULTIPASS_SUPPORT*/
12532  #if defined(WLAN_FEATURE_TSF_AUTO_REPORT) || defined(WLAN_CONFIG_TX_DELAY)
12533  	.txrx_set_delta_tsf = dp_set_delta_tsf,
12534  #endif
12535  #ifdef WLAN_FEATURE_TSF_UPLINK_DELAY
12536  	.txrx_set_tsf_ul_delay_report = dp_set_tsf_ul_delay_report,
12537  	.txrx_get_uplink_delay = dp_get_uplink_delay,
12538  #endif
12539  #ifdef QCA_UNDECODED_METADATA_SUPPORT
12540  	.txrx_set_pdev_phyrx_error_mask = dp_set_pdev_phyrx_error_mask,
12541  	.txrx_get_pdev_phyrx_error_mask = dp_get_pdev_phyrx_error_mask,
12542  #endif
12543  	.txrx_peer_flush_frags = dp_peer_flush_frags,
12544  #ifdef DP_UMAC_HW_RESET_SUPPORT
12545  	.get_umac_reset_in_progress_state = dp_get_umac_reset_in_progress_state,
12546  #endif
12547  #ifdef WLAN_SUPPORT_RX_FISA
12548  	.txrx_fisa_config = dp_fisa_config,
12549  #endif
12550  };
12551  
12552  static struct cdp_me_ops dp_ops_me = {
12553  #ifndef QCA_HOST_MODE_WIFI_DISABLED
12554  #ifdef ATH_SUPPORT_IQUE
12555  	.tx_me_alloc_descriptor = dp_tx_me_alloc_descriptor,
12556  	.tx_me_free_descriptor = dp_tx_me_free_descriptor,
12557  	.tx_me_convert_ucast = dp_tx_me_send_convert_ucast,
12558  #endif
12559  #endif
12560  };
12561  
12562  static struct cdp_host_stats_ops dp_ops_host_stats = {
12563  	.txrx_per_peer_stats = dp_get_host_peer_stats,
12564  	.get_fw_peer_stats = dp_get_fw_peer_stats,
12565  	.get_htt_stats = dp_get_htt_stats,
12566  	.txrx_stats_publish = dp_txrx_stats_publish,
12567  	.txrx_get_vdev_stats  = dp_txrx_get_vdev_stats,
12568  	.txrx_get_peer_stats = dp_txrx_get_peer_stats,
12569  	.txrx_get_peer_stats_based_on_peer_type =
12570  			dp_txrx_get_peer_stats_based_on_peer_type,
12571  	.txrx_get_soc_stats = dp_txrx_get_soc_stats,
12572  	.txrx_get_peer_stats_param = dp_txrx_get_peer_stats_param,
12573  	.txrx_get_per_link_stats = dp_txrx_get_per_link_peer_stats,
12574  	.txrx_reset_peer_stats = dp_txrx_reset_peer_stats,
12575  	.txrx_get_pdev_stats = dp_txrx_get_pdev_stats,
12576  #if defined(IPA_OFFLOAD) && defined(QCA_ENHANCED_STATS_SUPPORT)
12577  	.txrx_get_peer_stats = dp_ipa_txrx_get_peer_stats,
12578  	.txrx_get_vdev_stats  = dp_ipa_txrx_get_vdev_stats,
12579  	.txrx_get_pdev_stats = dp_ipa_txrx_get_pdev_stats,
12580  #endif
12581  	.txrx_get_ratekbps = dp_txrx_get_ratekbps,
12582  	.txrx_update_vdev_stats = dp_txrx_update_vdev_host_stats,
12583  	.txrx_get_peer_delay_stats = dp_txrx_get_peer_delay_stats,
12584  	.txrx_get_peer_jitter_stats = dp_txrx_get_peer_jitter_stats,
12585  #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
12586  	.txrx_alloc_vdev_stats_id = dp_txrx_alloc_vdev_stats_id,
12587  	.txrx_reset_vdev_stats_id = dp_txrx_reset_vdev_stats_id,
12588  #endif
12589  #ifdef WLAN_TX_PKT_CAPTURE_ENH
12590  	.get_peer_tx_capture_stats = dp_peer_get_tx_capture_stats,
12591  	.get_pdev_tx_capture_stats = dp_pdev_get_tx_capture_stats,
12592  #endif /* WLAN_TX_PKT_CAPTURE_ENH */
12593  #ifdef HW_TX_DELAY_STATS_ENABLE
12594  	.enable_disable_vdev_tx_delay_stats =
12595  				dp_enable_disable_vdev_tx_delay_stats,
12596  	.is_tx_delay_stats_enabled = dp_check_vdev_tx_delay_stats_enabled,
12597  #endif
12598  	.txrx_get_pdev_tid_stats = dp_pdev_get_tid_stats,
12599  #ifdef WLAN_CONFIG_TELEMETRY_AGENT
12600  	.txrx_pdev_telemetry_stats = dp_get_pdev_telemetry_stats,
12601  	.txrx_peer_telemetry_stats = dp_get_peer_telemetry_stats,
12602  	.txrx_pdev_deter_stats = dp_get_pdev_deter_stats,
12603  	.txrx_peer_deter_stats = dp_get_peer_deter_stats,
12604  	.txrx_update_pdev_chan_util_stats = dp_update_pdev_chan_util_stats,
12605  #endif
12606  	.txrx_get_peer_extd_rate_link_stats =
12607  					dp_get_peer_extd_rate_link_stats,
12608  	.get_pdev_obss_stats = dp_get_obss_stats,
12609  	.clear_pdev_obss_pd_stats = dp_clear_pdev_obss_pd_stats,
12610  	.txrx_get_interface_stats  = dp_txrx_get_interface_stats,
12611  #ifdef WLAN_FEATURE_TX_LATENCY_STATS
12612  	.tx_latency_stats_fetch = dp_tx_latency_stats_fetch,
12613  	.tx_latency_stats_config = dp_tx_latency_stats_config,
12614  	.tx_latency_stats_register_cb = dp_tx_latency_stats_register_cb,
12615  #endif
12616  	/* TODO */
12617  };
12618  
12619  static struct cdp_raw_ops dp_ops_raw = {
12620  	/* TODO */
12621  };
12622  
12623  #ifdef PEER_FLOW_CONTROL
12624  static struct cdp_pflow_ops dp_ops_pflow = {
12625  	dp_tx_flow_ctrl_configure_pdev,
12626  };
12627  #endif
12628  
12629  #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
12630  static struct cdp_cfr_ops dp_ops_cfr = {
12631  	.txrx_get_cfr_rcc = dp_get_cfr_rcc,
12632  	.txrx_set_cfr_rcc = dp_set_cfr_rcc,
12633  	.txrx_get_cfr_dbg_stats = dp_get_cfr_dbg_stats,
12634  	.txrx_clear_cfr_dbg_stats = dp_clear_cfr_dbg_stats,
12635  };
12636  #endif
12637  
12638  #ifdef WLAN_SUPPORT_MSCS
12639  static struct cdp_mscs_ops dp_ops_mscs = {
12640  	.mscs_peer_lookup_n_get_priority = dp_mscs_peer_lookup_n_get_priority,
12641  };
12642  #endif
12643  
12644  #ifdef WLAN_SUPPORT_MESH_LATENCY
12645  static struct cdp_mesh_latency_ops dp_ops_mesh_latency = {
12646  	.mesh_latency_update_peer_parameter =
12647  		dp_mesh_latency_update_peer_parameter,
12648  };
12649  #endif
12650  
12651  #ifdef WLAN_SUPPORT_SCS
12652  static struct cdp_scs_ops dp_ops_scs = {
12653  	.scs_peer_lookup_n_rule_match = dp_scs_peer_lookup_n_rule_match,
12654  };
12655  #endif
12656  
12657  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
12658  static struct cdp_fse_ops dp_ops_fse = {
12659  	.fse_rule_add = dp_rx_sfe_add_flow_entry,
12660  	.fse_rule_delete = dp_rx_sfe_delete_flow_entry,
12661  };
12662  #endif
12663  
12664  #ifdef CONFIG_SAWF_DEF_QUEUES
12665  static struct cdp_sawf_ops dp_ops_sawf = {
12666  	.sawf_def_queues_map_req = dp_sawf_def_queues_map_req,
12667  	.sawf_def_queues_unmap_req = dp_sawf_def_queues_unmap_req,
12668  	.sawf_def_queues_get_map_report =
12669  		dp_sawf_def_queues_get_map_report,
12670  #ifdef CONFIG_SAWF_STATS
12671  	.sawf_get_peer_msduq_info = dp_sawf_get_peer_msduq_info,
12672  	.txrx_get_peer_sawf_delay_stats = dp_sawf_get_peer_delay_stats,
12673  	.txrx_get_peer_sawf_tx_stats = dp_sawf_get_peer_tx_stats,
12674  	.sawf_mpdu_stats_req = dp_sawf_mpdu_stats_req,
12675  	.sawf_mpdu_details_stats_req = dp_sawf_mpdu_details_stats_req,
12676  	.txrx_sawf_set_mov_avg_params = dp_sawf_set_mov_avg_params,
12677  	.txrx_sawf_set_sla_params = dp_sawf_set_sla_params,
12678  	.txrx_sawf_init_telemtery_params = dp_sawf_init_telemetry_params,
12679  	.telemetry_get_throughput_stats = dp_sawf_get_tx_stats,
12680  	.telemetry_get_mpdu_stats = dp_sawf_get_mpdu_sched_stats,
12681  	.telemetry_get_drop_stats = dp_sawf_get_drop_stats,
12682  	.peer_config_ul = dp_sawf_peer_config_ul,
12683  	.swaf_peer_sla_configuration = dp_swaf_peer_sla_configuration,
12684  	.sawf_peer_flow_count = dp_sawf_peer_flow_count,
12685  #endif
12686  #ifdef WLAN_FEATURE_11BE_MLO_3_LINK_TX
12687  	.get_peer_msduq = dp_sawf_get_peer_msduq,
12688  	.sawf_3_link_peer_flow_count = dp_sawf_3_link_peer_flow_count,
12689  #endif
12690  };
12691  #endif
12692  
12693  #ifdef DP_TX_TRACKING
12694  
12695  #define DP_TX_COMP_MAX_LATENCY_MS 60000
12696  
dp_check_pending_tx(struct dp_soc * soc)12697  static bool dp_check_pending_tx(struct dp_soc *soc)
12698  {
12699  	hal_soc_handle_t hal_soc = soc->hal_soc;
12700  	uint32_t hp, tp, i;
12701  
12702  	for (i = 0; i < soc->num_tcl_data_rings; i++) {
12703  		if (dp_ipa_is_ring_ipa_tx(soc, i))
12704  			continue;
12705  
12706  		hal_get_sw_hptp(hal_soc, soc->tcl_data_ring[i].hal_srng,
12707  				&tp, &hp);
12708  
12709  		if (hp != tp) {
12710  			dp_info_rl("Pending transactions in TCL DATA Ring[%d] hp=0x%x, tp=0x%x",
12711  				   i, hp, tp);
12712  			return true;
12713  		}
12714  
12715  		if (wlan_cfg_get_wbm_ring_num_for_index(soc->wlan_cfg_ctx, i) ==
12716  		    INVALID_WBM_RING_NUM)
12717  			continue;
12718  
12719  		hal_get_sw_hptp(hal_soc, soc->tx_comp_ring[i].hal_srng,
12720  				&tp, &hp);
12721  
12722  		if (hp != tp) {
12723  			dp_info_rl("Pending transactions in TX comp Ring[%d] hp=0x%x, tp=0x%x",
12724  				   i, hp, tp);
12725  			return true;
12726  		}
12727  	}
12728  
12729  	return false;
12730  }
12731  
12732  /**
12733   * dp_tx_comp_delay_check() - calculate time latency for tx completion per pkt
12734   * @tx_desc: tx descriptor
12735   *
12736   * Calculate time latency for tx completion per pkt and trigger self recovery
12737   * when the delay is more than threshold value.
12738   *
12739   * Return: True if delay is more than threshold
12740   */
dp_tx_comp_delay_check(struct dp_tx_desc_s * tx_desc)12741  static bool dp_tx_comp_delay_check(struct dp_tx_desc_s *tx_desc)
12742  {
12743  	uint64_t time_latency, timestamp_tick = tx_desc->timestamp_tick;
12744  	qdf_ktime_t current_time = qdf_ktime_real_get();
12745  	qdf_ktime_t timestamp = tx_desc->timestamp;
12746  
12747  	if (dp_tx_pkt_tracepoints_enabled()) {
12748  		if (!timestamp)
12749  			return false;
12750  
12751  		time_latency = qdf_ktime_to_ms(current_time) -
12752  				qdf_ktime_to_ms(timestamp);
12753  		if (time_latency >= DP_TX_COMP_MAX_LATENCY_MS) {
12754  			dp_err_rl("enqueued: %llu ms, current : %llu ms",
12755  				  timestamp, current_time);
12756  			return true;
12757  		}
12758  	} else {
12759  		if (!timestamp_tick)
12760  			return false;
12761  
12762  		current_time = qdf_system_ticks();
12763  		time_latency = qdf_system_ticks_to_msecs(current_time -
12764  							 timestamp_tick);
12765  		if (time_latency >= DP_TX_COMP_MAX_LATENCY_MS) {
12766  			dp_err_rl("enqueued: %u ms, current : %u ms",
12767  				  qdf_system_ticks_to_msecs(timestamp_tick),
12768  				  qdf_system_ticks_to_msecs(current_time));
12769  			return true;
12770  		}
12771  	}
12772  
12773  	return false;
12774  }
12775  
dp_find_missing_tx_comp(struct dp_soc * soc)12776  void dp_find_missing_tx_comp(struct dp_soc *soc)
12777  {
12778  	uint8_t i;
12779  	uint32_t j;
12780  	uint32_t num_desc, page_id, offset;
12781  	uint16_t num_desc_per_page;
12782  	struct dp_tx_desc_s *tx_desc = NULL;
12783  	struct dp_tx_desc_pool_s *tx_desc_pool = NULL;
12784  
12785  	if (dp_check_pending_tx(soc))
12786  		return;
12787  
12788  	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
12789  		tx_desc_pool = &soc->tx_desc[i];
12790  		if (!(tx_desc_pool->pool_size) ||
12791  		    IS_TX_DESC_POOL_STATUS_INACTIVE(tx_desc_pool) ||
12792  		    !(tx_desc_pool->desc_pages.cacheable_pages))
12793  			continue;
12794  
12795  		num_desc = tx_desc_pool->pool_size;
12796  		num_desc_per_page =
12797  			tx_desc_pool->desc_pages.num_element_per_page;
12798  		for (j = 0; j < num_desc; j++) {
12799  			page_id = j / num_desc_per_page;
12800  			offset = j % num_desc_per_page;
12801  
12802  			if (qdf_unlikely(!(tx_desc_pool->
12803  					 desc_pages.cacheable_pages)))
12804  				break;
12805  
12806  			tx_desc = dp_tx_desc_find(soc, i, page_id, offset,
12807  						  false);
12808  			if (tx_desc->magic == DP_TX_MAGIC_PATTERN_FREE) {
12809  				continue;
12810  			} else if (tx_desc->magic ==
12811  				   DP_TX_MAGIC_PATTERN_INUSE) {
12812  				if (dp_tx_comp_delay_check(tx_desc)) {
12813  					dp_err_rl("Tx completion not rcvd for id: %u",
12814  						  tx_desc->id);
12815  					if (tx_desc->vdev_id == DP_INVALID_VDEV_ID) {
12816  						tx_desc->flags |= DP_TX_DESC_FLAG_FLUSH;
12817  						dp_err_rl("Freed tx_desc %u",
12818  							  tx_desc->id);
12819  						dp_tx_comp_free_buf(soc,
12820  								    tx_desc,
12821  								    false);
12822  						dp_tx_desc_release(soc, tx_desc,
12823  								   i);
12824  						DP_STATS_INC(soc,
12825  							     tx.tx_comp_force_freed, 1);
12826  					}
12827  				}
12828  			} else {
12829  				dp_err_rl("tx desc %u corrupted, flags: 0x%x",
12830  					  tx_desc->id, tx_desc->flags);
12831  			}
12832  		}
12833  	}
12834  }
12835  #else
dp_find_missing_tx_comp(struct dp_soc * soc)12836  inline void dp_find_missing_tx_comp(struct dp_soc *soc)
12837  {
12838  }
12839  #endif
12840  
12841  #ifdef FEATURE_RUNTIME_PM
12842  /**
12843   * dp_runtime_suspend() - ensure DP is ready to runtime suspend
12844   * @soc_hdl: Datapath soc handle
12845   * @pdev_id: id of data path pdev handle
12846   *
12847   * DP is ready to runtime suspend if there are no pending TX packets.
12848   *
12849   * Return: QDF_STATUS
12850   */
dp_runtime_suspend(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)12851  static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
12852  {
12853  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12854  	struct dp_pdev *pdev;
12855  	int32_t tx_pending;
12856  
12857  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
12858  	if (!pdev) {
12859  		dp_err("pdev is NULL");
12860  		return QDF_STATUS_E_INVAL;
12861  	}
12862  
12863  	/* Abort if there are any pending TX packets */
12864  	tx_pending = dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev));
12865  	if (tx_pending) {
12866  		dp_info_rl("%pK: Abort suspend due to pending TX packets %d",
12867  			   soc, tx_pending);
12868  		dp_find_missing_tx_comp(soc);
12869  		/* perform a force flush if tx is pending */
12870  		soc->arch_ops.dp_update_ring_hptp(soc, true);
12871  		qdf_atomic_set(&soc->tx_pending_rtpm, 0);
12872  
12873  		return QDF_STATUS_E_AGAIN;
12874  	}
12875  
12876  	if (dp_runtime_get_refcount(soc)) {
12877  		dp_init_info("refcount: %d", dp_runtime_get_refcount(soc));
12878  
12879  		return QDF_STATUS_E_AGAIN;
12880  	}
12881  
12882  	if (soc->intr_mode == DP_INTR_POLL)
12883  		qdf_timer_stop(&soc->int_timer);
12884  
12885  	return QDF_STATUS_SUCCESS;
12886  }
12887  
12888  #define DP_FLUSH_WAIT_CNT 10
12889  #define DP_RUNTIME_SUSPEND_WAIT_MS 10
12890  /**
12891   * dp_runtime_resume() - ensure DP is ready to runtime resume
12892   * @soc_hdl: Datapath soc handle
12893   * @pdev_id: id of data path pdev handle
12894   *
12895   * Resume DP for runtime PM.
12896   *
12897   * Return: QDF_STATUS
12898   */
dp_runtime_resume(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)12899  static QDF_STATUS dp_runtime_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
12900  {
12901  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12902  	int suspend_wait = 0;
12903  
12904  	if (soc->intr_mode == DP_INTR_POLL)
12905  		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
12906  
12907  	/*
12908  	 * Wait until dp runtime refcount becomes zero or time out, then flush
12909  	 * pending tx for runtime suspend.
12910  	 */
12911  	while (dp_runtime_get_refcount(soc) &&
12912  	       suspend_wait < DP_FLUSH_WAIT_CNT) {
12913  		qdf_sleep(DP_RUNTIME_SUSPEND_WAIT_MS);
12914  		suspend_wait++;
12915  	}
12916  
12917  	soc->arch_ops.dp_update_ring_hptp(soc, false);
12918  	qdf_atomic_set(&soc->tx_pending_rtpm, 0);
12919  
12920  	return QDF_STATUS_SUCCESS;
12921  }
12922  #endif /* FEATURE_RUNTIME_PM */
12923  
12924  /**
12925   * dp_tx_get_success_ack_stats() - get tx success completion count
12926   * @soc_hdl: Datapath soc handle
12927   * @vdev_id: vdev identifier
12928   *
12929   * Return: tx success ack count
12930   */
dp_tx_get_success_ack_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id)12931  static uint32_t dp_tx_get_success_ack_stats(struct cdp_soc_t *soc_hdl,
12932  					    uint8_t vdev_id)
12933  {
12934  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12935  	struct cdp_vdev_stats *vdev_stats = NULL;
12936  	uint32_t tx_success;
12937  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
12938  						     DP_MOD_ID_CDP);
12939  
12940  	if (!vdev) {
12941  		dp_cdp_err("%pK: Invalid vdev id %d", soc, vdev_id);
12942  		return 0;
12943  	}
12944  
12945  	vdev_stats = qdf_mem_malloc_atomic(sizeof(struct cdp_vdev_stats));
12946  	if (!vdev_stats) {
12947  		dp_cdp_err("%pK: DP alloc failure - unable to get alloc vdev stats", soc);
12948  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
12949  		return 0;
12950  	}
12951  
12952  	dp_aggregate_vdev_stats(vdev, vdev_stats, DP_XMIT_TOTAL);
12953  
12954  	tx_success = vdev_stats->tx.tx_success.num;
12955  	qdf_mem_free(vdev_stats);
12956  
12957  	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
12958  	return tx_success;
12959  }
12960  
12961  #ifdef WLAN_SUPPORT_DATA_STALL
12962  /**
12963   * dp_register_data_stall_detect_cb() - register data stall callback
12964   * @soc_hdl: Datapath soc handle
12965   * @pdev_id: id of data path pdev handle
12966   * @data_stall_detect_callback: data stall callback function
12967   *
12968   * Return: QDF_STATUS Enumeration
12969   */
12970  static
dp_register_data_stall_detect_cb(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,data_stall_detect_cb data_stall_detect_callback)12971  QDF_STATUS dp_register_data_stall_detect_cb(
12972  			struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
12973  			data_stall_detect_cb data_stall_detect_callback)
12974  {
12975  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
12976  	struct dp_pdev *pdev;
12977  
12978  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
12979  	if (!pdev) {
12980  		dp_err("pdev NULL!");
12981  		return QDF_STATUS_E_INVAL;
12982  	}
12983  
12984  	pdev->data_stall_detect_callback = data_stall_detect_callback;
12985  	return QDF_STATUS_SUCCESS;
12986  }
12987  
12988  /**
12989   * dp_deregister_data_stall_detect_cb() - de-register data stall callback
12990   * @soc_hdl: Datapath soc handle
12991   * @pdev_id: id of data path pdev handle
12992   * @data_stall_detect_callback: data stall callback function
12993   *
12994   * Return: QDF_STATUS Enumeration
12995   */
12996  static
dp_deregister_data_stall_detect_cb(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,data_stall_detect_cb data_stall_detect_callback)12997  QDF_STATUS dp_deregister_data_stall_detect_cb(
12998  			struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
12999  			data_stall_detect_cb data_stall_detect_callback)
13000  {
13001  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13002  	struct dp_pdev *pdev;
13003  
13004  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13005  	if (!pdev) {
13006  		dp_err("pdev NULL!");
13007  		return QDF_STATUS_E_INVAL;
13008  	}
13009  
13010  	pdev->data_stall_detect_callback = NULL;
13011  	return QDF_STATUS_SUCCESS;
13012  }
13013  
13014  /**
13015   * dp_txrx_post_data_stall_event() - post data stall event
13016   * @soc_hdl: Datapath soc handle
13017   * @indicator: Module triggering data stall
13018   * @data_stall_type: data stall event type
13019   * @pdev_id: pdev id
13020   * @vdev_id_bitmap: vdev id bitmap
13021   * @recovery_type: data stall recovery type
13022   *
13023   * Return: None
13024   */
13025  static void
dp_txrx_post_data_stall_event(struct cdp_soc_t * soc_hdl,enum data_stall_log_event_indicator indicator,enum data_stall_log_event_type data_stall_type,uint32_t pdev_id,uint32_t vdev_id_bitmap,enum data_stall_log_recovery_type recovery_type)13026  dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl,
13027  			      enum data_stall_log_event_indicator indicator,
13028  			      enum data_stall_log_event_type data_stall_type,
13029  			      uint32_t pdev_id, uint32_t vdev_id_bitmap,
13030  			      enum data_stall_log_recovery_type recovery_type)
13031  {
13032  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13033  	struct data_stall_event_info data_stall_info;
13034  	struct dp_pdev *pdev;
13035  
13036  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13037  	if (!pdev) {
13038  		dp_err("pdev NULL!");
13039  		return;
13040  	}
13041  
13042  	if (!pdev->data_stall_detect_callback) {
13043  		dp_err("data stall cb not registered!");
13044  		return;
13045  	}
13046  
13047  	dp_info("data_stall_type: %x pdev_id: %d",
13048  		data_stall_type, pdev_id);
13049  
13050  	data_stall_info.indicator = indicator;
13051  	data_stall_info.data_stall_type = data_stall_type;
13052  	data_stall_info.vdev_id_bitmap = vdev_id_bitmap;
13053  	data_stall_info.pdev_id = pdev_id;
13054  	data_stall_info.recovery_type = recovery_type;
13055  
13056  	pdev->data_stall_detect_callback(&data_stall_info);
13057  }
13058  #endif /* WLAN_SUPPORT_DATA_STALL */
13059  
13060  #ifdef WLAN_FEATURE_STATS_EXT
13061  /**
13062   * dp_txrx_ext_stats_request() - request dp txrx extended stats request
13063   * @soc_hdl: soc handle
13064   * @pdev_id: pdev id
13065   * @req: stats request
13066   *
13067   * Return: QDF_STATUS
13068   */
13069  static QDF_STATUS
dp_txrx_ext_stats_request(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_txrx_ext_stats * req)13070  dp_txrx_ext_stats_request(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
13071  			  struct cdp_txrx_ext_stats *req)
13072  {
13073  	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
13074  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13075  	int i = 0;
13076  	int tcl_ring_full = 0;
13077  
13078  	if (!pdev) {
13079  		dp_err("pdev is null");
13080  		return QDF_STATUS_E_INVAL;
13081  	}
13082  
13083  	dp_aggregate_pdev_stats(pdev);
13084  
13085  	for(i = 0 ; i < MAX_TCL_DATA_RINGS; i++)
13086  		tcl_ring_full += soc->stats.tx.tcl_ring_full[i];
13087  
13088  	req->tx_msdu_enqueue = pdev->stats.tx_i.processed.num;
13089  	req->tx_msdu_overflow = tcl_ring_full;
13090  	/* Error rate at LMAC */
13091  	req->rx_mpdu_received = soc->ext_stats.rx_mpdu_received +
13092  				pdev->stats.err.fw_reported_rxdma_error;
13093  	/* only count error source from RXDMA */
13094  	req->rx_mpdu_error = pdev->stats.err.fw_reported_rxdma_error;
13095  
13096  	/* Error rate at above the MAC */
13097  	req->rx_mpdu_delivered = soc->ext_stats.rx_mpdu_received;
13098  	req->rx_mpdu_missed = pdev->stats.err.reo_error;
13099  
13100  	dp_info("ext stats: tx_msdu_enq = %u, tx_msdu_overflow = %u, "
13101  		"rx_mpdu_receive = %u, rx_mpdu_delivered = %u, "
13102  		"rx_mpdu_missed = %u, rx_mpdu_error = %u",
13103  		req->tx_msdu_enqueue,
13104  		req->tx_msdu_overflow,
13105  		req->rx_mpdu_received,
13106  		req->rx_mpdu_delivered,
13107  		req->rx_mpdu_missed,
13108  		req->rx_mpdu_error);
13109  
13110  	return QDF_STATUS_SUCCESS;
13111  }
13112  
13113  #endif /* WLAN_FEATURE_STATS_EXT */
13114  
13115  #ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
13116  /**
13117   * dp_mark_first_wakeup_packet() - set flag to indicate that
13118   *    fw is compatible for marking first packet after wow wakeup
13119   * @soc_hdl: Datapath soc handle
13120   * @pdev_id: id of data path pdev handle
13121   * @value: 1 for enabled/ 0 for disabled
13122   *
13123   * Return: None
13124   */
dp_mark_first_wakeup_packet(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t value)13125  static void dp_mark_first_wakeup_packet(struct cdp_soc_t *soc_hdl,
13126  					uint8_t pdev_id, uint8_t value)
13127  {
13128  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13129  	struct dp_pdev *pdev;
13130  
13131  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13132  	if (!pdev) {
13133  		dp_err("pdev is NULL");
13134  		return;
13135  	}
13136  
13137  	pdev->is_first_wakeup_packet = value;
13138  }
13139  #endif
13140  
13141  #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
13142  /**
13143   * dp_set_peer_txq_flush_config() - Set the peer txq flush configuration
13144   * @soc_hdl: Opaque handle to the DP soc object
13145   * @vdev_id: VDEV identifier
13146   * @mac: MAC address of the peer
13147   * @ac: access category mask
13148   * @tid: TID mask
13149   * @policy: Flush policy
13150   *
13151   * Return: 0 on success, errno on failure
13152   */
dp_set_peer_txq_flush_config(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint8_t * mac,uint8_t ac,uint32_t tid,enum cdp_peer_txq_flush_policy policy)13153  static int dp_set_peer_txq_flush_config(struct cdp_soc_t *soc_hdl,
13154  					uint8_t vdev_id, uint8_t *mac,
13155  					uint8_t ac, uint32_t tid,
13156  					enum cdp_peer_txq_flush_policy policy)
13157  {
13158  	struct dp_soc *soc;
13159  
13160  	if (!soc_hdl) {
13161  		dp_err("soc is null");
13162  		return -EINVAL;
13163  	}
13164  	soc = cdp_soc_t_to_dp_soc(soc_hdl);
13165  	return target_if_peer_txq_flush_config(soc->ctrl_psoc, vdev_id,
13166  					       mac, ac, tid, policy);
13167  }
13168  #endif
13169  
13170  #ifdef CONNECTIVITY_PKTLOG
13171  /**
13172   * dp_register_packetdump_callback() - registers
13173   *  tx data packet, tx mgmt. packet and rx data packet
13174   *  dump callback handler.
13175   *
13176   * @soc_hdl: Datapath soc handle
13177   * @pdev_id: id of data path pdev handle
13178   * @dp_tx_packetdump_cb: tx packetdump cb
13179   * @dp_rx_packetdump_cb: rx packetdump cb
13180   *
13181   * This function is used to register tx data pkt, tx mgmt.
13182   * pkt and rx data pkt dump callback
13183   *
13184   * Return: None
13185   *
13186   */
13187  static inline
dp_register_packetdump_callback(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,ol_txrx_pktdump_cb dp_tx_packetdump_cb,ol_txrx_pktdump_cb dp_rx_packetdump_cb)13188  void dp_register_packetdump_callback(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
13189  				     ol_txrx_pktdump_cb dp_tx_packetdump_cb,
13190  				     ol_txrx_pktdump_cb dp_rx_packetdump_cb)
13191  {
13192  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13193  	struct dp_pdev *pdev;
13194  
13195  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13196  	if (!pdev) {
13197  		dp_err("pdev is NULL!");
13198  		return;
13199  	}
13200  
13201  	pdev->dp_tx_packetdump_cb = dp_tx_packetdump_cb;
13202  	pdev->dp_rx_packetdump_cb = dp_rx_packetdump_cb;
13203  }
13204  
13205  /**
13206   * dp_deregister_packetdump_callback() - deregidters
13207   *  tx data packet, tx mgmt. packet and rx data packet
13208   *  dump callback handler
13209   * @soc_hdl: Datapath soc handle
13210   * @pdev_id: id of data path pdev handle
13211   *
13212   * This function is used to deregidter tx data pkt.,
13213   * tx mgmt. pkt and rx data pkt. dump callback
13214   *
13215   * Return: None
13216   *
13217   */
13218  static inline
dp_deregister_packetdump_callback(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13219  void dp_deregister_packetdump_callback(struct cdp_soc_t *soc_hdl,
13220  				       uint8_t pdev_id)
13221  {
13222  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13223  	struct dp_pdev *pdev;
13224  
13225  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13226  	if (!pdev) {
13227  		dp_err("pdev is NULL!");
13228  		return;
13229  	}
13230  
13231  	pdev->dp_tx_packetdump_cb = NULL;
13232  	pdev->dp_rx_packetdump_cb = NULL;
13233  }
13234  #endif
13235  
13236  #ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
13237  /**
13238   * dp_set_bus_vote_lvl_high() - Take a vote on bus bandwidth from dp
13239   * @soc_hdl: Datapath soc handle
13240   * @high: whether the bus bw is high or not
13241   *
13242   * Return: void
13243   */
13244  static void
dp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl,bool high)13245  dp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl, bool high)
13246  {
13247  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13248  
13249  	soc->high_throughput = high;
13250  }
13251  
13252  /**
13253   * dp_get_bus_vote_lvl_high() - get bus bandwidth vote to dp
13254   * @soc_hdl: Datapath soc handle
13255   *
13256   * Return: bool
13257   */
13258  static bool
dp_get_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl)13259  dp_get_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl)
13260  {
13261  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13262  
13263  	return soc->high_throughput;
13264  }
13265  #endif
13266  
13267  #ifdef DP_PEER_EXTENDED_API
13268  static struct cdp_misc_ops dp_ops_misc = {
13269  #ifdef FEATURE_WLAN_TDLS
13270  	.tx_non_std = dp_tx_non_std,
13271  #endif /* FEATURE_WLAN_TDLS */
13272  	.get_opmode = dp_get_opmode,
13273  #ifdef FEATURE_RUNTIME_PM
13274  	.runtime_suspend = dp_runtime_suspend,
13275  	.runtime_resume = dp_runtime_resume,
13276  #endif /* FEATURE_RUNTIME_PM */
13277  	.get_num_rx_contexts = dp_get_num_rx_contexts,
13278  	.get_tx_ack_stats = dp_tx_get_success_ack_stats,
13279  #ifdef WLAN_SUPPORT_DATA_STALL
13280  	.txrx_data_stall_cb_register = dp_register_data_stall_detect_cb,
13281  	.txrx_data_stall_cb_deregister = dp_deregister_data_stall_detect_cb,
13282  	.txrx_post_data_stall_event = dp_txrx_post_data_stall_event,
13283  #endif
13284  
13285  #ifdef WLAN_FEATURE_STATS_EXT
13286  	.txrx_ext_stats_request = dp_txrx_ext_stats_request,
13287  #ifndef WLAN_SOFTUMAC_SUPPORT
13288  	.request_rx_hw_stats = dp_request_rx_hw_stats,
13289  	.reset_rx_hw_ext_stats = dp_reset_rx_hw_ext_stats,
13290  #endif
13291  #endif /* WLAN_FEATURE_STATS_EXT */
13292  	.vdev_inform_ll_conn = dp_vdev_inform_ll_conn,
13293  #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
13294  	.set_swlm_enable = dp_soc_set_swlm_enable,
13295  	.is_swlm_enabled = dp_soc_is_swlm_enabled,
13296  #endif
13297  	.display_txrx_hw_info = dp_display_srng_info,
13298  #ifndef WLAN_SOFTUMAC_SUPPORT
13299  	.get_tx_rings_grp_bitmap = dp_get_tx_rings_grp_bitmap,
13300  #endif
13301  #ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
13302  	.mark_first_wakeup_packet = dp_mark_first_wakeup_packet,
13303  #endif
13304  #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF
13305  	.set_peer_txq_flush_config = dp_set_peer_txq_flush_config,
13306  #endif
13307  #ifdef CONNECTIVITY_PKTLOG
13308  	.register_pktdump_cb = dp_register_packetdump_callback,
13309  	.unregister_pktdump_cb = dp_deregister_packetdump_callback,
13310  #endif
13311  #ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
13312  	.set_bus_vote_lvl_high = dp_set_bus_vote_lvl_high,
13313  	.get_bus_vote_lvl_high = dp_get_bus_vote_lvl_high,
13314  #endif
13315  #ifdef DP_TX_PACKET_INSPECT_FOR_ILP
13316  	.evaluate_update_tx_ilp_cfg = dp_evaluate_update_tx_ilp_config,
13317  #endif
13318  };
13319  #endif
13320  
13321  #ifdef DP_FLOW_CTL
13322  static struct cdp_flowctl_ops dp_ops_flowctl = {
13323  	/* WIFI 3.0 DP implement as required. */
13324  #ifdef QCA_LL_TX_FLOW_CONTROL_V2
13325  #ifndef WLAN_SOFTUMAC_SUPPORT
13326  	.flow_pool_map_handler = dp_tx_flow_pool_map,
13327  	.flow_pool_unmap_handler = dp_tx_flow_pool_unmap,
13328  #endif /*WLAN_SOFTUMAC_SUPPORT */
13329  	.register_pause_cb = dp_txrx_register_pause_cb,
13330  	.dump_flow_pool_info = dp_tx_dump_flow_pool_info,
13331  	.tx_desc_thresh_reached = dp_tx_desc_thresh_reached,
13332  #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
13333  };
13334  
13335  static struct cdp_lflowctl_ops dp_ops_l_flowctl = {
13336  	/* WIFI 3.0 DP NOT IMPLEMENTED YET */
13337  };
13338  #endif
13339  
13340  #ifdef IPA_OFFLOAD
13341  static struct cdp_ipa_ops dp_ops_ipa = {
13342  	.ipa_get_resource = dp_ipa_get_resource,
13343  	.ipa_set_doorbell_paddr = dp_ipa_set_doorbell_paddr,
13344  	.ipa_iounmap_doorbell_vaddr = dp_ipa_iounmap_doorbell_vaddr,
13345  	.ipa_op_response = dp_ipa_op_response,
13346  	.ipa_register_op_cb = dp_ipa_register_op_cb,
13347  	.ipa_deregister_op_cb = dp_ipa_deregister_op_cb,
13348  	.ipa_get_stat = dp_ipa_get_stat,
13349  	.ipa_tx_data_frame = dp_tx_send_ipa_data_frame,
13350  	.ipa_enable_autonomy = dp_ipa_enable_autonomy,
13351  	.ipa_disable_autonomy = dp_ipa_disable_autonomy,
13352  	.ipa_setup = dp_ipa_setup,
13353  	.ipa_cleanup = dp_ipa_cleanup,
13354  	.ipa_setup_iface = dp_ipa_setup_iface,
13355  	.ipa_cleanup_iface = dp_ipa_cleanup_iface,
13356  	.ipa_enable_pipes = dp_ipa_enable_pipes,
13357  	.ipa_disable_pipes = dp_ipa_disable_pipes,
13358  	.ipa_set_perf_level = dp_ipa_set_perf_level,
13359  	.ipa_rx_intrabss_fwd = dp_ipa_rx_intrabss_fwd,
13360  	.ipa_tx_buf_smmu_mapping = dp_ipa_tx_buf_smmu_mapping,
13361  	.ipa_tx_buf_smmu_unmapping = dp_ipa_tx_buf_smmu_unmapping,
13362  	.ipa_rx_buf_smmu_pool_mapping = dp_ipa_rx_buf_pool_smmu_mapping,
13363  	.ipa_set_smmu_mapped = dp_ipa_set_smmu_mapped,
13364  	.ipa_get_smmu_mapped = dp_ipa_get_smmu_mapped,
13365  #ifdef QCA_SUPPORT_WDS_EXTENDED
13366  	.ipa_rx_wdsext_iface = dp_ipa_rx_wdsext_iface,
13367  #endif
13368  #ifdef QCA_ENHANCED_STATS_SUPPORT
13369  	.ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats,
13370  #endif
13371  #ifdef IPA_OPT_WIFI_DP
13372  	.ipa_rx_super_rule_setup = dp_ipa_rx_super_rule_setup,
13373  	.ipa_pcie_link_up = dp_ipa_pcie_link_up,
13374  	.ipa_pcie_link_down = dp_ipa_pcie_link_down,
13375  #endif
13376  #ifdef IPA_WDS_EASYMESH_FEATURE
13377  	.ipa_ast_create = dp_ipa_ast_create,
13378  #endif
13379  	.ipa_get_wdi_version = dp_ipa_get_wdi_version,
13380  };
13381  #endif
13382  
13383  #ifdef DP_POWER_SAVE
dp_bus_suspend(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13384  static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
13385  {
13386  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13387  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13388  	int timeout = SUSPEND_DRAIN_WAIT;
13389  	int drain_wait_delay = 50; /* 50 ms */
13390  	int32_t tx_pending;
13391  
13392  	if (qdf_unlikely(!pdev)) {
13393  		dp_err("pdev is NULL");
13394  		return QDF_STATUS_E_INVAL;
13395  	}
13396  
13397  	/* Abort if there are any pending TX packets */
13398  	while ((tx_pending = dp_get_tx_pending((struct cdp_pdev *)pdev))) {
13399  		qdf_sleep(drain_wait_delay);
13400  		if (timeout <= 0) {
13401  			dp_info("TX frames are pending %d, abort suspend",
13402  				tx_pending);
13403  			dp_find_missing_tx_comp(soc);
13404  			return QDF_STATUS_E_TIMEOUT;
13405  		}
13406  		timeout = timeout - drain_wait_delay;
13407  	}
13408  
13409  	if (soc->intr_mode == DP_INTR_POLL)
13410  		qdf_timer_stop(&soc->int_timer);
13411  
13412  	/* Stop monitor reap timer and reap any pending frames in ring */
13413  	dp_monitor_reap_timer_suspend(soc);
13414  
13415  	return QDF_STATUS_SUCCESS;
13416  }
13417  
dp_bus_resume(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13418  static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
13419  {
13420  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13421  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13422  
13423  	if (qdf_unlikely(!pdev)) {
13424  		dp_err("pdev is NULL");
13425  		return QDF_STATUS_E_INVAL;
13426  	}
13427  
13428  	if (soc->intr_mode == DP_INTR_POLL)
13429  		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
13430  
13431  	/* Start monitor reap timer */
13432  	dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_ANY);
13433  
13434  	soc->arch_ops.dp_update_ring_hptp(soc, false);
13435  
13436  	return QDF_STATUS_SUCCESS;
13437  }
13438  
13439  /**
13440   * dp_process_wow_ack_rsp() - process wow ack response
13441   * @soc_hdl: datapath soc handle
13442   * @pdev_id: data path pdev handle id
13443   *
13444   * Return: none
13445   */
dp_process_wow_ack_rsp(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13446  static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
13447  {
13448  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13449  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13450  
13451  	if (qdf_unlikely(!pdev)) {
13452  		dp_err("pdev is NULL");
13453  		return;
13454  	}
13455  
13456  	/*
13457  	 * As part of wow enable FW disables the mon status ring and in wow ack
13458  	 * response from FW reap mon status ring to make sure no packets pending
13459  	 * in the ring.
13460  	 */
13461  	dp_monitor_reap_timer_suspend(soc);
13462  }
13463  
13464  /**
13465   * dp_process_target_suspend_req() - process target suspend request
13466   * @soc_hdl: datapath soc handle
13467   * @pdev_id: data path pdev handle id
13468   *
13469   * Return: none
13470   */
dp_process_target_suspend_req(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13471  static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl,
13472  					  uint8_t pdev_id)
13473  {
13474  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13475  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13476  
13477  	if (qdf_unlikely(!pdev)) {
13478  		dp_err("pdev is NULL");
13479  		return;
13480  	}
13481  
13482  	/* Stop monitor reap timer and reap any pending frames in ring */
13483  	dp_monitor_reap_timer_suspend(soc);
13484  }
13485  
13486  static struct cdp_bus_ops dp_ops_bus = {
13487  	.bus_suspend = dp_bus_suspend,
13488  	.bus_resume = dp_bus_resume,
13489  	.process_wow_ack_rsp = dp_process_wow_ack_rsp,
13490  	.process_target_suspend_req = dp_process_target_suspend_req
13491  };
13492  #endif
13493  
13494  #ifdef DP_FLOW_CTL
13495  static struct cdp_throttle_ops dp_ops_throttle = {
13496  	/* WIFI 3.0 DP NOT IMPLEMENTED YET */
13497  };
13498  
13499  static struct cdp_cfg_ops dp_ops_cfg = {
13500  	/* WIFI 3.0 DP NOT IMPLEMENTED YET */
13501  };
13502  #endif
13503  
13504  #ifdef DP_PEER_EXTENDED_API
13505  static struct cdp_ocb_ops dp_ops_ocb = {
13506  	/* WIFI 3.0 DP NOT IMPLEMENTED YET */
13507  };
13508  
13509  static struct cdp_mob_stats_ops dp_ops_mob_stats = {
13510  	.clear_stats = dp_txrx_clear_dump_stats,
13511  };
13512  
13513  static struct cdp_peer_ops dp_ops_peer = {
13514  	.register_peer = dp_register_peer,
13515  	.clear_peer = dp_clear_peer,
13516  	.find_peer_exist = dp_find_peer_exist,
13517  	.find_peer_exist_on_vdev = dp_find_peer_exist_on_vdev,
13518  	.find_peer_exist_on_other_vdev = dp_find_peer_exist_on_other_vdev,
13519  	.peer_state_update = dp_peer_state_update,
13520  	.get_vdevid = dp_get_vdevid,
13521  	.get_vdev_by_peer_addr = dp_get_vdev_by_peer_addr,
13522  	.peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr,
13523  	.get_peer_state = dp_get_peer_state,
13524  	.peer_flush_frags = dp_peer_flush_frags,
13525  	.set_peer_as_tdls_peer = dp_set_peer_as_tdls_peer,
13526  };
13527  #endif
13528  
dp_soc_txrx_ops_attach(struct dp_soc * soc)13529  static void dp_soc_txrx_ops_attach(struct dp_soc *soc)
13530  {
13531  	soc->cdp_soc.ops->cmn_drv_ops = &dp_ops_cmn;
13532  	soc->cdp_soc.ops->ctrl_ops = &dp_ops_ctrl;
13533  	soc->cdp_soc.ops->me_ops = &dp_ops_me;
13534  	soc->cdp_soc.ops->host_stats_ops = &dp_ops_host_stats;
13535  	soc->cdp_soc.ops->wds_ops = &dp_ops_wds;
13536  	soc->cdp_soc.ops->raw_ops = &dp_ops_raw;
13537  #ifdef PEER_FLOW_CONTROL
13538  	soc->cdp_soc.ops->pflow_ops = &dp_ops_pflow;
13539  #endif /* PEER_FLOW_CONTROL */
13540  #ifdef DP_PEER_EXTENDED_API
13541  	soc->cdp_soc.ops->misc_ops = &dp_ops_misc;
13542  	soc->cdp_soc.ops->ocb_ops = &dp_ops_ocb;
13543  	soc->cdp_soc.ops->peer_ops = &dp_ops_peer;
13544  	soc->cdp_soc.ops->mob_stats_ops = &dp_ops_mob_stats;
13545  #endif
13546  #ifdef DP_FLOW_CTL
13547  	soc->cdp_soc.ops->cfg_ops = &dp_ops_cfg;
13548  	soc->cdp_soc.ops->flowctl_ops = &dp_ops_flowctl;
13549  	soc->cdp_soc.ops->l_flowctl_ops = &dp_ops_l_flowctl;
13550  	soc->cdp_soc.ops->throttle_ops = &dp_ops_throttle;
13551  #endif
13552  #ifdef IPA_OFFLOAD
13553  	soc->cdp_soc.ops->ipa_ops = &dp_ops_ipa;
13554  #endif
13555  #ifdef DP_POWER_SAVE
13556  	soc->cdp_soc.ops->bus_ops = &dp_ops_bus;
13557  #endif
13558  #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
13559  	soc->cdp_soc.ops->cfr_ops = &dp_ops_cfr;
13560  #endif
13561  #ifdef WLAN_SUPPORT_MSCS
13562  	soc->cdp_soc.ops->mscs_ops = &dp_ops_mscs;
13563  #endif
13564  #ifdef WLAN_SUPPORT_MESH_LATENCY
13565  	soc->cdp_soc.ops->mesh_latency_ops = &dp_ops_mesh_latency;
13566  #endif
13567  #ifdef CONFIG_SAWF_DEF_QUEUES
13568  	soc->cdp_soc.ops->sawf_ops = &dp_ops_sawf;
13569  #endif
13570  #ifdef WLAN_SUPPORT_SCS
13571  	soc->cdp_soc.ops->scs_ops = &dp_ops_scs;
13572  #endif
13573  #ifdef WLAN_SUPPORT_RX_FLOW_TAG
13574  	soc->cdp_soc.ops->fse_ops = &dp_ops_fse;
13575  #endif
13576  };
13577  
13578  #if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \
13579  	defined(QCA_WIFI_QCA5018) || defined(QCA_WIFI_QCA9574) || \
13580  	defined(QCA_WIFI_QCA5332)
13581  
13582  /**
13583   * dp_soc_attach_wifi3() - Attach txrx SOC
13584   * @ctrl_psoc: Opaque SOC handle from control plane
13585   * @params: SOC attach params
13586   *
13587   * Return: DP SOC handle on success, NULL on failure
13588   */
13589  struct cdp_soc_t *
dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc * ctrl_psoc,struct cdp_soc_attach_params * params)13590  dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
13591  		    struct cdp_soc_attach_params *params)
13592  {
13593  	struct dp_soc *dp_soc = NULL;
13594  
13595  	dp_soc = dp_soc_attach(ctrl_psoc, params);
13596  
13597  	return dp_soc_to_cdp_soc_t(dp_soc);
13598  }
13599  
dp_soc_set_def_pdev(struct dp_soc * soc)13600  static inline void dp_soc_set_def_pdev(struct dp_soc *soc)
13601  {
13602  	int lmac_id;
13603  
13604  	for (lmac_id = 0; lmac_id < MAX_NUM_LMAC_HW; lmac_id++) {
13605  		/*Set default host PDEV ID for lmac_id*/
13606  		wlan_cfg_set_pdev_idx(soc->wlan_cfg_ctx,
13607  				      INVALID_PDEV_ID, lmac_id);
13608  	}
13609  }
13610  
dp_soc_unset_qref_debug_list(struct dp_soc * soc)13611  static void dp_soc_unset_qref_debug_list(struct dp_soc *soc)
13612  {
13613  	uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size;
13614  
13615  	if (max_list_size == 0)
13616  		return;
13617  
13618  	qdf_mem_free(soc->list_shared_qaddr_del);
13619  	qdf_mem_free(soc->reo_write_list);
13620  	qdf_mem_free(soc->list_qdesc_addr_free);
13621  	qdf_mem_free(soc->list_qdesc_addr_alloc);
13622  }
13623  
dp_soc_set_qref_debug_list(struct dp_soc * soc)13624  static void dp_soc_set_qref_debug_list(struct dp_soc *soc)
13625  {
13626  	uint32_t max_list_size = soc->wlan_cfg_ctx->qref_control_size;
13627  
13628  	if (max_list_size == 0)
13629  		return;
13630  
13631  	soc->list_shared_qaddr_del =
13632  			(struct test_qaddr_del *)
13633  				qdf_mem_malloc(sizeof(struct test_qaddr_del) *
13634  					       max_list_size);
13635  	soc->reo_write_list =
13636  			(struct test_qaddr_del *)
13637  				qdf_mem_malloc(sizeof(struct test_qaddr_del) *
13638  					       max_list_size);
13639  	soc->list_qdesc_addr_free =
13640  			(struct test_mem_free *)
13641  				qdf_mem_malloc(sizeof(struct test_mem_free) *
13642  					       max_list_size);
13643  	soc->list_qdesc_addr_alloc =
13644  			(struct test_mem_free *)
13645  				qdf_mem_malloc(sizeof(struct test_mem_free) *
13646  					       max_list_size);
13647  }
13648  
13649  static uint32_t
dp_get_link_desc_id_start(uint16_t arch_id)13650  dp_get_link_desc_id_start(uint16_t arch_id)
13651  {
13652  	switch (arch_id) {
13653  	case CDP_ARCH_TYPE_LI:
13654  	case CDP_ARCH_TYPE_RH:
13655  		return LINK_DESC_ID_START_21_BITS_COOKIE;
13656  	case CDP_ARCH_TYPE_BE:
13657  		return LINK_DESC_ID_START_20_BITS_COOKIE;
13658  	default:
13659  		dp_err("unknown arch_id 0x%x", arch_id);
13660  		QDF_BUG(0);
13661  		return LINK_DESC_ID_START_21_BITS_COOKIE;
13662  	}
13663  }
13664  
13665  #ifdef DP_TX_PACKET_INSPECT_FOR_ILP
13666  static inline
dp_soc_init_tx_ilp(struct dp_soc * soc)13667  void dp_soc_init_tx_ilp(struct dp_soc *soc)
13668  {
13669  	soc->tx_ilp_enable = false;
13670  }
13671  #else
13672  static inline
dp_soc_init_tx_ilp(struct dp_soc * soc)13673  void dp_soc_init_tx_ilp(struct dp_soc *soc)
13674  {
13675  }
13676  #endif
13677  
13678  /**
13679   * dp_soc_attach() - Attach txrx SOC
13680   * @ctrl_psoc: Opaque SOC handle from control plane
13681   * @params: SOC attach params
13682   *
13683   * Return: DP SOC handle on success, NULL on failure
13684   */
13685  static struct dp_soc *
dp_soc_attach(struct cdp_ctrl_objmgr_psoc * ctrl_psoc,struct cdp_soc_attach_params * params)13686  dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
13687  	      struct cdp_soc_attach_params *params)
13688  {
13689  	struct dp_soc *soc =  NULL;
13690  	uint16_t arch_id;
13691  	struct hif_opaque_softc *hif_handle = params->hif_handle;
13692  	qdf_device_t qdf_osdev = params->qdf_osdev;
13693  	struct ol_if_ops *ol_ops = params->ol_ops;
13694  	uint16_t device_id = params->device_id;
13695  
13696  	if (!hif_handle) {
13697  		dp_err("HIF handle is NULL");
13698  		goto fail0;
13699  	}
13700  	arch_id = cdp_get_arch_type_from_devid(device_id);
13701  	soc = qdf_mem_common_alloc(dp_get_soc_context_size(device_id));
13702  	if (!soc) {
13703  		dp_err("DP SOC memory allocation failed");
13704  		goto fail0;
13705  	}
13706  
13707  	dp_info("soc memory allocated %pK", soc);
13708  	soc->hif_handle = hif_handle;
13709  	soc->hal_soc = hif_get_hal_handle(soc->hif_handle);
13710  	if (!soc->hal_soc)
13711  		goto fail1;
13712  
13713  	hif_get_cmem_info(soc->hif_handle,
13714  			  &soc->cmem_base,
13715  			  &soc->cmem_total_size);
13716  	soc->cmem_avail_size = soc->cmem_total_size;
13717  	soc->device_id = device_id;
13718  	soc->cdp_soc.ops =
13719  		(struct cdp_ops *)qdf_mem_malloc(sizeof(struct cdp_ops));
13720  	if (!soc->cdp_soc.ops)
13721  		goto fail1;
13722  
13723  	dp_soc_txrx_ops_attach(soc);
13724  	soc->cdp_soc.ol_ops = ol_ops;
13725  	soc->ctrl_psoc = ctrl_psoc;
13726  	soc->osdev = qdf_osdev;
13727  	soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS;
13728  	dp_soc_init_tx_ilp(soc);
13729  	hal_rx_get_tlv_size(soc->hal_soc, &soc->rx_pkt_tlv_size,
13730  			    &soc->rx_mon_pkt_tlv_size);
13731  	soc->idle_link_bm_id = hal_get_idle_link_bm_id(soc->hal_soc,
13732  						       params->mlo_chip_id);
13733  	soc->features.dmac_cmn_src_rxbuf_ring_enabled =
13734  		hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc);
13735  	soc->arch_id = arch_id;
13736  	soc->link_desc_id_start =
13737  			dp_get_link_desc_id_start(soc->arch_id);
13738  	dp_configure_arch_ops(soc);
13739  
13740  	/* Reset wbm sg list and flags */
13741  	dp_rx_wbm_sg_list_reset(soc);
13742  
13743  	dp_soc_cfg_history_attach(soc);
13744  	dp_soc_tx_hw_desc_history_attach(soc);
13745  	dp_soc_rx_history_attach(soc);
13746  	dp_soc_mon_status_ring_history_attach(soc);
13747  	dp_soc_tx_history_attach(soc);
13748  	dp_soc_msdu_done_fail_desc_list_attach(soc);
13749  	dp_soc_msdu_done_fail_history_attach(soc);
13750  	wlan_set_srng_cfg(&soc->wlan_srng_cfg);
13751  	soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc);
13752  	if (!soc->wlan_cfg_ctx) {
13753  		dp_err("wlan_cfg_ctx failed");
13754  		goto fail2;
13755  	}
13756  
13757  	qdf_ssr_driver_dump_register_region("wlan_cfg_ctx", soc->wlan_cfg_ctx,
13758  					    sizeof(*soc->wlan_cfg_ctx));
13759  
13760  	/*sync DP soc cfg items with profile support after cfg_soc_attach*/
13761  	wlan_dp_soc_cfg_sync_profile((struct cdp_soc_t *)soc);
13762  
13763  	soc->arch_ops.soc_cfg_attach(soc);
13764  
13765  	qdf_ssr_driver_dump_register_region("tcl_wbm_map_array",
13766  					    &soc->wlan_cfg_ctx->tcl_wbm_map_array,
13767  					    sizeof(struct wlan_cfg_tcl_wbm_ring_num_map));
13768  
13769  	if (dp_hw_link_desc_pool_banks_alloc(soc, WLAN_INVALID_PDEV_ID)) {
13770  		dp_err("failed to allocate link desc pool banks");
13771  		goto fail3;
13772  	}
13773  
13774  	if (dp_hw_link_desc_ring_alloc(soc)) {
13775  		dp_err("failed to allocate link_desc_ring");
13776  		goto fail4;
13777  	}
13778  
13779  	if (!QDF_IS_STATUS_SUCCESS(soc->arch_ops.txrx_soc_attach(soc,
13780  								 params))) {
13781  		dp_err("unable to do target specific attach");
13782  		goto fail5;
13783  	}
13784  
13785  	if (dp_soc_srng_alloc(soc)) {
13786  		dp_err("failed to allocate soc srng rings");
13787  		goto fail6;
13788  	}
13789  
13790  	if (dp_soc_tx_desc_sw_pools_alloc(soc)) {
13791  		dp_err("dp_soc_tx_desc_sw_pools_alloc failed");
13792  		goto fail7;
13793  	}
13794  
13795  	if (!dp_monitor_modularized_enable()) {
13796  		if (dp_mon_soc_attach_wrapper(soc)) {
13797  			dp_err("failed to attach monitor");
13798  			goto fail8;
13799  		}
13800  	}
13801  
13802  	if (hal_reo_shared_qaddr_setup((hal_soc_handle_t)soc->hal_soc,
13803  				       &soc->reo_qref)
13804  	    != QDF_STATUS_SUCCESS) {
13805  		dp_err("unable to setup reo shared qaddr");
13806  		goto fail9;
13807  	}
13808  
13809  	if (dp_sysfs_initialize_stats(soc) != QDF_STATUS_SUCCESS) {
13810  		dp_err("failed to initialize dp stats sysfs file");
13811  		dp_sysfs_deinitialize_stats(soc);
13812  	}
13813  
13814  	dp_soc_swlm_attach(soc);
13815  	dp_soc_set_interrupt_mode(soc);
13816  	dp_soc_set_def_pdev(soc);
13817  	dp_soc_set_qref_debug_list(soc);
13818  	qdf_ssr_driver_dump_register_region("dp_soc", soc, sizeof(*soc));
13819  	qdf_nbuf_ssr_register_region();
13820  
13821  	dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u",
13822  		qdf_dma_mem_stats_read(),
13823  		qdf_heap_mem_stats_read(),
13824  		qdf_skb_total_mem_stats_read());
13825  
13826  	return soc;
13827  fail9:
13828  	if (!dp_monitor_modularized_enable())
13829  		dp_mon_soc_detach_wrapper(soc);
13830  fail8:
13831  	dp_soc_tx_desc_sw_pools_free(soc);
13832  fail7:
13833  	dp_soc_srng_free(soc);
13834  fail6:
13835  	soc->arch_ops.txrx_soc_detach(soc);
13836  fail5:
13837  	dp_hw_link_desc_ring_free(soc);
13838  fail4:
13839  	dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID);
13840  fail3:
13841  	wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
13842  fail2:
13843  	dp_soc_msdu_done_fail_history_detach(soc);
13844  	qdf_mem_free(soc->cdp_soc.ops);
13845  fail1:
13846  	qdf_mem_common_free(soc);
13847  fail0:
13848  	return NULL;
13849  }
13850  
dp_soc_init_wifi3(struct cdp_soc_t * cdp_soc,struct cdp_ctrl_objmgr_psoc * ctrl_psoc,struct hif_opaque_softc * hif_handle,HTC_HANDLE htc_handle,qdf_device_t qdf_osdev,struct ol_if_ops * ol_ops,uint16_t device_id)13851  void *dp_soc_init_wifi3(struct cdp_soc_t *cdp_soc,
13852  			struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
13853  			struct hif_opaque_softc *hif_handle,
13854  			HTC_HANDLE htc_handle, qdf_device_t qdf_osdev,
13855  			struct ol_if_ops *ol_ops, uint16_t device_id)
13856  {
13857  	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
13858  
13859  	return soc->arch_ops.txrx_soc_init(soc, htc_handle, hif_handle);
13860  }
13861  
13862  #endif
13863  
dp_get_pdev_for_mac_id(struct dp_soc * soc,uint32_t mac_id)13864  void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id)
13865  {
13866  	if (wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx))
13867  		return (mac_id < MAX_PDEV_CNT) ? soc->pdev_list[mac_id] : NULL;
13868  
13869  	/* Typically for MCL as there only 1 PDEV*/
13870  	return soc->pdev_list[0];
13871  }
13872  
dp_update_num_mac_rings_for_dbs(struct dp_soc * soc,int * max_mac_rings)13873  void dp_update_num_mac_rings_for_dbs(struct dp_soc *soc,
13874  				     int *max_mac_rings)
13875  {
13876  	bool dbs_enable = false;
13877  
13878  	if (soc->cdp_soc.ol_ops->is_hw_dbs_capable)
13879  		dbs_enable = soc->cdp_soc.ol_ops->
13880  				is_hw_dbs_capable((void *)soc->ctrl_psoc);
13881  
13882  	*max_mac_rings = dbs_enable ? (*max_mac_rings) : 1;
13883  	dp_info("dbs_enable %d, max_mac_rings %d",
13884  		dbs_enable, *max_mac_rings);
13885  }
13886  
13887  qdf_export_symbol(dp_update_num_mac_rings_for_dbs);
13888  
13889  #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
13890  /**
13891   * dp_get_cfr_rcc() - get cfr rcc config
13892   * @soc_hdl: Datapath soc handle
13893   * @pdev_id: id of objmgr pdev
13894   *
13895   * Return: true/false based on cfr mode setting
13896   */
13897  static
dp_get_cfr_rcc(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13898  bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
13899  {
13900  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13901  	struct dp_pdev *pdev = NULL;
13902  
13903  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13904  	if (!pdev) {
13905  		dp_err("pdev is NULL");
13906  		return false;
13907  	}
13908  
13909  	return pdev->cfr_rcc_mode;
13910  }
13911  
13912  /**
13913   * dp_set_cfr_rcc() - enable/disable cfr rcc config
13914   * @soc_hdl: Datapath soc handle
13915   * @pdev_id: id of objmgr pdev
13916   * @enable: Enable/Disable cfr rcc mode
13917   *
13918   * Return: none
13919   */
13920  static
dp_set_cfr_rcc(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,bool enable)13921  void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable)
13922  {
13923  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13924  	struct dp_pdev *pdev = NULL;
13925  
13926  	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13927  	if (!pdev) {
13928  		dp_err("pdev is NULL");
13929  		return;
13930  	}
13931  
13932  	pdev->cfr_rcc_mode = enable;
13933  }
13934  
13935  /**
13936   * dp_get_cfr_dbg_stats - Get the debug statistics for CFR
13937   * @soc_hdl: Datapath soc handle
13938   * @pdev_id: id of data path pdev handle
13939   * @cfr_rcc_stats: CFR RCC debug statistics buffer
13940   *
13941   * Return: none
13942   */
13943  static inline void
dp_get_cfr_dbg_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_cfr_rcc_stats * cfr_rcc_stats)13944  dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
13945  		     struct cdp_cfr_rcc_stats *cfr_rcc_stats)
13946  {
13947  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13948  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13949  
13950  	if (!pdev) {
13951  		dp_err("pdev is NULL");
13952  		return;
13953  	}
13954  
13955  	qdf_mem_copy(cfr_rcc_stats, &pdev->stats.rcc,
13956  		     sizeof(struct cdp_cfr_rcc_stats));
13957  }
13958  
13959  /**
13960   * dp_clear_cfr_dbg_stats - Clear debug statistics for CFR
13961   * @soc_hdl: Datapath soc handle
13962   * @pdev_id: id of data path pdev handle
13963   *
13964   * Return: none
13965   */
dp_clear_cfr_dbg_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)13966  static void dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl,
13967  				   uint8_t pdev_id)
13968  {
13969  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
13970  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
13971  
13972  	if (!pdev) {
13973  		dp_err("dp pdev is NULL");
13974  		return;
13975  	}
13976  
13977  	qdf_mem_zero(&pdev->stats.rcc, sizeof(pdev->stats.rcc));
13978  }
13979  #endif
13980  
13981  /**
13982   * dp_bucket_index() - Return index from array
13983   *
13984   * @delay: delay measured
13985   * @array: array used to index corresponding delay
13986   * @delay_in_us: flag to indicate whether the delay in ms or us
13987   *
13988   * Return: index
13989   */
13990  static uint8_t
dp_bucket_index(uint32_t delay,uint16_t * array,bool delay_in_us)13991  dp_bucket_index(uint32_t delay, uint16_t *array, bool delay_in_us)
13992  {
13993  	uint8_t i = CDP_DELAY_BUCKET_0;
13994  	uint32_t thr_low, thr_high;
13995  
13996  	for (; i < CDP_DELAY_BUCKET_MAX - 1; i++) {
13997  		thr_low = array[i];
13998  		thr_high = array[i + 1];
13999  
14000  		if (delay_in_us) {
14001  			thr_low = thr_low * USEC_PER_MSEC;
14002  			thr_high = thr_high * USEC_PER_MSEC;
14003  		}
14004  		if (delay >= thr_low && delay <= thr_high)
14005  			return i;
14006  	}
14007  	return (CDP_DELAY_BUCKET_MAX - 1);
14008  }
14009  
14010  #ifdef HW_TX_DELAY_STATS_ENABLE
14011  /*
14012   * cdp_fw_to_hw_delay_range
14013   * Fw to hw delay ranges in milliseconds
14014   */
14015  static uint16_t cdp_fw_to_hw_delay[CDP_DELAY_BUCKET_MAX] = {
14016  	0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 250, 500};
14017  #else
14018  static uint16_t cdp_fw_to_hw_delay[CDP_DELAY_BUCKET_MAX] = {
14019  	0, 2, 4, 6, 8, 10, 20, 30, 40, 50, 100, 250, 500};
14020  #endif
14021  
14022  /*
14023   * cdp_sw_enq_delay_range
14024   * Software enqueue delay ranges in milliseconds
14025   */
14026  static uint16_t cdp_sw_enq_delay[CDP_DELAY_BUCKET_MAX] = {
14027  	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
14028  
14029  /*
14030   * cdp_intfrm_delay_range
14031   * Interframe delay ranges in milliseconds
14032   */
14033  static uint16_t cdp_intfrm_delay[CDP_DELAY_BUCKET_MAX] = {
14034  	0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60};
14035  
14036  /**
14037   * dp_fill_delay_buckets() - Fill delay statistics bucket for each
14038   *				type of delay
14039   * @tstats: tid tx stats
14040   * @rstats: tid rx stats
14041   * @delay: delay in ms
14042   * @tid: tid value
14043   * @mode: type of tx delay mode
14044   * @ring_id: ring number
14045   * @delay_in_us: flag to indicate whether the delay in ms or us
14046   *
14047   * Return: pointer to cdp_delay_stats structure
14048   */
14049  static struct cdp_delay_stats *
dp_fill_delay_buckets(struct cdp_tid_tx_stats * tstats,struct cdp_tid_rx_stats * rstats,uint32_t delay,uint8_t tid,uint8_t mode,uint8_t ring_id,bool delay_in_us)14050  dp_fill_delay_buckets(struct cdp_tid_tx_stats *tstats,
14051  		      struct cdp_tid_rx_stats *rstats, uint32_t delay,
14052  		      uint8_t tid, uint8_t mode, uint8_t ring_id,
14053  		      bool delay_in_us)
14054  {
14055  	uint8_t delay_index = 0;
14056  	struct cdp_delay_stats *stats = NULL;
14057  
14058  	/*
14059  	 * Update delay stats in proper bucket
14060  	 */
14061  	switch (mode) {
14062  	/* Software Enqueue delay ranges */
14063  	case CDP_DELAY_STATS_SW_ENQ:
14064  		if (!tstats)
14065  			break;
14066  
14067  		delay_index = dp_bucket_index(delay, cdp_sw_enq_delay,
14068  					      delay_in_us);
14069  		tstats->swq_delay.delay_bucket[delay_index]++;
14070  		stats = &tstats->swq_delay;
14071  		break;
14072  
14073  	/* Tx Completion delay ranges */
14074  	case CDP_DELAY_STATS_FW_HW_TRANSMIT:
14075  		if (!tstats)
14076  			break;
14077  
14078  		delay_index = dp_bucket_index(delay, cdp_fw_to_hw_delay,
14079  					      delay_in_us);
14080  		tstats->hwtx_delay.delay_bucket[delay_index]++;
14081  		stats = &tstats->hwtx_delay;
14082  		break;
14083  
14084  	/* Interframe tx delay ranges */
14085  	case CDP_DELAY_STATS_TX_INTERFRAME:
14086  		if (!tstats)
14087  			break;
14088  
14089  		delay_index = dp_bucket_index(delay, cdp_intfrm_delay,
14090  					      delay_in_us);
14091  		tstats->intfrm_delay.delay_bucket[delay_index]++;
14092  		stats = &tstats->intfrm_delay;
14093  		break;
14094  
14095  	/* Interframe rx delay ranges */
14096  	case CDP_DELAY_STATS_RX_INTERFRAME:
14097  		if (!rstats)
14098  			break;
14099  
14100  		delay_index = dp_bucket_index(delay, cdp_intfrm_delay,
14101  					      delay_in_us);
14102  		rstats->intfrm_delay.delay_bucket[delay_index]++;
14103  		stats = &rstats->intfrm_delay;
14104  		break;
14105  
14106  	/* Ring reap to indication to network stack */
14107  	case CDP_DELAY_STATS_REAP_STACK:
14108  		if (!rstats)
14109  			break;
14110  
14111  		delay_index = dp_bucket_index(delay, cdp_intfrm_delay,
14112  					      delay_in_us);
14113  		rstats->to_stack_delay.delay_bucket[delay_index]++;
14114  		stats = &rstats->to_stack_delay;
14115  		break;
14116  	default:
14117  		dp_debug("Incorrect delay mode: %d", mode);
14118  	}
14119  
14120  	return stats;
14121  }
14122  
dp_update_delay_stats(struct cdp_tid_tx_stats * tstats,struct cdp_tid_rx_stats * rstats,uint32_t delay,uint8_t tid,uint8_t mode,uint8_t ring_id,bool delay_in_us)14123  void dp_update_delay_stats(struct cdp_tid_tx_stats *tstats,
14124  			   struct cdp_tid_rx_stats *rstats, uint32_t delay,
14125  			   uint8_t tid, uint8_t mode, uint8_t ring_id,
14126  			   bool delay_in_us)
14127  {
14128  	struct cdp_delay_stats *dstats = NULL;
14129  
14130  	/*
14131  	 * Delay ranges are different for different delay modes
14132  	 * Get the correct index to update delay bucket
14133  	 */
14134  	dstats = dp_fill_delay_buckets(tstats, rstats, delay, tid, mode,
14135  				       ring_id, delay_in_us);
14136  	if (qdf_unlikely(!dstats))
14137  		return;
14138  
14139  	if (delay != 0) {
14140  		/*
14141  		 * Compute minimum,average and maximum
14142  		 * delay
14143  		 */
14144  		if (delay < dstats->min_delay)
14145  			dstats->min_delay = delay;
14146  
14147  		if (delay > dstats->max_delay)
14148  			dstats->max_delay = delay;
14149  
14150  		/*
14151  		 * Average over delay measured till now
14152  		 */
14153  		if (!dstats->avg_delay)
14154  			dstats->avg_delay = delay;
14155  		else
14156  			dstats->avg_delay = ((delay + dstats->avg_delay) >> 1);
14157  	}
14158  }
14159  
dp_get_peer_mac_list(ol_txrx_soc_handle soc,uint8_t vdev_id,u_int8_t newmac[][QDF_MAC_ADDR_SIZE],u_int16_t mac_cnt,bool limit)14160  uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id,
14161  			      u_int8_t newmac[][QDF_MAC_ADDR_SIZE],
14162  			      u_int16_t mac_cnt, bool limit)
14163  {
14164  	struct dp_soc *dp_soc = (struct dp_soc *)soc;
14165  	struct dp_vdev *vdev =
14166  		dp_vdev_get_ref_by_id(dp_soc, vdev_id, DP_MOD_ID_CDP);
14167  	struct dp_peer *peer;
14168  	uint16_t new_mac_cnt = 0;
14169  
14170  	if (!vdev)
14171  		return new_mac_cnt;
14172  
14173  	if (limit && (vdev->num_peers > mac_cnt)) {
14174  		dp_vdev_unref_delete(dp_soc, vdev, DP_MOD_ID_CDP);
14175  		return 0;
14176  	}
14177  
14178  	qdf_spin_lock_bh(&vdev->peer_list_lock);
14179  	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
14180  		if (peer->bss_peer)
14181  			continue;
14182  		if (new_mac_cnt < mac_cnt) {
14183  			WLAN_ADDR_COPY(newmac[new_mac_cnt], peer->mac_addr.raw);
14184  			new_mac_cnt++;
14185  		}
14186  	}
14187  	qdf_spin_unlock_bh(&vdev->peer_list_lock);
14188  	dp_vdev_unref_delete(dp_soc, vdev, DP_MOD_ID_CDP);
14189  	return new_mac_cnt;
14190  }
14191  
dp_get_peer_id(ol_txrx_soc_handle soc,uint8_t vdev_id,uint8_t * mac)14192  uint16_t dp_get_peer_id(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *mac)
14193  {
14194  	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
14195  						       mac, 0, vdev_id,
14196  						       DP_MOD_ID_CDP);
14197  	uint16_t peer_id = HTT_INVALID_PEER;
14198  
14199  	if (!peer) {
14200  		dp_cdp_debug("%pK: Peer is NULL!", (struct dp_soc *)soc);
14201  		return peer_id;
14202  	}
14203  
14204  	peer_id = peer->peer_id;
14205  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
14206  	return peer_id;
14207  }
14208  
14209  #ifdef QCA_SUPPORT_WDS_EXTENDED
dp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc,uint8_t vdev_id,uint8_t * mac,ol_txrx_rx_fp rx,ol_osif_peer_handle osif_peer)14210  QDF_STATUS dp_wds_ext_set_peer_rx(ol_txrx_soc_handle soc,
14211  				  uint8_t vdev_id,
14212  				  uint8_t *mac,
14213  				  ol_txrx_rx_fp rx,
14214  				  ol_osif_peer_handle osif_peer)
14215  {
14216  	struct dp_txrx_peer *txrx_peer = NULL;
14217  	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
14218  						       mac, 0, vdev_id,
14219  						       DP_MOD_ID_CDP);
14220  	QDF_STATUS status = QDF_STATUS_E_INVAL;
14221  
14222  	if (!peer) {
14223  		dp_cdp_debug("%pK: Peer is NULL!", (struct dp_soc *)soc);
14224  		return status;
14225  	}
14226  
14227  	txrx_peer = dp_get_txrx_peer(peer);
14228  	if (!txrx_peer) {
14229  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
14230  		return status;
14231  	}
14232  
14233  	if (rx) {
14234  		if (txrx_peer->osif_rx) {
14235  			status = QDF_STATUS_E_ALREADY;
14236  		} else {
14237  			txrx_peer->osif_rx = rx;
14238  			status = QDF_STATUS_SUCCESS;
14239  		}
14240  	} else {
14241  		if (txrx_peer->osif_rx) {
14242  			txrx_peer->osif_rx = NULL;
14243  			status = QDF_STATUS_SUCCESS;
14244  		} else {
14245  			status = QDF_STATUS_E_ALREADY;
14246  		}
14247  	}
14248  
14249  	txrx_peer->wds_ext.osif_peer = osif_peer;
14250  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
14251  
14252  	return status;
14253  }
14254  
dp_wds_ext_get_peer_osif_handle(ol_txrx_soc_handle soc,uint8_t vdev_id,uint8_t * mac,ol_osif_peer_handle * osif_peer)14255  QDF_STATUS dp_wds_ext_get_peer_osif_handle(
14256  				ol_txrx_soc_handle soc,
14257  				uint8_t vdev_id,
14258  				uint8_t *mac,
14259  				ol_osif_peer_handle *osif_peer)
14260  {
14261  	struct dp_soc *dp_soc = (struct dp_soc *)soc;
14262  	struct dp_txrx_peer *txrx_peer = NULL;
14263  	struct dp_peer *peer = dp_peer_find_hash_find(dp_soc,
14264  						      mac, 0, vdev_id,
14265  						      DP_MOD_ID_CDP);
14266  
14267  	if (!peer) {
14268  		dp_cdp_debug("%pK: Peer is NULL!", dp_soc);
14269  		return QDF_STATUS_E_INVAL;
14270  	}
14271  
14272  	txrx_peer = dp_get_txrx_peer(peer);
14273  	if (!txrx_peer) {
14274  		dp_cdp_debug("%pK: TXRX Peer is NULL!", dp_soc);
14275  		dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
14276  		return QDF_STATUS_E_INVAL;
14277  	}
14278  
14279  	*osif_peer = txrx_peer->wds_ext.osif_peer;
14280  	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
14281  
14282  	return QDF_STATUS_SUCCESS;
14283  }
14284  
dp_wds_ext_set_peer_bit(ol_txrx_soc_handle soc,uint8_t * mac)14285  QDF_STATUS dp_wds_ext_set_peer_bit(ol_txrx_soc_handle soc, uint8_t *mac)
14286  {
14287  	struct dp_txrx_peer *txrx_peer = NULL;
14288  	struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc,
14289  						       mac, 0, DP_VDEV_ALL,
14290  						       DP_MOD_ID_IPA);
14291  	if (!peer) {
14292  		dp_cdp_debug("%pK: Peer is NULL!\n", (struct dp_soc *)soc);
14293  		return QDF_STATUS_E_INVAL;
14294  	}
14295  
14296  	txrx_peer = dp_get_txrx_peer(peer);
14297  	if (!txrx_peer) {
14298  		dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
14299  		return QDF_STATUS_E_INVAL;
14300  	}
14301  	qdf_atomic_test_and_set_bit(WDS_EXT_PEER_INIT_BIT,
14302  				    &txrx_peer->wds_ext.init);
14303  	dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
14304  
14305  	return QDF_STATUS_SUCCESS;
14306  }
14307  #endif /* QCA_SUPPORT_WDS_EXTENDED */
14308  
14309  /**
14310   * dp_pdev_srng_deinit() - de-initialize all pdev srng ring including
14311   *			   monitor rings
14312   * @pdev: Datapath pdev handle
14313   *
14314   */
dp_pdev_srng_deinit(struct dp_pdev * pdev)14315  static void dp_pdev_srng_deinit(struct dp_pdev *pdev)
14316  {
14317  	struct dp_soc *soc = pdev->soc;
14318  	uint8_t i;
14319  
14320  	if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled)
14321  		dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id],
14322  			       RXDMA_BUF,
14323  			       pdev->lmac_id);
14324  
14325  	if (!soc->rxdma2sw_rings_not_supported) {
14326  		for (i = 0;
14327  		     i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) {
14328  			int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i,
14329  								 pdev->pdev_id);
14330  
14331  			wlan_minidump_remove(soc->rxdma_err_dst_ring[lmac_id].
14332  							base_vaddr_unaligned,
14333  					     soc->rxdma_err_dst_ring[lmac_id].
14334  								alloc_size,
14335  					     soc->ctrl_psoc,
14336  					     WLAN_MD_DP_SRNG_RXDMA_ERR_DST,
14337  					     "rxdma_err_dst");
14338  			dp_srng_deinit(soc, &soc->rxdma_err_dst_ring[lmac_id],
14339  				       RXDMA_DST, lmac_id);
14340  		}
14341  	}
14342  
14343  
14344  }
14345  
14346  /**
14347   * dp_pdev_srng_init() - initialize all pdev srng rings including
14348   *			   monitor rings
14349   * @pdev: Datapath pdev handle
14350   *
14351   * Return: QDF_STATUS_SUCCESS on success
14352   *	   QDF_STATUS_E_NOMEM on failure
14353   */
dp_pdev_srng_init(struct dp_pdev * pdev)14354  static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev)
14355  {
14356  	struct dp_soc *soc = pdev->soc;
14357  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
14358  	uint32_t i;
14359  
14360  	soc_cfg_ctx = soc->wlan_cfg_ctx;
14361  
14362  	if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
14363  		if (dp_srng_init(soc, &soc->rx_refill_buf_ring[pdev->lmac_id],
14364  				 RXDMA_BUF, 0, pdev->lmac_id)) {
14365  			dp_init_err("%pK: dp_srng_init failed rx refill ring",
14366  				    soc);
14367  			goto fail1;
14368  		}
14369  	}
14370  
14371  	/* LMAC RxDMA to SW Rings configuration */
14372  	if (!wlan_cfg_per_pdev_lmac_ring(soc_cfg_ctx))
14373  		/* Only valid for MCL */
14374  		pdev = soc->pdev_list[0];
14375  
14376  	if (!soc->rxdma2sw_rings_not_supported) {
14377  		for (i = 0;
14378  		     i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) {
14379  			int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i,
14380  								 pdev->pdev_id);
14381  			struct dp_srng *srng =
14382  				&soc->rxdma_err_dst_ring[lmac_id];
14383  
14384  			if (srng->hal_srng)
14385  				continue;
14386  
14387  			if (dp_srng_init(soc, srng, RXDMA_DST, 0, lmac_id)) {
14388  				dp_init_err("%pK:" RNG_ERR "rxdma_err_dst_ring",
14389  					    soc);
14390  				goto fail1;
14391  			}
14392  			wlan_minidump_log(soc->rxdma_err_dst_ring[lmac_id].
14393  						base_vaddr_unaligned,
14394  					  soc->rxdma_err_dst_ring[lmac_id].
14395  						alloc_size,
14396  					  soc->ctrl_psoc,
14397  					  WLAN_MD_DP_SRNG_RXDMA_ERR_DST,
14398  					  "rxdma_err_dst");
14399  		}
14400  	}
14401  	return QDF_STATUS_SUCCESS;
14402  
14403  fail1:
14404  	dp_pdev_srng_deinit(pdev);
14405  	return QDF_STATUS_E_NOMEM;
14406  }
14407  
14408  /**
14409   * dp_pdev_srng_free() - free all pdev srng rings including monitor rings
14410   * @pdev: Datapath pdev handle
14411   *
14412   */
dp_pdev_srng_free(struct dp_pdev * pdev)14413  static void dp_pdev_srng_free(struct dp_pdev *pdev)
14414  {
14415  	struct dp_soc *soc = pdev->soc;
14416  	uint8_t i;
14417  
14418  	if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled)
14419  		dp_srng_free(soc, &soc->rx_refill_buf_ring[pdev->lmac_id]);
14420  
14421  	if (!soc->rxdma2sw_rings_not_supported) {
14422  		for (i = 0;
14423  		     i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) {
14424  			int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i,
14425  								 pdev->pdev_id);
14426  
14427  			dp_srng_free(soc, &soc->rxdma_err_dst_ring[lmac_id]);
14428  		}
14429  	}
14430  }
14431  
14432  /**
14433   * dp_pdev_srng_alloc() - allocate memory for all pdev srng rings including
14434   *			  monitor rings
14435   * @pdev: Datapath pdev handle
14436   *
14437   * Return: QDF_STATUS_SUCCESS on success
14438   *	   QDF_STATUS_E_NOMEM on failure
14439   */
dp_pdev_srng_alloc(struct dp_pdev * pdev)14440  static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev)
14441  {
14442  	struct dp_soc *soc = pdev->soc;
14443  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
14444  	uint32_t ring_size;
14445  	uint32_t i;
14446  
14447  	soc_cfg_ctx = soc->wlan_cfg_ctx;
14448  
14449  	ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx);
14450  	if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) {
14451  		if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[pdev->lmac_id],
14452  				  RXDMA_BUF, ring_size, 0)) {
14453  			dp_init_err("%pK: dp_srng_alloc failed rx refill ring",
14454  				    soc);
14455  			goto fail1;
14456  		}
14457  	}
14458  
14459  	ring_size = wlan_cfg_get_dp_soc_rxdma_err_dst_ring_size(soc_cfg_ctx);
14460  	/* LMAC RxDMA to SW Rings configuration */
14461  	if (!wlan_cfg_per_pdev_lmac_ring(soc_cfg_ctx))
14462  		/* Only valid for MCL */
14463  		pdev = soc->pdev_list[0];
14464  
14465  	if (!soc->rxdma2sw_rings_not_supported) {
14466  		for (i = 0;
14467  		     i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) {
14468  			int lmac_id = dp_get_lmac_id_for_pdev_id(soc, i,
14469  								 pdev->pdev_id);
14470  			struct dp_srng *srng =
14471  				&soc->rxdma_err_dst_ring[lmac_id];
14472  
14473  			if (srng->base_vaddr_unaligned)
14474  				continue;
14475  
14476  			if (dp_srng_alloc(soc, srng, RXDMA_DST, ring_size, 0)) {
14477  				dp_init_err("%pK:" RNG_ERR "rxdma_err_dst_ring",
14478  					    soc);
14479  				goto fail1;
14480  			}
14481  		}
14482  	}
14483  
14484  	return QDF_STATUS_SUCCESS;
14485  fail1:
14486  	dp_pdev_srng_free(pdev);
14487  	return QDF_STATUS_E_NOMEM;
14488  }
14489  
14490  #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT)
14491  /**
14492   * dp_init_link_peer_stats_enabled() - Init link_peer_stats as per config
14493   * @pdev: DP pdev
14494   *
14495   * Return: None
14496   */
14497  static inline void
dp_init_link_peer_stats_enabled(struct dp_pdev * pdev)14498  dp_init_link_peer_stats_enabled(struct dp_pdev *pdev)
14499  {
14500  	pdev->link_peer_stats = wlan_cfg_is_peer_link_stats_enabled(
14501  						pdev->soc->wlan_cfg_ctx);
14502  }
14503  #else
14504  static inline void
dp_init_link_peer_stats_enabled(struct dp_pdev * pdev)14505  dp_init_link_peer_stats_enabled(struct dp_pdev *pdev)
14506  {
14507  }
14508  #endif
14509  
dp_pdev_init(struct cdp_soc_t * txrx_soc,HTC_HANDLE htc_handle,qdf_device_t qdf_osdev,uint8_t pdev_id)14510  static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc,
14511  				      HTC_HANDLE htc_handle,
14512  				      qdf_device_t qdf_osdev,
14513  				      uint8_t pdev_id)
14514  {
14515  	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
14516  	int nss_cfg;
14517  	void *sojourn_buf;
14518  
14519  	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
14520  	struct dp_pdev *pdev = soc->pdev_list[pdev_id];
14521  
14522  	soc_cfg_ctx = soc->wlan_cfg_ctx;
14523  	pdev->soc = soc;
14524  	pdev->pdev_id = pdev_id;
14525  
14526  	/*
14527  	 * Variable to prevent double pdev deinitialization during
14528  	 * radio detach execution .i.e. in the absence of any vdev.
14529  	 */
14530  	pdev->pdev_deinit = 0;
14531  
14532  	if (dp_wdi_event_attach(pdev)) {
14533  		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
14534  			  "dp_wdi_evet_attach failed");
14535  		goto fail0;
14536  	}
14537  
14538  	if (dp_pdev_srng_init(pdev)) {
14539  		dp_init_err("%pK: Failed to initialize pdev srng rings", soc);
14540  		goto fail1;
14541  	}
14542  
14543  	/* Initialize descriptors in TCL Rings used by IPA */
14544  	if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) {
14545  		hal_tx_init_data_ring(soc->hal_soc,
14546  				      soc->tcl_data_ring[IPA_TCL_DATA_RING_IDX].hal_srng);
14547  		dp_ipa_hal_tx_init_alt_data_ring(soc);
14548  	}
14549  
14550  	/*
14551  	 * Initialize command/credit ring descriptor
14552  	 * Command/CREDIT ring also used for sending DATA cmds
14553  	 */
14554  	dp_tx_init_cmd_credit_ring(soc);
14555  
14556  	dp_tx_pdev_init(pdev);
14557  
14558  	/*
14559  	 * set nss pdev config based on soc config
14560  	 */
14561  	nss_cfg = wlan_cfg_get_dp_soc_nss_cfg(soc_cfg_ctx);
14562  	wlan_cfg_set_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx,
14563  					 (nss_cfg & (1 << pdev_id)));
14564  	pdev->target_pdev_id =
14565  		dp_calculate_target_pdev_id_from_host_pdev_id(soc, pdev_id);
14566  
14567  	if (soc->preferred_hw_mode == WMI_HOST_HW_MODE_2G_PHYB &&
14568  	    pdev->lmac_id == PHYB_2G_LMAC_ID) {
14569  		pdev->target_pdev_id = PHYB_2G_TARGET_PDEV_ID;
14570  	}
14571  
14572  	/* Reset the cpu ring map if radio is NSS offloaded */
14573  	if (wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx)) {
14574  		dp_soc_reset_cpu_ring_map(soc);
14575  		dp_soc_reset_intr_mask(soc);
14576  	}
14577  
14578  	/* Reset the ring interrupt mask if DPDK is enabled */
14579  	if (wlan_cfg_get_dp_soc_dpdk_cfg(soc->ctrl_psoc)) {
14580  		dp_soc_reset_dpdk_intr_mask(soc);
14581  	}
14582  	/* Reset the cpu ring map if radio is NSS offloaded */
14583  	dp_soc_reset_ipa_vlan_intr_mask(soc);
14584  
14585  	TAILQ_INIT(&pdev->vdev_list);
14586  	qdf_spinlock_create(&pdev->vdev_list_lock);
14587  	pdev->vdev_count = 0;
14588  	pdev->is_lro_hash_configured = 0;
14589  
14590  	qdf_spinlock_create(&pdev->tx_mutex);
14591  	pdev->ch_band_lmac_id_mapping[REG_BAND_2G] = DP_MON_INVALID_LMAC_ID;
14592  	pdev->ch_band_lmac_id_mapping[REG_BAND_5G] = DP_MON_INVALID_LMAC_ID;
14593  	pdev->ch_band_lmac_id_mapping[REG_BAND_6G] = DP_MON_INVALID_LMAC_ID;
14594  
14595  	DP_STATS_INIT(pdev);
14596  
14597  	dp_local_peer_id_pool_init(pdev);
14598  
14599  	dp_dscp_tid_map_setup(pdev);
14600  	dp_pcp_tid_map_setup(pdev);
14601  
14602  	/* set the reo destination during initialization */
14603  	dp_pdev_set_default_reo(pdev);
14604  
14605  	qdf_mem_zero(&pdev->sojourn_stats, sizeof(struct cdp_tx_sojourn_stats));
14606  
14607  	pdev->sojourn_buf = qdf_nbuf_alloc(pdev->soc->osdev,
14608  			      sizeof(struct cdp_tx_sojourn_stats), 0, 4,
14609  			      TRUE);
14610  
14611  	if (!pdev->sojourn_buf) {
14612  		dp_init_err("%pK: Failed to allocate sojourn buf", soc);
14613  		goto fail2;
14614  	}
14615  	sojourn_buf = qdf_nbuf_data(pdev->sojourn_buf);
14616  	qdf_mem_zero(sojourn_buf, sizeof(struct cdp_tx_sojourn_stats));
14617  
14618  	qdf_event_create(&pdev->fw_peer_stats_event);
14619  	qdf_event_create(&pdev->fw_stats_event);
14620  	qdf_event_create(&pdev->fw_obss_stats_event);
14621  
14622  	pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
14623  	pdev->num_tx_spl_allowed =
14624  		wlan_cfg_get_num_tx_spl_desc(soc->wlan_cfg_ctx);
14625  	pdev->num_reg_tx_allowed =
14626  		pdev->num_tx_allowed - pdev->num_tx_spl_allowed;
14627  	if (dp_rxdma_ring_setup(soc, pdev)) {
14628  		dp_init_err("%pK: RXDMA ring config failed", soc);
14629  		goto fail3;
14630  	}
14631  
14632  	if (dp_init_ipa_rx_refill_buf_ring(soc, pdev))
14633  		goto fail3;
14634  
14635  	if (dp_ipa_ring_resource_setup(soc, pdev))
14636  		goto fail4;
14637  
14638  	if (dp_ipa_uc_attach(soc, pdev) != QDF_STATUS_SUCCESS) {
14639  		dp_init_err("%pK: dp_ipa_uc_attach failed", soc);
14640  		goto fail4;
14641  	}
14642  
14643  	if (dp_pdev_bkp_stats_attach(pdev) != QDF_STATUS_SUCCESS) {
14644  		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
14645  			  FL("dp_pdev_bkp_stats_attach failed"));
14646  		goto fail5;
14647  	}
14648  
14649  	if (dp_monitor_pdev_init(pdev)) {
14650  		dp_init_err("%pK: dp_monitor_pdev_init failed", soc);
14651  		goto fail6;
14652  	}
14653  
14654  	/* initialize sw rx descriptors */
14655  	dp_rx_pdev_desc_pool_init(pdev);
14656  	/* allocate buffers and replenish the RxDMA ring */
14657  	dp_rx_pdev_buffers_alloc(pdev);
14658  
14659  	dp_init_tso_stats(pdev);
14660  	dp_init_link_peer_stats_enabled(pdev);
14661  
14662  	/* Initialize dp tx fast path flag */
14663  	pdev->tx_fast_flag = DP_TX_DESC_FLAG_SIMPLE;
14664  	if (soc->hw_txrx_stats_en)
14665  		pdev->tx_fast_flag |= DP_TX_DESC_FLAG_FASTPATH_SIMPLE;
14666  
14667  	pdev->rx_fast_flag = false;
14668  	dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u",
14669  		qdf_dma_mem_stats_read(),
14670  		qdf_heap_mem_stats_read(),
14671  		qdf_skb_total_mem_stats_read());
14672  
14673  	return QDF_STATUS_SUCCESS;
14674  fail6:
14675  	dp_pdev_bkp_stats_detach(pdev);
14676  fail5:
14677  	dp_ipa_uc_detach(soc, pdev);
14678  fail4:
14679  	dp_deinit_ipa_rx_refill_buf_ring(soc, pdev);
14680  fail3:
14681  	dp_rxdma_ring_cleanup(soc, pdev);
14682  	qdf_nbuf_free(pdev->sojourn_buf);
14683  fail2:
14684  	qdf_spinlock_destroy(&pdev->tx_mutex);
14685  	qdf_spinlock_destroy(&pdev->vdev_list_lock);
14686  	dp_pdev_srng_deinit(pdev);
14687  fail1:
14688  	dp_wdi_event_detach(pdev);
14689  fail0:
14690  	return QDF_STATUS_E_FAILURE;
14691  }
14692  
14693  /**
14694   * dp_pdev_init_wifi3() - Init txrx pdev
14695   * @txrx_soc:
14696   * @htc_handle: HTC handle for host-target interface
14697   * @qdf_osdev: QDF OS device
14698   * @pdev_id: pdev Id
14699   *
14700   * Return: QDF_STATUS
14701   */
dp_pdev_init_wifi3(struct cdp_soc_t * txrx_soc,HTC_HANDLE htc_handle,qdf_device_t qdf_osdev,uint8_t pdev_id)14702  static QDF_STATUS dp_pdev_init_wifi3(struct cdp_soc_t *txrx_soc,
14703  				     HTC_HANDLE htc_handle,
14704  				     qdf_device_t qdf_osdev,
14705  				     uint8_t pdev_id)
14706  {
14707  	return dp_pdev_init(txrx_soc, htc_handle, qdf_osdev, pdev_id);
14708  }
14709  
14710  #ifdef FEATURE_DIRECT_LINK
dp_setup_direct_link_refill_ring(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)14711  struct dp_srng *dp_setup_direct_link_refill_ring(struct cdp_soc_t *soc_hdl,
14712  						 uint8_t pdev_id)
14713  {
14714  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
14715  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
14716  
14717  	if (!pdev) {
14718  		dp_err("DP pdev is NULL");
14719  		return NULL;
14720  	}
14721  
14722  	if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring4,
14723  			  RXDMA_BUF, DIRECT_LINK_REFILL_RING_ENTRIES, false)) {
14724  		dp_err("SRNG alloc failed for rx_refill_buf_ring4");
14725  		return NULL;
14726  	}
14727  
14728  	if (dp_srng_init(soc, &pdev->rx_refill_buf_ring4,
14729  			 RXDMA_BUF, DIRECT_LINK_REFILL_RING_IDX, 0)) {
14730  		dp_err("SRNG init failed for rx_refill_buf_ring4");
14731  		dp_srng_free(soc, &pdev->rx_refill_buf_ring4);
14732  		return NULL;
14733  	}
14734  
14735  	if (htt_srng_setup(soc->htt_handle, pdev_id,
14736  			   pdev->rx_refill_buf_ring4.hal_srng, RXDMA_BUF)) {
14737  		dp_srng_deinit(soc, &pdev->rx_refill_buf_ring4, RXDMA_BUF,
14738  			       DIRECT_LINK_REFILL_RING_IDX);
14739  		dp_srng_free(soc, &pdev->rx_refill_buf_ring4);
14740  		return NULL;
14741  	}
14742  
14743  	return &pdev->rx_refill_buf_ring4;
14744  }
14745  
dp_destroy_direct_link_refill_ring(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)14746  void dp_destroy_direct_link_refill_ring(struct cdp_soc_t *soc_hdl,
14747  					uint8_t pdev_id)
14748  {
14749  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
14750  	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
14751  
14752  	if (!pdev) {
14753  		dp_err("DP pdev is NULL");
14754  		return;
14755  	}
14756  
14757  	dp_srng_deinit(soc, &pdev->rx_refill_buf_ring4, RXDMA_BUF, 0);
14758  	dp_srng_free(soc, &pdev->rx_refill_buf_ring4);
14759  }
14760  #endif
14761  
14762  #ifdef QCA_MULTIPASS_SUPPORT
dp_set_vlan_groupkey(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint16_t vlan_id,uint16_t group_key)14763  QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
14764  				uint16_t vlan_id, uint16_t group_key)
14765  {
14766  	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
14767  	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
14768  						     DP_MOD_ID_TX_MULTIPASS);
14769  	QDF_STATUS status;
14770  
14771  	dp_info("Try: vdev_id %d, vdev %pK, multipass_en %d, vlan_id %d, group_key %d",
14772  		vdev_id, vdev, vdev ? vdev->multipass_en : 0, vlan_id,
14773  		group_key);
14774  	if (!vdev || !vdev->multipass_en) {
14775  		status = QDF_STATUS_E_INVAL;
14776  		goto fail;
14777  	}
14778  
14779  	if (!vdev->iv_vlan_map) {
14780  		uint16_t vlan_map_size = (sizeof(uint16_t)) * DP_MAX_VLAN_IDS;
14781  
14782  		vdev->iv_vlan_map = (uint16_t *)qdf_mem_malloc(vlan_map_size);
14783  		if (!vdev->iv_vlan_map) {
14784  			QDF_TRACE_ERROR(QDF_MODULE_ID_DP, "iv_vlan_map");
14785  			status = QDF_STATUS_E_NOMEM;
14786  			goto fail;
14787  		}
14788  
14789  		/*
14790  		 * 0 is invalid group key.
14791  		 * Initilalize array with invalid group keys.
14792  		 */
14793  		qdf_mem_zero(vdev->iv_vlan_map, vlan_map_size);
14794  	}
14795  
14796  	if (vlan_id >= DP_MAX_VLAN_IDS) {
14797  		status = QDF_STATUS_E_INVAL;
14798  		goto fail;
14799  	}
14800  
14801  	dp_info("Successful setting: vdev_id %d, vlan_id %d, group_key %d",
14802  		vdev_id, vlan_id, group_key);
14803  	vdev->iv_vlan_map[vlan_id] = group_key;
14804  	status = QDF_STATUS_SUCCESS;
14805  fail:
14806  	if (vdev)
14807  		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_TX_MULTIPASS);
14808  	return status;
14809  }
14810  
dp_tx_remove_vlan_tag(struct dp_vdev * vdev,qdf_nbuf_t nbuf)14811  void dp_tx_remove_vlan_tag(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
14812  {
14813  	struct vlan_ethhdr veth_hdr;
14814  	struct vlan_ethhdr *veh = (struct vlan_ethhdr *)nbuf->data;
14815  
14816  	/*
14817  	 * Extract VLAN header of 4 bytes:
14818  	 * Frame Format : {dst_addr[6], src_addr[6], 802.1Q header[4],
14819  	 *		   EtherType[2], Payload}
14820  	 * Before Removal : xx xx xx xx xx xx xx xx xx xx xx xx 81 00 00 02
14821  	 *		    08 00 45 00 00...
14822  	 * After Removal  : xx xx xx xx xx xx xx xx xx xx xx xx 08 00 45 00
14823  	 *		    00...
14824  	 */
14825  	qdf_mem_copy(&veth_hdr, veh, sizeof(veth_hdr));
14826  	qdf_nbuf_pull_head(nbuf, ETHERTYPE_VLAN_LEN);
14827  	veh = (struct vlan_ethhdr *)nbuf->data;
14828  	qdf_mem_copy(veh, &veth_hdr, 2 * QDF_MAC_ADDR_SIZE);
14829  }
14830  
dp_tx_vdev_multipass_deinit(struct dp_vdev * vdev)14831  void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev)
14832  {
14833  	struct dp_txrx_peer *txrx_peer = NULL;
14834  
14835  	qdf_spin_lock_bh(&vdev->mpass_peer_mutex);
14836  	TAILQ_FOREACH(txrx_peer, &vdev->mpass_peer_list, mpass_peer_list_elem)
14837  		qdf_err("Peers present in mpass list : %d", txrx_peer->peer_id);
14838  	qdf_spin_unlock_bh(&vdev->mpass_peer_mutex);
14839  
14840  	if (vdev->iv_vlan_map) {
14841  		qdf_mem_free(vdev->iv_vlan_map);
14842  		vdev->iv_vlan_map = NULL;
14843  	}
14844  
14845  	qdf_spinlock_destroy(&vdev->mpass_peer_mutex);
14846  }
14847  
dp_peer_multipass_list_init(struct dp_vdev * vdev)14848  void dp_peer_multipass_list_init(struct dp_vdev *vdev)
14849  {
14850  	/*
14851  	 * vdev->iv_vlan_map is allocated when the first configuration command
14852  	 * is issued to avoid unnecessary allocation for regular mode VAP.
14853  	 */
14854  	TAILQ_INIT(&vdev->mpass_peer_list);
14855  	qdf_spinlock_create(&vdev->mpass_peer_mutex);
14856  }
14857  #endif /* QCA_MULTIPASS_SUPPORT */
14858  
14859  #ifdef WLAN_FEATURE_SSR_DRIVER_DUMP
14860  #define MAX_STR_LEN 50
14861  #define MAX_SRNG_STR_LEN 30
14862  
dp_ssr_dump_srng_register(char * region_name,struct dp_srng * srng,int num)14863  void dp_ssr_dump_srng_register(char *region_name, struct dp_srng *srng, int num)
14864  {
14865  	char ring[MAX_SRNG_STR_LEN], ring_handle[MAX_STR_LEN];
14866  
14867  	if (num >= 0)
14868  		qdf_snprint(ring, MAX_SRNG_STR_LEN, "%s%s%d",
14869  			    region_name, "_", num);
14870  	else
14871  		qdf_snprint(ring, MAX_SRNG_STR_LEN, "%s", region_name);
14872  
14873  	qdf_snprint(ring_handle, MAX_STR_LEN, "%s%s", ring, "_handle");
14874  
14875  	qdf_ssr_driver_dump_register_region(ring_handle, srng->hal_srng,
14876  					    sizeof(struct hal_srng));
14877  	qdf_ssr_driver_dump_register_region(ring,
14878  					    srng->base_vaddr_aligned,
14879  					    srng->alloc_size);
14880  }
14881  
dp_ssr_dump_srng_unregister(char * region_name,int num)14882  void dp_ssr_dump_srng_unregister(char *region_name, int num)
14883  {
14884  	char ring[MAX_SRNG_STR_LEN], ring_handle[MAX_STR_LEN];
14885  
14886  	if (num >= 0)
14887  		qdf_snprint(ring, MAX_SRNG_STR_LEN, "%s%s%d",
14888  			    region_name, "_", num);
14889  	else
14890  		qdf_snprint(ring, MAX_SRNG_STR_LEN, "%s", region_name);
14891  
14892  	qdf_snprint(ring_handle, MAX_STR_LEN, "%s%s", ring, "_handle");
14893  
14894  	qdf_ssr_driver_dump_unregister_region(ring);
14895  	qdf_ssr_driver_dump_unregister_region(ring_handle);
14896  }
14897  
dp_ssr_dump_pdev_register(struct dp_pdev * pdev,uint8_t pdev_id)14898  void dp_ssr_dump_pdev_register(struct dp_pdev *pdev, uint8_t pdev_id)
14899  {
14900  	char pdev_str[MAX_STR_LEN];
14901  
14902  	qdf_snprint(pdev_str, MAX_STR_LEN, "%s%s%d", "dp_pdev", "_", pdev_id);
14903  	qdf_ssr_driver_dump_register_region(pdev_str, pdev, sizeof(*pdev));
14904  }
14905  
dp_ssr_dump_pdev_unregister(uint8_t pdev_id)14906  void dp_ssr_dump_pdev_unregister(uint8_t pdev_id)
14907  {
14908  	char pdev_str[MAX_STR_LEN];
14909  
14910  	qdf_snprint(pdev_str, MAX_STR_LEN, "%s%s%d", "dp_pdev", "_", pdev_id);
14911  	qdf_ssr_driver_dump_unregister_region(pdev_str);
14912  }
14913  #endif
14914