xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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 "target_if.h"
21 #include "wlan_lmac_if_def.h"
22 #include "target_if_direct_buf_rx_main.h"
23 #include <target_if_direct_buf_rx_api.h>
24 #include "hal_api.h"
25 #include <service_ready_util.h>
26 #include <init_deinit_lmac.h>
27 
28 /**
29  * struct module_name : Module name information structure
30  * @module_name_str : Module name subscribing to DBR
31  */
32 struct module_name {
33 	unsigned char module_name_str[QDF_MAX_NAME_SIZE];
34 };
35 
36 static const struct module_name g_dbr_module_name[DBR_MODULE_MAX] = {
37 	[DBR_MODULE_SPECTRAL] = {"SPECTRAL"},
38 	[DBR_MODULE_CFR]      = {"CFR"},
39 };
40 
41 static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev)
42 {
43 	struct wlan_objmgr_psoc *psoc;
44 	struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap;
45 	uint8_t num_dbr_ring_caps, cap_idx, pdev_id, num_modules;
46 	struct target_psoc_info *tgt_psoc_info;
47 
48 	psoc = wlan_pdev_get_psoc(pdev);
49 
50 	if (!psoc) {
51 		direct_buf_rx_err("psoc is null");
52 		return 0;
53 	}
54 
55 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
56 	if (!tgt_psoc_info) {
57 		direct_buf_rx_err("target_psoc_info is null");
58 		return 0;
59 	}
60 	num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info);
61 	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
62 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
63 	num_modules = 0;
64 
65 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
66 		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id)
67 			num_modules++;
68 	}
69 
70 	return num_modules;
71 }
72 
73 static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev,
74 			struct direct_buf_rx_module_param *mod_param)
75 {
76 	struct wlan_objmgr_psoc *psoc;
77 	struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap;
78 	uint8_t cap_idx;
79 	bool cap_found = false;
80 	enum DBR_MODULE mod_id = mod_param->mod_id;
81 	uint32_t num_dbr_ring_caps, pdev_id;
82 	struct target_psoc_info *tgt_psoc_info;
83 
84 	psoc = wlan_pdev_get_psoc(pdev);
85 
86 	if (!psoc) {
87 		direct_buf_rx_err("psoc is null");
88 		return QDF_STATUS_E_INVAL;
89 	}
90 
91 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
92 	if (!tgt_psoc_info) {
93 		direct_buf_rx_err("target_psoc_info is null");
94 		return QDF_STATUS_E_INVAL;
95 	}
96 
97 	num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info);
98 	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
99 	pdev_id = mod_param->pdev_id;
100 
101 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
102 		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) {
103 			if (dbr_ring_cap[cap_idx].mod_id == mod_id) {
104 				mod_param->dbr_ring_cap->ring_elems_min =
105 					dbr_ring_cap[cap_idx].ring_elems_min;
106 				mod_param->dbr_ring_cap->min_buf_size =
107 					dbr_ring_cap[cap_idx].min_buf_size;
108 				mod_param->dbr_ring_cap->min_buf_align =
109 					dbr_ring_cap[cap_idx].min_buf_align;
110 				cap_found = true;
111 			}
112 		}
113 	}
114 
115 	if (!cap_found) {
116 		direct_buf_rx_err("No cap found for module %d in pdev %d",
117 				  mod_id, pdev_id);
118 		return QDF_STATUS_E_FAILURE;
119 	}
120 
121 	return QDF_STATUS_SUCCESS;
122 }
123 #ifdef DIRECT_BUF_RX_DEBUG
124 static inline struct direct_buf_rx_module_debug *
125 target_if_get_dbr_mod_debug_from_dbr_pdev_obj(
126 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
127 	uint8_t mod_id)
128 {
129 	if (!dbr_pdev_obj) {
130 		direct_buf_rx_err("dir buf rx object is null");
131 		return NULL;
132 	}
133 
134 	if (mod_id >= DBR_MODULE_MAX) {
135 		direct_buf_rx_err("Invalid module id");
136 		return NULL;
137 	}
138 
139 	if (!dbr_pdev_obj->dbr_mod_debug) {
140 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_debug is NULL");
141 		return NULL;
142 	}
143 
144 	if (mod_id >= dbr_pdev_obj->num_modules) {
145 		direct_buf_rx_err("Module %d not supported in target", mod_id);
146 		return NULL;
147 	}
148 	return &dbr_pdev_obj->dbr_mod_debug[mod_id];
149 }
150 
151 static inline struct direct_buf_rx_module_debug *
152 target_if_get_dbr_mod_debug_from_pdev(
153 	struct wlan_objmgr_pdev *pdev,
154 	uint8_t mod_id)
155 {
156 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
157 
158 	if (!pdev) {
159 		direct_buf_rx_err("pdev is null");
160 		return NULL;
161 	}
162 
163 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
164 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
165 
166 	return target_if_get_dbr_mod_debug_from_dbr_pdev_obj(
167 				dbr_pdev_obj, mod_id);
168 }
169 #endif
170 
171 #ifdef DIRECT_BUF_RX_DEBUG
172 #define RING_DEBUG_EVENT_NAME_SIZE 12
173 static const unsigned char
174 g_dbr_ring_debug_event[DBR_RING_DEBUG_EVENT_MAX][RING_DEBUG_EVENT_NAME_SIZE] = {
175 	[DBR_RING_DEBUG_EVENT_RX]                  = "Rx",
176 	[DBR_RING_DEBUG_EVENT_REPLENISH_RING]      = "Replenish",
177 };
178 
179 /**
180  * target_if_dbr_print_ring_debug_entries() - Print ring debug entries
181  * @print: The print adapter function
182  * @print_priv: The private data to be consumed by @print
183  * @dbr_pdev_obj: Pdev object of the DBR module
184  * @mod_id: Module ID
185  *
186  * Print ring debug entries of the ring identified by @dbr_pdev_obj and @mod_id
187  * using the  given print adapter function
188  *
189  * Return: QDF_STATUS of operation
190  */
191 static QDF_STATUS target_if_dbr_print_ring_debug_entries(
192 	qdf_abstract_print print, void *print_priv,
193 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
194 	uint8_t mod_id, uint8_t srng_id)
195 {
196 	struct direct_buf_rx_module_debug *mod_debug;
197 	struct direct_buf_rx_ring_debug *ring_debug;
198 	int idx;
199 
200 	mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj,
201 								  mod_id);
202 	if (!mod_debug)
203 		return QDF_STATUS_E_INVAL;
204 
205 	mod_debug = &dbr_pdev_obj->dbr_mod_debug[mod_id];
206 	ring_debug = &mod_debug->dbr_ring_debug[srng_id];
207 
208 	if (ring_debug->entries) {
209 		print(print_priv, "Current debug entry is %d",
210 		      ring_debug->ring_debug_idx);
211 		print(print_priv, "---------------------------------------------------------");
212 		print(print_priv, "| Number | Head Idx | Tail Idx | Timestamp |    event   |");
213 		print(print_priv, "---------------------------------------------------------");
214 		for (idx = 0; idx < ring_debug->num_ring_debug_entries; ++idx) {
215 			print(print_priv, "|%8u|%10u|%10u|%11llu|%12s|", idx,
216 			      ring_debug->entries[idx].head_idx,
217 			      ring_debug->entries[idx].tail_idx,
218 			      ring_debug->entries[idx].timestamp,
219 			      g_dbr_ring_debug_event[
220 				ring_debug->entries[idx].event]);
221 		}
222 		print(print_priv, "---------------------------------------------------------");
223 	}
224 
225 	return QDF_STATUS_SUCCESS;
226 }
227 
228 /**
229  * target_if_dbr_qdf_err_printer() - QDF error level printer for DBR module
230  * @print_priv: The private data
231  * @fmt: Format string
232  *
233  * This function should be passed in place of the 'print' argument to
234  * target_if_dbr_print_ring_debug_entries function for the logs that should be
235  * printed via QDF trace
236  *
237  * Return: QDF_STATUS of operation
238  */
239 static int target_if_dbr_qdf_err_printer(void *priv, const char *fmt, ...)
240 {
241 	va_list args;
242 
243 	va_start(args, fmt);
244 	QDF_VTRACE(QDF_MODULE_ID_DIRECT_BUF_RX, QDF_TRACE_LEVEL_ERROR,
245 		   (char *)fmt, args);
246 	va_end(args);
247 
248 	return 0;
249 }
250 
251 static inline void target_if_direct_buf_rx_free_mod_debug(
252 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
253 {
254 	if (!dbr_pdev_obj) {
255 		direct_buf_rx_err("dir buf rx object is null");
256 		return;
257 	}
258 	/* Free the debug data structures of all modules */
259 	if (dbr_pdev_obj->dbr_mod_debug) {
260 		qdf_mem_free(dbr_pdev_obj->dbr_mod_debug);
261 		dbr_pdev_obj->dbr_mod_debug = NULL;
262 	}
263 }
264 
265 static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug(
266 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
267 {
268 	if (!dbr_pdev_obj) {
269 		direct_buf_rx_err("dir buf rx object is null");
270 		return QDF_STATUS_E_FAILURE;
271 	}
272 	/* Allocate the debug data structure for each module */
273 	dbr_pdev_obj->dbr_mod_debug = qdf_mem_malloc(
274 				dbr_pdev_obj->num_modules *
275 				sizeof(struct direct_buf_rx_module_debug));
276 
277 	if (!dbr_pdev_obj->dbr_mod_debug)
278 		return QDF_STATUS_E_NOMEM;
279 
280 	return QDF_STATUS_SUCCESS;
281 }
282 #else
283 static inline QDF_STATUS target_if_direct_buf_rx_alloc_mod_debug(
284 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
285 {
286 	return QDF_STATUS_SUCCESS;
287 }
288 
289 static inline void target_if_direct_buf_rx_free_mod_debug(
290 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
291 {
292 }
293 #endif
294 
295 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG)
296 static inline void target_if_direct_buf_pdev_debugfs_init(
297 	struct wlan_objmgr_pdev *pdev)
298 {
299 	char dir_name[32];
300 	struct wlan_objmgr_psoc *psoc;
301 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
302 
303 	if (!pdev) {
304 		direct_buf_rx_err("pdev is null");
305 		return;
306 	}
307 
308 	psoc = wlan_pdev_get_psoc(pdev);
309 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
310 		pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
311 
312 	if (!dbr_pdev_obj) {
313 		direct_buf_rx_err("dir buf rx object is null");
314 		return;
315 	}
316 
317 	qdf_snprintf(dir_name, sizeof(dir_name), "SOC%u_PDEV%u",
318 		     wlan_psoc_get_id(psoc),
319 		     wlan_objmgr_pdev_get_pdev_id(pdev));
320 
321 	/* Create debugfs entry for this radio */
322 	dbr_pdev_obj->debugfs_entry = qdf_debugfs_create_dir(
323 					dir_name, dbr_debugfs_entry);
324 
325 	if (!dbr_pdev_obj->debugfs_entry)
326 		direct_buf_rx_err("error while creating direct_buf debugfs dir");
327 }
328 
329 static inline void target_if_direct_buf_pdev_debugfs_deinit(
330 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
331 {
332 	if (!dbr_pdev_obj) {
333 		direct_buf_rx_err("dir buf rx object is null");
334 		return;
335 	}
336 	/* Remove the debugfs entry of the radio */
337 	if (dbr_pdev_obj->debugfs_entry) {
338 		qdf_debugfs_remove_dir_recursive(dbr_pdev_obj->debugfs_entry);
339 		dbr_pdev_obj->debugfs_entry = NULL;
340 	}
341 }
342 #else
343 static inline void target_if_direct_buf_pdev_debugfs_init(
344 	struct wlan_objmgr_pdev *pdev)
345 {
346 }
347 
348 static inline void target_if_direct_buf_pdev_debugfs_deinit(
349 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj)
350 {
351 }
352 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */
353 
354 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler(
355 	struct wlan_objmgr_pdev *pdev, void *data)
356 {
357 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
358 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
359 	struct wlan_objmgr_psoc *psoc;
360 	uint8_t num_modules;
361 	QDF_STATUS status;
362 
363 	direct_buf_rx_enter();
364 
365 	if (!pdev) {
366 		direct_buf_rx_err("pdev context passed is null");
367 		return QDF_STATUS_E_INVAL;
368 	}
369 
370 	psoc = wlan_pdev_get_psoc(pdev);
371 
372 	if (!psoc) {
373 		direct_buf_rx_err("psoc is null");
374 		return QDF_STATUS_E_INVAL;
375 	}
376 
377 	dbr_psoc_obj =
378 	wlan_objmgr_psoc_get_comp_private_obj(psoc,
379 					      WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
380 
381 	if (!dbr_psoc_obj) {
382 		direct_buf_rx_err("dir buf rx psoc object is null");
383 		return QDF_STATUS_E_FAILURE;
384 	}
385 
386 	dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj));
387 
388 	if (!dbr_pdev_obj)
389 		return QDF_STATUS_E_NOMEM;
390 
391 	status = wlan_objmgr_pdev_component_obj_attach(pdev,
392 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
393 					dbr_pdev_obj, QDF_STATUS_SUCCESS);
394 
395 	if (status != QDF_STATUS_SUCCESS) {
396 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
397 				  status);
398 		qdf_mem_free(dbr_pdev_obj);
399 		return status;
400 	}
401 
402 	dbr_psoc_obj->dbr_pdev_obj[wlan_objmgr_pdev_get_pdev_id(pdev)] =
403 								dbr_pdev_obj;
404 
405 	num_modules = get_num_dbr_modules_per_pdev(pdev);
406 	direct_buf_rx_debug("Number of modules = %d pdev %d DBR pdev obj %pK",
407 			    num_modules, wlan_objmgr_pdev_get_pdev_id(pdev),
408 			    dbr_pdev_obj);
409 	dbr_pdev_obj->num_modules = num_modules;
410 
411 	if (!dbr_pdev_obj->num_modules) {
412 		direct_buf_rx_info("Number of modules = %d", num_modules);
413 		return QDF_STATUS_SUCCESS;
414 	}
415 
416 	direct_buf_rx_debug("sring number = %d", DBR_SRNG_NUM);
417 	dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules *
418 				DBR_SRNG_NUM *
419 				sizeof(struct direct_buf_rx_module_param));
420 
421 	if (!dbr_pdev_obj->dbr_mod_param) {
422 		direct_buf_rx_err("alloc dbr mod param fail");
423 		goto dbr_mod_param_fail;
424 	}
425 
426 	if (target_if_direct_buf_rx_alloc_mod_debug(dbr_pdev_obj) !=
427 		QDF_STATUS_SUCCESS)
428 		goto dbr_mod_debug_fail;
429 
430 	target_if_direct_buf_pdev_debugfs_init(pdev);
431 
432 	return QDF_STATUS_SUCCESS;
433 
434 dbr_mod_debug_fail:
435 	qdf_mem_free(dbr_pdev_obj->dbr_mod_param);
436 
437 dbr_mod_param_fail:
438 	wlan_objmgr_pdev_component_obj_detach(
439 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
440 				dbr_pdev_obj);
441 	qdf_mem_free(dbr_pdev_obj);
442 
443 	return QDF_STATUS_E_NOMEM;
444 }
445 
446 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler(
447 	struct wlan_objmgr_pdev *pdev, void *data)
448 {
449 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
450 	QDF_STATUS status;
451 	uint8_t num_modules, mod_idx, srng_id;
452 
453 	if (!pdev) {
454 		direct_buf_rx_err("pdev context passed is null");
455 		return QDF_STATUS_E_INVAL;
456 	}
457 
458 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
459 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
460 
461 	if (!dbr_pdev_obj) {
462 		direct_buf_rx_err("dir buf rx object is null");
463 		return QDF_STATUS_E_FAILURE;
464 	}
465 
466 	num_modules = dbr_pdev_obj->num_modules;
467 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
468 		/*
469 		 * If the module didn't stop the ring debug by this time,
470 		 * it will result in memory leak of its ring debug entries.
471 		 * So, stop the ring debug
472 		 */
473 		target_if_dbr_stop_ring_debug(pdev, mod_idx);
474 		for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++)
475 			target_if_deinit_dbr_ring(pdev, dbr_pdev_obj,
476 						  mod_idx, srng_id);
477 	}
478 
479 	target_if_direct_buf_pdev_debugfs_deinit(dbr_pdev_obj);
480 	target_if_direct_buf_rx_free_mod_debug(dbr_pdev_obj);
481 	qdf_mem_free(dbr_pdev_obj->dbr_mod_param);
482 	dbr_pdev_obj->dbr_mod_param = NULL;
483 
484 	status = wlan_objmgr_pdev_component_obj_detach(pdev,
485 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
486 					dbr_pdev_obj);
487 
488 	if (status != QDF_STATUS_SUCCESS) {
489 		direct_buf_rx_err("failed to detach dir buf rx component %d",
490 				  status);
491 	}
492 
493 	qdf_mem_free(dbr_pdev_obj);
494 
495 	return status;
496 }
497 
498 #if defined(DBR_HOLD_LARGE_MEM) && defined(CNSS_MEM_PRE_ALLOC)
499 /**
500  * struct direct_buf_rx_large_mem - large memory for DBR
501  * @node: large memory node
502  * @size: Size of the memory
503  * @vaddr_unaligned: unaligned base address of the memory
504  * @offset: offset between unaligned vaddr and aligned vaddr
505  * @align: Base address alignment
506  */
507 struct direct_buf_rx_large_mem {
508 	qdf_list_node_t node;
509 	uint32_t size;
510 	void *vaddr_unaligned;
511 	uint8_t offset;
512 	uint32_t align;
513 };
514 
515 /* check if the actual buffer_size/base_address_alignment match the request */
516 #define DBR_MEM_NODE_MATCH(_actual_align, _actual_size, _req_align, _req_size) \
517 	((_actual_align) == (_req_align) && \
518 	 ((_actual_size) == (_req_size) || \
519 	  (_actual_size) == ((_req_size) + (_req_align) - 1)))
520 
521 /*
522  * Memory with a size(in bytes) equal or larger than this threshold will be
523  * hold during the entire PSOC lifetime.
524  * MUST equal or larger than the allocation threshold in cnss_prealloc module.
525  */
526 #define TARGET_IF_DBR_HOLD_MEM_THRESHOLD (8 * 1024)
527 
528 /**
529  * target_if_dbr_init_mem_list() - init the large memory list for DBR
530  * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj
531  *
532  * Return: None
533  */
534 static void
535 target_if_dbr_init_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj)
536 {
537 	int i;
538 
539 	qdf_spinlock_create(&dbr_psoc_obj->mem_list_lock);
540 	qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock);
541 	for (i = 0; i < QDF_ARRAY_SIZE(dbr_psoc_obj->mem_list); i++)
542 		qdf_list_create(&dbr_psoc_obj->mem_list[i], 0);
543 
544 	qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock);
545 }
546 
547 /**
548  * target_if_dbr_deinit_mem_list() - deinit the large memory list for DBR
549  * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj
550  *
551  * Return: None
552  */
553 static void
554 target_if_dbr_deinit_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj)
555 {
556 	struct direct_buf_rx_large_mem *cur, *next;
557 	qdf_list_t *mem_list;
558 	int i;
559 
560 	qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock);
561 	for (i = 0; i < QDF_ARRAY_SIZE(dbr_psoc_obj->mem_list); i++) {
562 		mem_list = &dbr_psoc_obj->mem_list[i];
563 		qdf_list_for_each_del(mem_list, cur, next, node) {
564 			qdf_list_remove_node(mem_list, &cur->node);
565 			qdf_mem_free(cur->vaddr_unaligned);
566 		}
567 
568 		qdf_list_destroy(mem_list);
569 	}
570 
571 	qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock);
572 	qdf_spinlock_destroy(&dbr_psoc_obj->mem_list_lock);
573 }
574 
575 /**
576  * target_if_dbr_mem_add() - allocate a new element for large memory list
577  * @dbr_psoc_obj: pointer to direct buffer rx module psoc obj
578  * @pdev_id: PDEV id
579  * @size: Size of the memory to be assigned to the new element
580  * @vaddr_unaligned: unaligned base address of the memory
581  * @offset: offset between unaligned vaddr and aligned vaddr
582  * @align: Base address alignment
583  *
584  * Return: None
585  */
586 static void
587 target_if_dbr_mem_add(struct direct_buf_rx_psoc_obj *dbr_psoc_obj,
588 		      uint8_t pdev_id, uint32_t size, void *vaddr_unaligned,
589 		      uint8_t offset, uint32_t align)
590 {
591 	struct direct_buf_rx_large_mem *new_node;
592 	uint32_t list_size;
593 
594 	new_node = vaddr_unaligned;
595 	qdf_mem_zero(new_node, sizeof(*new_node));
596 	new_node->size = size;
597 	new_node->vaddr_unaligned = vaddr_unaligned;
598 	new_node->offset = offset;
599 	new_node->align = align;
600 
601 	qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock);
602 	qdf_list_insert_back(&dbr_psoc_obj->mem_list[pdev_id],
603 			     &new_node->node);
604 	list_size = qdf_list_size(&dbr_psoc_obj->mem_list[pdev_id]);
605 	qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock);
606 }
607 
608 /**
609  * target_if_dbr_mem_get() - get aligned memory
610  * @pdev: pointer to pdev object
611  * @size: Size to be allocated
612  * @offset: offset between unaligned vaddr and aligned vaddr
613  * @align: Base address alignment
614  * @mod_id: DBR module id (enum DBR_MODULE)
615  *
616  * If size to be allocated is equal or smaller than the threshold, this
617  * function will allocate the aligned memory dynamically;
618  * If NOT, it will search the saved memory list, return the one which meet the
619  * requirement, otherwise, allocate the aligned memory dynamically.
620  *
621  * Return:
622  * Unaligned base address of the memory on succeed, NULL otherwise.
623  */
624 static void *
625 target_if_dbr_mem_get(struct wlan_objmgr_pdev *pdev, uint32_t *size,
626 		      uint8_t *offset, uint32_t align, uint32_t mod_id)
627 {
628 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
629 	struct wlan_objmgr_psoc *psoc;
630 	struct direct_buf_rx_large_mem *cur, *next;
631 	void *vaddr_unaligned = NULL, *vaddr_aligned;
632 	dma_addr_t paddr_aligned, paddr_unaligned;
633 	QDF_STATUS status;
634 	qdf_list_t *mem_list;
635 	uint8_t pdev_id;
636 
637 	if (*size < TARGET_IF_DBR_HOLD_MEM_THRESHOLD) {
638 		vaddr_aligned = qdf_aligned_malloc(size, &vaddr_unaligned,
639 						   &paddr_unaligned,
640 						   &paddr_aligned, align);
641 		if (!vaddr_aligned)
642 			return NULL;
643 
644 		*offset = vaddr_aligned - vaddr_unaligned;
645 
646 		return vaddr_unaligned;
647 	}
648 
649 	if (!pdev) {
650 		direct_buf_rx_err("pdev context passed is null");
651 		return vaddr_unaligned;
652 	}
653 
654 	psoc = wlan_pdev_get_psoc(pdev);
655 
656 	if (!psoc) {
657 		direct_buf_rx_err("psoc is null");
658 		return vaddr_unaligned;
659 	}
660 
661 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
662 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
663 
664 	if (!dbr_psoc_obj) {
665 		direct_buf_rx_err("dir buf rx psoc object is null");
666 		return vaddr_unaligned;
667 	}
668 
669 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
670 	qdf_spin_lock_bh(&dbr_psoc_obj->mem_list_lock);
671 	mem_list = &dbr_psoc_obj->mem_list[pdev_id];
672 	qdf_list_for_each_del(mem_list, cur, next, node) {
673 		if (DBR_MEM_NODE_MATCH(cur->align, cur->size, align, *size)) {
674 			status = qdf_list_remove_node(mem_list, &cur->node);
675 			if (QDF_IS_STATUS_ERROR(status)) {
676 				direct_buf_rx_err("failed to remove node: %d",
677 						  status);
678 				break;
679 			}
680 
681 			*offset = cur->offset;
682 			*size = cur->size;
683 			vaddr_unaligned = cur->vaddr_unaligned;
684 			break;
685 		}
686 	}
687 	qdf_spin_unlock_bh(&dbr_psoc_obj->mem_list_lock);
688 
689 	if (vaddr_unaligned) {
690 		qdf_mem_zero(vaddr_unaligned, *size);
691 		return vaddr_unaligned;
692 	}
693 
694 	vaddr_aligned =
695 		qdf_aligned_malloc(size, &vaddr_unaligned, &paddr_unaligned,
696 				   &paddr_aligned, align);
697 	if (!vaddr_aligned)
698 		return NULL;
699 
700 	*offset = vaddr_aligned - vaddr_unaligned;
701 	return vaddr_unaligned;
702 }
703 
704 /**
705  * target_if_dbr_mem_put() - put aligned memory
706  * @pdev: pointer to pdev object
707  * @size: size of the memory to be put
708  * @vaddr_unaligned: unaligned base address of the memory
709  * @offset: offset between unaligned vaddr and aligned vaddr
710  * @align: Base address alignment
711  * @mod_id: DBR module id (enum DBR_MODULE)
712  *
713  * If size to be allocated is equal or smaller than the threshold, this
714  * function will free the memory directly;
715  * If NOT, it will search the saved memory list, mark the one which meet the
716  * requirement as NOT in use; and if no element is found, free the memory.
717  *
718  * Return: None
719  */
720 static void
721 target_if_dbr_mem_put(struct wlan_objmgr_pdev *pdev, uint32_t size,
722 		      void *vaddr_unaligned, uint8_t offset,
723 		      uint32_t align, uint32_t mod_id)
724 {
725 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
726 	struct wlan_objmgr_psoc *psoc;
727 
728 	if (!vaddr_unaligned)
729 		return;
730 
731 	if (size < TARGET_IF_DBR_HOLD_MEM_THRESHOLD) {
732 		qdf_mem_free(vaddr_unaligned);
733 		return;
734 	}
735 
736 	if (!pdev) {
737 		direct_buf_rx_err("pdev context passed is null");
738 		return;
739 	}
740 
741 	psoc = wlan_pdev_get_psoc(pdev);
742 	if (!psoc) {
743 		direct_buf_rx_err("psoc is null");
744 		return;
745 	}
746 
747 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
748 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
749 	if (!dbr_psoc_obj) {
750 		direct_buf_rx_err("dir buf rx psoc object is null");
751 		return;
752 	}
753 
754 	target_if_dbr_mem_add(dbr_psoc_obj, wlan_objmgr_pdev_get_pdev_id(pdev),
755 			      size, vaddr_unaligned, offset, align);
756 }
757 #else
758 static inline void
759 target_if_dbr_init_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj)
760 {
761 }
762 
763 static inline void
764 target_if_dbr_deinit_mem_list(struct direct_buf_rx_psoc_obj *dbr_psoc_obj)
765 {
766 }
767 
768 static void *
769 target_if_dbr_mem_get(struct wlan_objmgr_pdev *pdev, uint32_t *size,
770 		      uint8_t *offset, uint32_t align, uint32_t mod_id)
771 {
772 	void *vaddr_unaligned = NULL, *vaddr_aligned;
773 	dma_addr_t paddr_aligned, paddr_unaligned;
774 
775 	vaddr_aligned = qdf_aligned_malloc(size, &vaddr_unaligned,
776 					   &paddr_unaligned, &paddr_aligned,
777 					   align);
778 	if (!vaddr_aligned)
779 		return NULL;
780 
781 	*offset = vaddr_aligned - vaddr_unaligned;
782 	return vaddr_unaligned;
783 }
784 
785 static inline void
786 target_if_dbr_mem_put(struct wlan_objmgr_pdev *pdev, uint32_t size,
787 		      void *vaddr_unaligned, uint8_t offset,
788 		      uint32_t align, uint32_t mod_id)
789 {
790 	qdf_mem_free(vaddr_unaligned);
791 }
792 #endif /* DBR_HOLD_LARGE_MEM */
793 
794 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler(
795 	struct wlan_objmgr_psoc *psoc, void *data)
796 {
797 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
798 	QDF_STATUS status;
799 
800 	direct_buf_rx_enter();
801 
802 	if (!psoc) {
803 		direct_buf_rx_err("psoc context passed is null");
804 		return QDF_STATUS_E_INVAL;
805 	}
806 
807 	dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj));
808 
809 	if (!dbr_psoc_obj)
810 		return QDF_STATUS_E_NOMEM;
811 
812 	direct_buf_rx_debug("Dbr psoc obj %pK", dbr_psoc_obj);
813 
814 	target_if_dbr_init_mem_list(dbr_psoc_obj);
815 
816 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
817 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj,
818 			QDF_STATUS_SUCCESS);
819 
820 	if (status != QDF_STATUS_SUCCESS) {
821 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
822 				  status);
823 		goto attach_error;
824 	}
825 
826 	return status;
827 
828 attach_error:
829 	qdf_mem_free(dbr_psoc_obj);
830 
831 	return status;
832 }
833 
834 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler(
835 	struct wlan_objmgr_psoc *psoc, void *data)
836 {
837 	QDF_STATUS status;
838 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
839 
840 	direct_buf_rx_enter();
841 
842 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
843 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
844 
845 	if (!dbr_psoc_obj) {
846 		direct_buf_rx_err("dir buf rx psoc obj is null");
847 		return QDF_STATUS_E_FAILURE;
848 	}
849 
850 	target_if_dbr_deinit_mem_list(dbr_psoc_obj);
851 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
852 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
853 				dbr_psoc_obj);
854 
855 	if (status != QDF_STATUS_SUCCESS) {
856 		direct_buf_rx_err("failed to detach dir buf rx component %d",
857 				  status);
858 	}
859 
860 	qdf_mem_free(dbr_psoc_obj);
861 
862 	return status;
863 }
864 
865 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG)
866 /**
867  * target_if_dbr_debugfs_show_ring_debug() - Function to display ring debug
868  * entries in debugfs
869  * @file: qdf debugfs file handler
870  * @arg: pointer to DBR debugfs private object
871  *
872  * Return: QDF_STATUS of operation
873  */
874 static QDF_STATUS target_if_dbr_debugfs_show_ring_debug(
875 	qdf_debugfs_file_t file, void *arg)
876 {
877 	struct dbr_debugfs_priv *priv = arg;
878 
879 	return target_if_dbr_print_ring_debug_entries(qdf_debugfs_printer,
880 						      file, priv->dbr_pdev_obj,
881 						      priv->mod_id,
882 						      priv->srng_id);
883 }
884 
885 /**
886  * target_if_dbr_mod_debugfs_init() - Init debugfs for a given module
887  * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module
888  * @mod_id: Module ID corresponding to this ring
889  *
890  * Return: QDF_STATUS of operation
891  */
892 static QDF_STATUS target_if_dbr_mod_debugfs_init(
893 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
894 	enum DBR_MODULE mod_id)
895 {
896 	struct direct_buf_rx_module_debug *mod_debug;
897 
898 	mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj,
899 								  mod_id);
900 
901 	if (!mod_debug)
902 		return QDF_STATUS_E_INVAL;
903 
904 	if (mod_debug->debugfs_entry) {
905 		direct_buf_rx_err("debugfs mod entry was already created for %s module",
906 				  g_dbr_module_name[mod_id].module_name_str);
907 		return QDF_STATUS_SUCCESS;
908 	}
909 
910 	mod_debug->debugfs_entry =
911 	    qdf_debugfs_create_dir(g_dbr_module_name[mod_id].module_name_str,
912 				   dbr_pdev_obj->debugfs_entry);
913 
914 	if (!mod_debug->debugfs_entry) {
915 		direct_buf_rx_err("error while creating direct_buf debugfs entry for %s module",
916 				  g_dbr_module_name[mod_id].module_name_str);
917 		return QDF_STATUS_E_FAILURE;
918 	}
919 
920 	return QDF_STATUS_SUCCESS;
921 }
922 
923 /**
924  * target_if_dbr_ring_debugfs_init() - Init debugfs for a given ring
925  * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module
926  * @mod_id: Module ID corresponding to this ring
927  * @srng_id: srng ID corresponding to this ring
928  *
929  * Return: QDF_STATUS of operation
930  */
931 static QDF_STATUS target_if_dbr_ring_debugfs_init(
932 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
933 	enum DBR_MODULE mod_id, uint8_t srng_id)
934 {
935 	struct direct_buf_rx_module_debug *mod_debug;
936 	struct direct_buf_rx_ring_debug *ring_debug;
937 	struct dbr_debugfs_priv *priv;
938 	char debug_file_name[32];
939 
940 	mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj,
941 								  mod_id);
942 
943 	if (!mod_debug)
944 		return QDF_STATUS_E_INVAL;
945 
946 	ring_debug = &mod_debug->dbr_ring_debug[srng_id];
947 
948 	if (!mod_debug->debugfs_entry) {
949 		direct_buf_rx_err("error mod_debug->debugfs_entry not created");
950 		return QDF_STATUS_E_FAILURE;
951 	}
952 
953 	if (ring_debug->debugfs_entry) {
954 		direct_buf_rx_err("debugfs file for %d ring under %s module already created",
955 				   srng_id,
956 				   g_dbr_module_name[mod_id].module_name_str);
957 		return QDF_STATUS_SUCCESS;
958 	}
959 
960 	qdf_snprintf(debug_file_name, sizeof(debug_file_name),
961 		     "ring_%d", srng_id);
962 
963 	// Allocate debugfs ops
964 	ring_debug->debugfs_fops =
965 		qdf_mem_malloc(sizeof(*ring_debug->debugfs_fops));
966 	if (!ring_debug->debugfs_fops) {
967 		direct_buf_rx_err("error in allocating debugfs ops");
968 		return QDF_STATUS_E_NOMEM;
969 	}
970 
971 	// Allocate private data
972 	priv = qdf_mem_malloc(sizeof(*priv));
973 	if (!priv) {
974 		direct_buf_rx_err("error in creating debugfs private data");
975 		goto priv_alloc_fail;
976 	}
977 	priv->dbr_pdev_obj = dbr_pdev_obj;
978 	priv->mod_id = mod_id;
979 	priv->srng_id = srng_id;
980 
981 	/* Fill in the debugfs ops for this ring.
982 	 * When the output time comes, the 'show' function will be
983 	 * called with 'priv' as an argument.
984 	 */
985 	ring_debug->debugfs_fops->show = target_if_dbr_debugfs_show_ring_debug;
986 	ring_debug->debugfs_fops->priv = priv;
987 
988 	ring_debug->debugfs_entry =
989 		qdf_debugfs_create_file_simplified(
990 				    debug_file_name,
991 				    (QDF_FILE_USR_READ | QDF_FILE_GRP_READ |
992 				    QDF_FILE_OTH_READ),
993 				    mod_debug->debugfs_entry,
994 				    ring_debug->debugfs_fops);
995 
996 	if (!ring_debug->debugfs_entry) {
997 		direct_buf_rx_err("error while creating direct_buf debugfs file for %d ring under %s module",
998 				  srng_id,
999 				  g_dbr_module_name[mod_id].module_name_str);
1000 		goto file_creation_fail;
1001 	}
1002 
1003 	return QDF_STATUS_SUCCESS;
1004 
1005 file_creation_fail:
1006 	qdf_mem_free(ring_debug->debugfs_fops->priv);
1007 
1008 priv_alloc_fail:
1009 	qdf_mem_free(ring_debug->debugfs_fops);
1010 	ring_debug->debugfs_fops = NULL;
1011 	return QDF_STATUS_E_NOMEM;
1012 }
1013 
1014 /**
1015  * target_if_dbr_mod_debugfs_deinit() - De-init debugfs for a given module
1016  * @mod_debug: Pointer to direct_buf_rx_module_debug structure
1017  *
1018  * Return: void
1019  */
1020 static void target_if_dbr_mod_debugfs_deinit(
1021 			struct direct_buf_rx_module_debug *mod_debug)
1022 {
1023 	if (!mod_debug) {
1024 		direct_buf_rx_err("mod_debug is null");
1025 		return;
1026 	}
1027 
1028 	if (mod_debug->debugfs_entry) {
1029 		qdf_debugfs_remove_file(mod_debug->debugfs_entry);
1030 		mod_debug->debugfs_entry = NULL;
1031 	}
1032 }
1033 
1034 /**
1035  * target_if_dbr_ring_debugfs_deinit() - De-init debugfs for a given ring
1036  * @ring_debug: Pointer to direct_buf_rx_ring_debug structure
1037  *
1038  * Return: void
1039  */
1040 static void target_if_dbr_ring_debugfs_deinit(
1041 	struct direct_buf_rx_ring_debug *ring_debug)
1042 {
1043 	if (!ring_debug) {
1044 		direct_buf_rx_err("ring_debug is null");
1045 		return;
1046 	}
1047 
1048 	if (ring_debug->debugfs_entry) {
1049 		qdf_debugfs_remove_file(ring_debug->debugfs_entry);
1050 		ring_debug->debugfs_entry = NULL;
1051 	}
1052 
1053 	// Free the private data and debugfs ops of this ring
1054 	if (ring_debug->debugfs_fops) {
1055 		qdf_mem_free(ring_debug->debugfs_fops->priv);
1056 		qdf_mem_free(ring_debug->debugfs_fops);
1057 		ring_debug->debugfs_fops = NULL;
1058 	}
1059 }
1060 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */
1061 
1062 #ifdef DIRECT_BUF_RX_DEBUG
1063 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev,
1064 					 uint8_t mod_id)
1065 {
1066 	struct direct_buf_rx_module_debug *mod_debug;
1067 	struct direct_buf_rx_ring_debug *ring_debug;
1068 	uint8_t srng_id;
1069 
1070 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1071 	if (!mod_debug)
1072 		return QDF_STATUS_E_INVAL;
1073 
1074 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1075 		ring_debug = &mod_debug->dbr_ring_debug[srng_id];
1076 		if (!ring_debug->entries) {
1077 			direct_buf_rx_debug("DBR ring debug for module %d srng %d was already disabled",
1078 					   mod_id, srng_id);
1079 			continue;
1080 		}
1081 		/* De-init debugsfs for this ring */
1082 		target_if_dbr_ring_debugfs_deinit(ring_debug);
1083 		qdf_mem_free(ring_debug->entries);
1084 		ring_debug->entries = NULL;
1085 		ring_debug->ring_debug_idx = 0;
1086 		ring_debug->num_ring_debug_entries = 0;
1087 		direct_buf_rx_info("DBR ring debug for module %d srng %d is now stopped",
1088 				   mod_id, srng_id);
1089 	}
1090 	target_if_dbr_mod_debugfs_deinit(mod_debug);
1091 
1092 	return QDF_STATUS_SUCCESS;
1093 }
1094 
1095 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev,
1096 					  uint8_t mod_id,
1097 					  uint32_t num_ring_debug_entries)
1098 {
1099 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1100 	struct direct_buf_rx_module_debug *mod_debug;
1101 	struct direct_buf_rx_ring_debug *ring_debug;
1102 	uint8_t srng_id;
1103 
1104 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1105 
1106 	if (!mod_debug)
1107 		return QDF_STATUS_E_INVAL;
1108 
1109 	if (num_ring_debug_entries > DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES) {
1110 		direct_buf_rx_err("Requested number of ring debug entries(%d) exceed the maximum entries allowed(%d)",
1111 				  num_ring_debug_entries,
1112 				  DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES);
1113 
1114 		return QDF_STATUS_E_FAILURE;
1115 	}
1116 
1117 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
1118 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1119 
1120 	target_if_dbr_mod_debugfs_init(dbr_pdev_obj, mod_id);
1121 
1122 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1123 		ring_debug = &mod_debug->dbr_ring_debug[srng_id];
1124 
1125 		if (ring_debug->entries) {
1126 			direct_buf_rx_err("DBR ring debug for module %d srng %d was already enabled",
1127 					  mod_id, srng_id);
1128 			continue;
1129 		}
1130 
1131 		ring_debug->entries = qdf_mem_malloc(
1132 					num_ring_debug_entries *
1133 					sizeof(*ring_debug->entries));
1134 
1135 		if (!ring_debug->entries)
1136 			return QDF_STATUS_E_NOMEM;
1137 
1138 		ring_debug->ring_debug_idx = 0;
1139 		ring_debug->num_ring_debug_entries = num_ring_debug_entries;
1140 		/* Init debugsfs for this ring */
1141 		target_if_dbr_ring_debugfs_init(
1142 			dbr_pdev_obj,
1143 			mod_id, srng_id);
1144 		direct_buf_rx_info("DBR ring debug for module %d srng %d is now started",
1145 				    mod_id, srng_id);
1146 	}
1147 	return QDF_STATUS_SUCCESS;
1148 }
1149 
1150 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
1151 						uint8_t mod_id, uint32_t value)
1152 {
1153 	struct direct_buf_rx_module_debug *mod_debug;
1154 
1155 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1156 
1157 	if (!mod_debug)
1158 		return QDF_STATUS_E_INVAL;
1159 
1160 	mod_debug->poisoning_enabled = true;
1161 	mod_debug->poison_value = value; /* Save the poison value */
1162 
1163 	direct_buf_rx_debug("DBR buffer poisoning for module %d is now started",
1164 			    mod_id);
1165 	return QDF_STATUS_SUCCESS;
1166 }
1167 
1168 QDF_STATUS target_if_dbr_stop_buffer_poisoning(
1169 	struct wlan_objmgr_pdev *pdev,
1170 	uint8_t mod_id)
1171 {
1172 	struct direct_buf_rx_module_debug *mod_debug;
1173 
1174 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1175 
1176 	if (!mod_debug)
1177 		return QDF_STATUS_E_INVAL;
1178 
1179 	mod_debug->poisoning_enabled = false;
1180 	mod_debug->poison_value = 0;
1181 
1182 	direct_buf_rx_debug("DBR buffer poisoning for module %d is now stopped",
1183 			    mod_id);
1184 	return QDF_STATUS_SUCCESS;
1185 }
1186 
1187 /**
1188  * target_if_dbr_fill_buffer_u32() - Fill buffer with an unsigned 32-bit value
1189  * @buffer: pointer to the buffer
1190  * @num_bytes: Size of the destination buffer in bytes
1191  * @value: Unsigned 32-bit value to be copied
1192  *
1193  * Return : void
1194  */
1195 static void
1196 target_if_dbr_fill_buffer_u32(uint8_t *buffer, uint32_t num_bytes,
1197 			      uint32_t value)
1198 {
1199 	uint32_t *bufp;
1200 	uint32_t idx;
1201 	uint32_t size = (num_bytes >> 2);
1202 
1203 	if (!buffer) {
1204 		direct_buf_rx_err("buffer empty");
1205 		return;
1206 	}
1207 
1208 	bufp = (uint32_t *)buffer;
1209 
1210 	for (idx = 0; idx < size; ++idx) {
1211 		*bufp = value;
1212 		++bufp;
1213 	}
1214 }
1215 
1216 /**
1217  * target_if_dbr_debug_poison_buffer() - Poison a given DBR buffer
1218  * @pdev: pointer to pdev object
1219  * @mod_id: Module ID of the owner of the buffer
1220  * @aligned_vaddr: Virtual address(aligned) of the buffer
1221  * @size: Size of the buffer
1222  *
1223  * Value with which the buffers will be poisoned would have been saved
1224  * while starting the buffer poisoning for the module, use that value.
1225  *
1226  * Return : QDF status of operation
1227  */
1228 static QDF_STATUS target_if_dbr_debug_poison_buffer(
1229 	struct wlan_objmgr_pdev *pdev,
1230 	uint32_t mod_id, void *aligned_vaddr, uint32_t size)
1231 {
1232 	struct direct_buf_rx_module_debug *mod_debug;
1233 
1234 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1235 
1236 	if (!mod_debug)
1237 		return QDF_STATUS_E_INVAL;
1238 
1239 	if (mod_debug->poisoning_enabled) {
1240 		target_if_dbr_fill_buffer_u32(aligned_vaddr, size,
1241 					      mod_debug->poison_value);
1242 	}
1243 
1244 	return QDF_STATUS_SUCCESS;
1245 }
1246 
1247 static inline void target_if_dbr_qdf_show_ring_debug(
1248 	struct wlan_objmgr_pdev *pdev,
1249 	uint8_t mod_id, uint8_t srng_id)
1250 {
1251 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj =
1252 			wlan_objmgr_pdev_get_comp_private_obj(
1253 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1254 
1255 	target_if_dbr_print_ring_debug_entries(
1256 			target_if_dbr_qdf_err_printer,
1257 			NULL, dbr_pdev_obj,
1258 			mod_id, srng_id);
1259 }
1260 #else
1261 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev,
1262 					 uint8_t mod_id)
1263 {
1264 	return QDF_STATUS_SUCCESS;
1265 }
1266 
1267 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev,
1268 					  uint8_t mod_id,
1269 					  uint32_t num_ring_debug_entries)
1270 {
1271 	return QDF_STATUS_SUCCESS;
1272 }
1273 
1274 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
1275 						uint8_t mod_id, uint32_t value)
1276 {
1277 	return QDF_STATUS_SUCCESS;
1278 }
1279 
1280 QDF_STATUS target_if_dbr_stop_buffer_poisoning(
1281 		struct wlan_objmgr_pdev *pdev,
1282 		uint8_t mod_id)
1283 {
1284 	return QDF_STATUS_SUCCESS;
1285 }
1286 
1287 static QDF_STATUS target_if_dbr_debug_poison_buffer(
1288 	struct wlan_objmgr_pdev *pdev,
1289 	uint32_t mod_id, void *aligned_vaddr, uint32_t size)
1290 {
1291 	return QDF_STATUS_SUCCESS;
1292 }
1293 
1294 static inline void target_if_dbr_qdf_show_ring_debug(
1295 	struct wlan_objmgr_pdev *pdev,
1296 	uint8_t mod_id, uint8_t srng_id)
1297 {
1298 }
1299 #endif /* DIRECT_BUF_RX_DEBUG */
1300 
1301 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev,
1302 			struct direct_buf_rx_module_param *mod_param,
1303 			void *aligned_vaddr, uint32_t cookie)
1304 {
1305 	uint32_t *ring_entry;
1306 	uint32_t dw_lo, dw_hi = 0, map_status;
1307 	void *hal_soc, *srng;
1308 	qdf_dma_addr_t paddr;
1309 	struct wlan_objmgr_psoc *psoc;
1310 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1311 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1312 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1313 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1314 
1315 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1316 	dbr_ring_cap = mod_param->dbr_ring_cap;
1317 	dbr_buf_pool = mod_param->dbr_buf_pool;
1318 
1319 	psoc = wlan_pdev_get_psoc(pdev);
1320 
1321 	if (!psoc) {
1322 		direct_buf_rx_err("psoc is null");
1323 		return QDF_STATUS_E_FAILURE;
1324 	}
1325 
1326 	if (cookie >= mod_param->dbr_ring_cfg->num_ptr) {
1327 		direct_buf_rx_err("invalid cookie %d", cookie);
1328 		return QDF_STATUS_E_INVAL;
1329 	}
1330 
1331 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1332 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1333 
1334 	if (!dbr_psoc_obj) {
1335 		direct_buf_rx_err("dir buf rx psoc object is null");
1336 		return QDF_STATUS_E_FAILURE;
1337 	}
1338 
1339 	hal_soc = dbr_psoc_obj->hal_soc;
1340 	srng = dbr_ring_cfg->srng;
1341 	if (!aligned_vaddr) {
1342 		direct_buf_rx_err("aligned vaddr is null");
1343 		return QDF_STATUS_SUCCESS;
1344 	}
1345 
1346 	target_if_dbr_debug_poison_buffer(
1347 			pdev, mod_param->mod_id, aligned_vaddr,
1348 			dbr_ring_cap->min_buf_size);
1349 
1350 	map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev,
1351 					       aligned_vaddr,
1352 					       QDF_DMA_FROM_DEVICE,
1353 					       dbr_ring_cap->min_buf_size,
1354 					       &paddr);
1355 	if (map_status) {
1356 		direct_buf_rx_err("mem map failed status = %d", map_status);
1357 		return QDF_STATUS_E_FAILURE;
1358 	}
1359 
1360 	QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align));
1361 	dbr_buf_pool[cookie].paddr = paddr;
1362 
1363 	hal_le_srng_access_start_in_cpu_order(hal_soc, srng);
1364 	ring_entry = hal_srng_src_get_next(hal_soc, srng);
1365 
1366 	if (!ring_entry) {
1367 		target_if_dbr_qdf_show_ring_debug(pdev, mod_param->mod_id,
1368 						  mod_param->srng_id);
1369 		QDF_BUG(0);
1370 	}
1371 
1372 	dw_lo = (uint64_t)paddr & 0xFFFFFFFF;
1373 	WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32);
1374 	WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie);
1375 	*ring_entry = qdf_cpu_to_le32(dw_lo);
1376 	ring_entry++;
1377 	*ring_entry = qdf_cpu_to_le32(dw_hi);
1378 	hal_le_srng_access_end_in_cpu_order(hal_soc, srng);
1379 
1380 	return QDF_STATUS_SUCCESS;
1381 }
1382 
1383 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev,
1384 			  struct direct_buf_rx_module_param *mod_param)
1385 {
1386 	uint32_t idx;
1387 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1388 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1389 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1390 	void *buf_vaddr_unaligned, *buf_vaddr_aligned;
1391 	QDF_STATUS status;
1392 	uint8_t offset;
1393 
1394 	direct_buf_rx_enter();
1395 
1396 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1397 	dbr_ring_cap = mod_param->dbr_ring_cap;
1398 	dbr_buf_pool = mod_param->dbr_buf_pool;
1399 
1400 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
1401 		buf_vaddr_unaligned =
1402 			target_if_dbr_mem_get(pdev, &dbr_ring_cap->min_buf_size,
1403 					      &offset,
1404 					      dbr_ring_cap->min_buf_align,
1405 					      mod_param->mod_id);
1406 		if (!buf_vaddr_unaligned) {
1407 			direct_buf_rx_err("dir buf rx ring alloc failed");
1408 			return QDF_STATUS_E_NOMEM;
1409 		}
1410 
1411 		dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned;
1412 		dbr_buf_pool[idx].offset = offset;
1413 		dbr_buf_pool[idx].cookie = idx;
1414 		buf_vaddr_aligned = buf_vaddr_unaligned + offset;
1415 		status = target_if_dbr_replenish_ring(pdev, mod_param,
1416 						      buf_vaddr_aligned, idx);
1417 		if (QDF_IS_STATUS_ERROR(status)) {
1418 			direct_buf_rx_err("replenish failed with status : %d",
1419 					  status);
1420 			target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size,
1421 					      buf_vaddr_unaligned, offset,
1422 					      dbr_ring_cap->min_buf_align,
1423 					      mod_param->mod_id);
1424 			return QDF_STATUS_E_FAILURE;
1425 		}
1426 	}
1427 
1428 	direct_buf_rx_exit();
1429 
1430 	return QDF_STATUS_SUCCESS;
1431 }
1432 
1433 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev,
1434 			struct direct_buf_rx_module_param *mod_param)
1435 {
1436 	void *srng;
1437 	uint32_t num_entries, ring_alloc_size, max_entries, entry_size;
1438 	qdf_dma_addr_t paddr;
1439 	struct hal_srng_params ring_params = {0};
1440 	struct wlan_objmgr_psoc *psoc;
1441 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1442 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1443 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1444 	QDF_STATUS status;
1445 
1446 	direct_buf_rx_enter();
1447 
1448 	psoc = wlan_pdev_get_psoc(pdev);
1449 
1450 	if (!psoc) {
1451 		direct_buf_rx_err("psoc is null");
1452 		return QDF_STATUS_E_FAILURE;
1453 	}
1454 
1455 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1456 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1457 
1458 	if (!dbr_psoc_obj) {
1459 		direct_buf_rx_err("dir buf rx psoc object is null");
1460 		return QDF_STATUS_E_FAILURE;
1461 	}
1462 
1463 	if (!dbr_psoc_obj->hal_soc ||
1464 	    !dbr_psoc_obj->osdev) {
1465 		direct_buf_rx_err("dir buf rx target attach failed");
1466 		return QDF_STATUS_E_FAILURE;
1467 	}
1468 
1469 	max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc,
1470 					   DIR_BUF_RX_DMA_SRC);
1471 	entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc,
1472 					    DIR_BUF_RX_DMA_SRC);
1473 	direct_buf_rx_debug("Max Entries = %d", max_entries);
1474 	direct_buf_rx_debug("Entry Size = %d", entry_size);
1475 
1476 	status = populate_dbr_cap_mod_param(pdev, mod_param);
1477 	if (QDF_IS_STATUS_ERROR(status)) {
1478 		direct_buf_rx_err("Module cap population failed");
1479 		return QDF_STATUS_E_FAILURE;
1480 	}
1481 
1482 	dbr_ring_cap = mod_param->dbr_ring_cap;
1483 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1484 	num_entries = dbr_ring_cap->ring_elems_min > max_entries ?
1485 			max_entries : dbr_ring_cap->ring_elems_min;
1486 	direct_buf_rx_debug("Num entries = %d", num_entries);
1487 	dbr_ring_cfg->num_ptr = num_entries;
1488 	mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof(
1489 				struct direct_buf_rx_buf_info));
1490 	if (!mod_param->dbr_buf_pool)
1491 		return QDF_STATUS_E_NOMEM;
1492 
1493 	ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1;
1494 	dbr_ring_cfg->ring_alloc_size = ring_alloc_size;
1495 	direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj);
1496 	dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent(
1497 		dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size,
1498 		&paddr);
1499 	direct_buf_rx_debug("vaddr aligned allocated");
1500 	dbr_ring_cfg->base_paddr_unaligned = paddr;
1501 	if (!dbr_ring_cfg->base_vaddr_unaligned) {
1502 		direct_buf_rx_err("dir buf rx vaddr alloc failed");
1503 		qdf_mem_free(mod_param->dbr_buf_pool);
1504 		return QDF_STATUS_E_NOMEM;
1505 	}
1506 
1507 	/* Alignment is defined to 8 for now. Will be advertised by FW */
1508 	dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup(
1509 		(uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned,
1510 		DBR_RING_BASE_ALIGN);
1511 	ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned;
1512 	dbr_ring_cfg->base_paddr_aligned = qdf_roundup(
1513 		(uint64_t)dbr_ring_cfg->base_paddr_unaligned,
1514 		DBR_RING_BASE_ALIGN);
1515 	ring_params.ring_base_paddr =
1516 		(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned;
1517 	ring_params.num_entries = num_entries;
1518 	srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC,
1519 			      mod_param->mod_id,
1520 			      mod_param->pdev_id, &ring_params, 0);
1521 
1522 	if (!srng) {
1523 		direct_buf_rx_err("srng setup failed");
1524 		qdf_mem_free(mod_param->dbr_buf_pool);
1525 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
1526 					dbr_psoc_obj->osdev->dev,
1527 					ring_alloc_size,
1528 					dbr_ring_cfg->base_vaddr_unaligned,
1529 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
1530 		return QDF_STATUS_E_FAILURE;
1531 	}
1532 	dbr_ring_cfg->srng = srng;
1533 	dbr_ring_cfg->tail_idx_addr =
1534 		hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng);
1535 	dbr_ring_cfg->head_idx_addr =
1536 		hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng);
1537 	dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size;
1538 
1539 	return target_if_dbr_fill_ring(pdev, mod_param);
1540 }
1541 
1542 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev,
1543 			struct direct_buf_rx_module_param *mod_param)
1544 {
1545 	QDF_STATUS status;
1546 
1547 	direct_buf_rx_debug("Init DBR srng");
1548 
1549 	if (!mod_param) {
1550 		direct_buf_rx_err("dir buf rx module param is null");
1551 		return QDF_STATUS_E_INVAL;
1552 	}
1553 
1554 	mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof(
1555 					struct direct_buf_rx_ring_cap));
1556 
1557 	if (!mod_param->dbr_ring_cap)
1558 		return QDF_STATUS_E_NOMEM;
1559 
1560 	/* Allocate memory for DBR Ring Config */
1561 	mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof(
1562 					struct direct_buf_rx_ring_cfg));
1563 
1564 	if (!mod_param->dbr_ring_cfg) {
1565 		qdf_mem_free(mod_param->dbr_ring_cap);
1566 		return QDF_STATUS_E_NOMEM;
1567 	}
1568 
1569 	status = target_if_dbr_init_ring(pdev, mod_param);
1570 
1571 	if (QDF_IS_STATUS_ERROR(status)) {
1572 		direct_buf_rx_err("DBR ring init failed");
1573 		qdf_mem_free(mod_param->dbr_ring_cfg);
1574 		qdf_mem_free(mod_param->dbr_ring_cap);
1575 		return QDF_STATUS_E_FAILURE;
1576 	}
1577 
1578 	return QDF_STATUS_SUCCESS;
1579 }
1580 
1581 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev,
1582 			struct direct_buf_rx_module_param *mod_param)
1583 {
1584 	QDF_STATUS status;
1585 	struct wlan_objmgr_psoc *psoc;
1586 	wmi_unified_t wmi_hdl;
1587 	struct direct_buf_rx_cfg_req dbr_cfg_req = {0};
1588 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1589 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1590 	struct dbr_module_config *dbr_config;
1591 
1592 	direct_buf_rx_enter();
1593 
1594 	psoc = wlan_pdev_get_psoc(pdev);
1595 	if (!psoc) {
1596 		direct_buf_rx_err("psoc is null");
1597 		return QDF_STATUS_E_FAILURE;
1598 	}
1599 
1600 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1601 	dbr_ring_cap = mod_param->dbr_ring_cap;
1602 	dbr_config = &mod_param->dbr_config;
1603 	wmi_hdl = lmac_get_pdev_wmi_handle(pdev);
1604 	if (!wmi_hdl) {
1605 		direct_buf_rx_err("WMI handle null. Can't send WMI CMD");
1606 		return QDF_STATUS_E_INVAL;
1607 	}
1608 
1609 	direct_buf_rx_debug("Sending DBR Ring CFG to target");
1610 	dbr_cfg_req.pdev_id = mod_param->pdev_id;
1611 	/* Module ID numbering starts from 1 in FW. need to fix it */
1612 	dbr_cfg_req.mod_id = mod_param->mod_id;
1613 	dbr_cfg_req.base_paddr_lo =
1614 		qdf_get_lower_32_bits(dbr_ring_cfg->base_paddr_aligned);
1615 	dbr_cfg_req.base_paddr_hi =
1616 		qdf_get_upper_32_bits(dbr_ring_cfg->base_paddr_aligned);
1617 	dbr_cfg_req.head_idx_paddr_lo =
1618 		qdf_get_lower_32_bits(dbr_ring_cfg->head_idx_addr);
1619 	dbr_cfg_req.head_idx_paddr_hi =
1620 		qdf_get_upper_32_bits(dbr_ring_cfg->head_idx_addr);
1621 	dbr_cfg_req.tail_idx_paddr_lo =
1622 		qdf_get_lower_32_bits(dbr_ring_cfg->tail_idx_addr);
1623 	dbr_cfg_req.tail_idx_paddr_hi =
1624 		qdf_get_upper_32_bits(dbr_ring_cfg->tail_idx_addr);
1625 	dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min;
1626 	dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size;
1627 	dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event;
1628 	dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms;
1629 	direct_buf_rx_debug("pdev id %d mod id %d base addr lo %x\n"
1630 			    "base addr hi %x head idx addr lo %x\n"
1631 			    "head idx addr hi %x tail idx addr lo %x\n"
1632 			    "tail idx addr hi %x num ptr %d\n"
1633 			    "num resp %d event timeout %d\n",
1634 			    dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id,
1635 			    dbr_cfg_req.base_paddr_lo,
1636 			    dbr_cfg_req.base_paddr_hi,
1637 			    dbr_cfg_req.head_idx_paddr_lo,
1638 			    dbr_cfg_req.head_idx_paddr_hi,
1639 			    dbr_cfg_req.tail_idx_paddr_lo,
1640 			    dbr_cfg_req.tail_idx_paddr_hi,
1641 			    dbr_cfg_req.num_elems,
1642 			    dbr_cfg_req.num_resp_per_event,
1643 			    dbr_cfg_req.event_timeout_ms);
1644 	status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req);
1645 
1646 	return status;
1647 }
1648 
1649 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev,
1650 				struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
1651 				enum DBR_MODULE mod_id, uint8_t srng_id)
1652 {
1653 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1654 	struct direct_buf_rx_module_param *mod_param;
1655 
1656 	direct_buf_rx_debug("Init DBR ring for module %d, srng %d",
1657 			    mod_id, srng_id);
1658 
1659 	if (!dbr_pdev_obj) {
1660 		direct_buf_rx_err("dir buf rx object is null");
1661 		return QDF_STATUS_E_INVAL;
1662 	}
1663 
1664 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
1665 
1666 	if (!mod_param) {
1667 		direct_buf_rx_err("dir buf rx module param is null");
1668 		return QDF_STATUS_E_FAILURE;
1669 	}
1670 
1671 	direct_buf_rx_debug("mod_param %pK", mod_param);
1672 
1673 	mod_param->mod_id = mod_id;
1674 	mod_param->pdev_id = dbr_get_pdev_id(
1675 				srng_id, wlan_objmgr_pdev_get_pdev_id(pdev));
1676 	mod_param->srng_id = srng_id;
1677 
1678 	/* Initialize DMA ring now */
1679 	status = target_if_dbr_init_srng(pdev, mod_param);
1680 	if (QDF_IS_STATUS_ERROR(status)) {
1681 		direct_buf_rx_err("DBR ring init failed %d", status);
1682 		return status;
1683 	}
1684 
1685 	/* Send CFG request command to firmware */
1686 	status = target_if_dbr_cfg_tgt(pdev, mod_param);
1687 	if (QDF_IS_STATUS_ERROR(status)) {
1688 		direct_buf_rx_err("DBR config to target failed %d", status);
1689 		goto dbr_srng_init_failed;
1690 	}
1691 
1692 	return QDF_STATUS_SUCCESS;
1693 
1694 dbr_srng_init_failed:
1695 	target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id);
1696 	return status;
1697 }
1698 
1699 QDF_STATUS target_if_direct_buf_rx_module_register(
1700 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id,
1701 			struct dbr_module_config *dbr_config,
1702 			bool (*dbr_rsp_handler)
1703 			     (struct wlan_objmgr_pdev *pdev,
1704 			      struct direct_buf_rx_data *dbr_data))
1705 {
1706 	QDF_STATUS status;
1707 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1708 	struct dbr_module_config *config = NULL;
1709 	struct direct_buf_rx_module_param *mod_param;
1710 	uint8_t srng_id;
1711 
1712 	if (!pdev) {
1713 		direct_buf_rx_err("pdev context passed is null");
1714 		return QDF_STATUS_E_INVAL;
1715 	}
1716 
1717 	if (!dbr_rsp_handler) {
1718 		direct_buf_rx_err("Response handler is null");
1719 		return QDF_STATUS_E_INVAL;
1720 	}
1721 
1722 	if (mod_id >= DBR_MODULE_MAX) {
1723 		direct_buf_rx_err("Invalid module id");
1724 		return QDF_STATUS_E_INVAL;
1725 	}
1726 
1727 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1728 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1729 
1730 	if (!dbr_pdev_obj) {
1731 		direct_buf_rx_err("dir buf rx object is null");
1732 		return QDF_STATUS_E_FAILURE;
1733 	}
1734 
1735 	direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj);
1736 
1737 	if (!dbr_pdev_obj->dbr_mod_param) {
1738 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
1739 		return QDF_STATUS_E_FAILURE;
1740 	}
1741 
1742 	if (mod_id >= dbr_pdev_obj->num_modules) {
1743 		direct_buf_rx_err("Module %d not supported in target", mod_id);
1744 		return QDF_STATUS_E_FAILURE;
1745 	}
1746 
1747 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1748 		mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1749 		config = &mod_param->dbr_config;
1750 		mod_param->dbr_rsp_handler = dbr_rsp_handler;
1751 		*config = *dbr_config;
1752 
1753 		status = target_if_init_dbr_ring(pdev, dbr_pdev_obj,
1754 						 (enum DBR_MODULE)mod_id,
1755 						 srng_id);
1756 		if (QDF_IS_STATUS_ERROR(status))
1757 			direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d",
1758 					  srng_id, status);
1759 		else
1760 			mod_param->registered = true;
1761 	}
1762 
1763 	return status;
1764 }
1765 
1766 QDF_STATUS target_if_direct_buf_rx_module_unregister(
1767 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id)
1768 {
1769 	QDF_STATUS status;
1770 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1771 	uint8_t srng_id;
1772 
1773 	if (!pdev) {
1774 		direct_buf_rx_err("pdev context passed is null");
1775 		return QDF_STATUS_E_INVAL;
1776 	}
1777 
1778 	if (mod_id >= DBR_MODULE_MAX) {
1779 		direct_buf_rx_err("Invalid module id");
1780 		return QDF_STATUS_E_INVAL;
1781 	}
1782 
1783 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
1784 			(pdev,
1785 			 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1786 
1787 	if (!dbr_pdev_obj) {
1788 		direct_buf_rx_err("dir buf rx object is null");
1789 		return QDF_STATUS_E_FAILURE;
1790 	}
1791 
1792 	direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj);
1793 
1794 	if (!dbr_pdev_obj->dbr_mod_param) {
1795 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
1796 		return QDF_STATUS_E_FAILURE;
1797 	}
1798 
1799 	if (mod_id >= dbr_pdev_obj->num_modules) {
1800 		direct_buf_rx_err("Module %d not supported in target", mod_id);
1801 		return QDF_STATUS_E_FAILURE;
1802 	}
1803 
1804 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1805 		status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj,
1806 						   mod_id, srng_id);
1807 		direct_buf_rx_info("status %d", status);
1808 	}
1809 
1810 	return status;
1811 }
1812 
1813 static void *target_if_dbr_vaddr_lookup(
1814 			struct direct_buf_rx_module_param *mod_param,
1815 			qdf_dma_addr_t paddr, uint32_t cookie)
1816 {
1817 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1818 
1819 	dbr_buf_pool = mod_param->dbr_buf_pool;
1820 
1821 	if (cookie >= mod_param->dbr_ring_cfg->num_ptr) {
1822 		direct_buf_rx_err("invalid cookie %d", cookie);
1823 		return NULL;
1824 	}
1825 
1826 	if (dbr_buf_pool[cookie].paddr == paddr) {
1827 		return dbr_buf_pool[cookie].vaddr +
1828 				dbr_buf_pool[cookie].offset;
1829 	}
1830 	direct_buf_rx_debug("Invalid paddr, cookie %d, pool paddr %pK, paddr %pK",
1831 			    cookie, (void *)dbr_buf_pool[cookie].paddr,
1832 			    (void *)paddr);
1833 
1834 	return NULL;
1835 }
1836 
1837 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev,
1838 				       uint8_t mod_id, qdf_dma_addr_t paddr,
1839 				       uint32_t *cookie, uint8_t srng_id)
1840 {
1841 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1842 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1843 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1844 	struct direct_buf_rx_module_param *mod_param;
1845 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
1846 	uint32_t idx;
1847 
1848 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
1849 	if (!dbr_pdev_obj) {
1850 		direct_buf_rx_err("dir buf rx object is null");
1851 		return QDF_STATUS_E_FAILURE;
1852 	}
1853 
1854 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1855 	if (!mod_param) {
1856 		direct_buf_rx_err("dir buf rx module param is null");
1857 		return QDF_STATUS_E_FAILURE;
1858 	}
1859 
1860 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1861 	dbr_buf_pool = mod_param->dbr_buf_pool;
1862 
1863 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
1864 		if (dbr_buf_pool[idx].paddr &&
1865 		    dbr_buf_pool[idx].paddr == paddr) {
1866 			*cookie = idx;
1867 			return QDF_STATUS_SUCCESS;
1868 		}
1869 	}
1870 
1871 	return QDF_STATUS_E_FAILURE;
1872 }
1873 
1874 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev,
1875 				     uint8_t mod_id, qdf_dma_addr_t paddr,
1876 				     uint32_t cookie, uint8_t srng_id)
1877 {
1878 	struct direct_buf_rx_module_param *mod_param;
1879 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1880 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
1881 	void *vaddr;
1882 	QDF_STATUS status;
1883 
1884 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
1885 	if (!dbr_pdev_obj) {
1886 		direct_buf_rx_err("dir buf rx object is null");
1887 		return QDF_STATUS_E_FAILURE;
1888 	}
1889 
1890 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1891 	if (!mod_param) {
1892 		direct_buf_rx_err("dir buf rx module param is null");
1893 		return QDF_STATUS_E_FAILURE;
1894 	}
1895 
1896 	vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie);
1897 	if (!vaddr)
1898 		return QDF_STATUS_E_FAILURE;
1899 
1900 	status = target_if_dbr_replenish_ring(pdev, mod_param,
1901 					      vaddr, cookie);
1902 	if (QDF_IS_STATUS_ERROR(status)) {
1903 		direct_buf_rx_err("Ring replenish failed");
1904 		return QDF_STATUS_E_FAILURE;
1905 	}
1906 
1907 	return QDF_STATUS_SUCCESS;
1908 }
1909 
1910 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev,
1911 			struct direct_buf_rx_module_param *mod_param,
1912 			struct direct_buf_rx_rsp *dbr_rsp,
1913 			struct direct_buf_rx_data *dbr_data,
1914 			uint8_t idx, uint32_t *cookie)
1915 {
1916 	qdf_dma_addr_t paddr = 0;
1917 	uint32_t addr_hi;
1918 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1919 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1920 	struct wlan_objmgr_psoc *psoc;
1921 
1922 	psoc = wlan_pdev_get_psoc(pdev);
1923 	if (!psoc) {
1924 		direct_buf_rx_err("psoc is null");
1925 		return QDF_STATUS_E_FAILURE;
1926 	}
1927 
1928 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1929 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1930 
1931 	if (!dbr_psoc_obj) {
1932 		direct_buf_rx_err("dir buf rx psoc object is null");
1933 		return QDF_STATUS_E_FAILURE;
1934 	}
1935 
1936 	dbr_ring_cap = mod_param->dbr_ring_cap;
1937 	addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET(
1938 				dbr_rsp->dbr_entries[idx].paddr_hi);
1939 	paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 |
1940 				  dbr_rsp->dbr_entries[idx].paddr_lo);
1941 	*cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET(
1942 				dbr_rsp->dbr_entries[idx].paddr_hi);
1943 	dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie);
1944 
1945 	if (!dbr_data->vaddr) {
1946 		direct_buf_rx_debug("dbr vaddr lookup failed, cookie %d, hi %x, lo %x",
1947 				    *cookie, dbr_rsp->dbr_entries[idx].paddr_hi,
1948 				    dbr_rsp->dbr_entries[idx].paddr_lo);
1949 		return QDF_STATUS_E_FAILURE;
1950 	}
1951 
1952 	dbr_data->cookie = *cookie;
1953 	dbr_data->paddr = paddr;
1954 	direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK",
1955 			    dbr_data->cookie, dbr_data->vaddr);
1956 	dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len;
1957 	qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr,
1958 				    QDF_DMA_FROM_DEVICE,
1959 				    dbr_ring_cap->min_buf_size);
1960 
1961 	return QDF_STATUS_SUCCESS;
1962 }
1963 
1964 #ifdef DBR_MULTI_SRNG_ENABLE
1965 /**
1966  * dbr_get_pdev_and_srng_id() - get pdev object and srng id
1967  *
1968  * @psoc: pointer to psoc object
1969  * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid
1970  * @srng_id:  pointer to return srng id
1971  *
1972  * Return : pointer to pdev
1973  */
1974 static struct wlan_objmgr_pdev *
1975 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1976 			 uint8_t *srng_id)
1977 {
1978 	struct wlan_objmgr_pdev *pdev;
1979 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
1980 
1981 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
1982 	if (!pdev) {
1983 		pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC,
1984 						  dbr_mod_id);
1985 		if (pdev) {
1986 			direct_buf_rx_debug("update srng id from %d to %d",
1987 					    *srng_id, pdev_id);
1988 			*srng_id = pdev_id;
1989 		}
1990 	}
1991 
1992 	return pdev;
1993 }
1994 #else
1995 static struct wlan_objmgr_pdev *
1996 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1997 			 uint8_t *srng_id)
1998 {
1999 	struct wlan_objmgr_pdev *pdev;
2000 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
2001 
2002 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
2003 
2004 	return pdev;
2005 }
2006 #endif
2007 
2008 #ifdef DIRECT_BUF_RX_DEBUG
2009 /**
2010  * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry
2011  * @pdev: pointer to pdev object
2012  * @mod_id: Module ID
2013  * @event: ring debug event
2014  *
2015  * Log the given event, head and tail pointers of DBR ring of the given module
2016  * into its ring debug data structure.
2017  * Also, log the timestamp at the time of logging.
2018  */
2019 static void target_if_dbr_add_ring_debug_entry(
2020 	struct wlan_objmgr_pdev *pdev,
2021 	uint32_t mod_id,
2022 	enum DBR_RING_DEBUG_EVENT event,
2023 	uint8_t srng_id)
2024 {
2025 	struct wlan_objmgr_psoc *psoc;
2026 	void *hal_soc, *srng;
2027 	uint32_t hp = 0, tp = 0;
2028 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2029 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2030 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2031 	struct direct_buf_rx_module_debug *mod_debug;
2032 	struct direct_buf_rx_module_param *mod_param;
2033 	struct direct_buf_rx_ring_debug *ring_debug;
2034 	struct direct_buf_rx_ring_debug_entry *entry;
2035 
2036 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
2037 
2038 	if (!mod_debug)
2039 		return;
2040 
2041 	psoc = wlan_pdev_get_psoc(pdev);
2042 
2043 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
2044 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2045 
2046 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
2047 				psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2048 
2049 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
2050 	if (!mod_param) {
2051 		direct_buf_rx_err("dir buf rx module param is null");
2052 		return;
2053 	}
2054 
2055 	hal_soc = dbr_psoc_obj->hal_soc;
2056 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2057 	srng = dbr_ring_cfg->srng;
2058 	ring_debug = &mod_debug->dbr_ring_debug[srng_id];
2059 
2060 	if (ring_debug->entries) {
2061 		if (hal_le_srng_access_start_in_cpu_order(hal_soc, srng)) {
2062 			direct_buf_rx_err("module %d - HAL srng access failed",
2063 					  mod_id);
2064 			return;
2065 		}
2066 		hal_get_sw_hptp(hal_soc, srng, &tp, &hp);
2067 		hal_le_srng_access_end_in_cpu_order(hal_soc, srng);
2068 		tp = qdf_le32_to_cpu(tp);
2069 		entry = &ring_debug->entries[ring_debug->ring_debug_idx];
2070 
2071 		entry->head_idx = hp;
2072 		entry->tail_idx = tp;
2073 		entry->timestamp = qdf_get_log_timestamp();
2074 		entry->event = event;
2075 
2076 		ring_debug->ring_debug_idx++;
2077 		if (ring_debug->ring_debug_idx ==
2078 			ring_debug->num_ring_debug_entries)
2079 			ring_debug->ring_debug_idx = 0;
2080 	}
2081 }
2082 
2083 #else
2084 static void target_if_dbr_add_ring_debug_entry(
2085 	struct wlan_objmgr_pdev *pdev,
2086 	uint32_t mod_id,
2087 	enum DBR_RING_DEBUG_EVENT event,
2088 	uint8_t srng_id)
2089 {
2090 }
2091 #endif /* DIRECT_BUF_RX_DEBUG */
2092 
2093 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn,
2094 						uint8_t *data_buf,
2095 						uint32_t data_len)
2096 {
2097 	int ret = 0;
2098 	uint8_t i = 0;
2099 	QDF_STATUS status;
2100 	uint32_t cookie = 0;
2101 	struct direct_buf_rx_rsp dbr_rsp = {0};
2102 	struct direct_buf_rx_data dbr_data = {0};
2103 	struct wlan_objmgr_psoc *psoc;
2104 	struct wlan_objmgr_pdev *pdev;
2105 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2106 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2107 	struct direct_buf_rx_module_param *mod_param;
2108 	struct wmi_unified *wmi_handle;
2109 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
2110 	uint8_t srng_id = 0;
2111 
2112 	direct_buf_rx_enter();
2113 
2114 	psoc = target_if_get_psoc_from_scn_hdl(scn);
2115 	if (!psoc) {
2116 		direct_buf_rx_err("psoc is null");
2117 		return QDF_STATUS_E_FAILURE;
2118 	}
2119 
2120 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
2121 	if (!wmi_handle) {
2122 		direct_buf_rx_err("WMI handle is null");
2123 		return QDF_STATUS_E_FAILURE;
2124 	}
2125 
2126 	if (wmi_extract_dbr_buf_release_fixed(
2127 		wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) {
2128 		direct_buf_rx_err("unable to extract DBR rsp fixed param");
2129 		return QDF_STATUS_E_FAILURE;
2130 	}
2131 
2132 	direct_buf_rx_debug("Num buf release entry = %d",
2133 			    dbr_rsp.num_buf_release_entry);
2134 
2135 	pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id,
2136 					&srng_id);
2137 	if (!pdev || (srng_id >= DBR_SRNG_NUM)) {
2138 		direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d",
2139 				  pdev, srng_id);
2140 		return QDF_STATUS_E_INVAL;
2141 	}
2142 
2143 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2144 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2145 
2146 	if (!dbr_pdev_obj) {
2147 		direct_buf_rx_err("dir buf rx object is null");
2148 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2149 		return QDF_STATUS_E_FAILURE;
2150 	}
2151 
2152 	if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) {
2153 		direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id);
2154 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2155 		return QDF_STATUS_E_FAILURE;
2156 	}
2157 	mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]);
2158 
2159 	if (!mod_param) {
2160 		direct_buf_rx_err("dir buf rx module param is null");
2161 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2162 		return QDF_STATUS_E_FAILURE;
2163 	}
2164 
2165 	dbr_buf_pool = mod_param->dbr_buf_pool;
2166 	dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry *
2167 					sizeof(struct direct_buf_rx_entry));
2168 	if (!dbr_rsp.dbr_entries) {
2169 		direct_buf_rx_err("invalid dbr_entries");
2170 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2171 		return QDF_STATUS_E_FAILURE;
2172 	}
2173 
2174 	if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) {
2175 		direct_buf_rx_err("More than expected number of metadata");
2176 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2177 		return QDF_STATUS_E_FAILURE;
2178 	}
2179 
2180 	for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) {
2181 		if (wmi_extract_dbr_buf_release_entry(
2182 			wmi_handle, data_buf, i,
2183 			&dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) {
2184 			direct_buf_rx_err("Unable to extract DBR buf entry %d",
2185 					  i+1);
2186 			qdf_mem_free(dbr_rsp.dbr_entries);
2187 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2188 			return QDF_STATUS_E_FAILURE;
2189 		}
2190 		status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp,
2191 						&dbr_data, i, &cookie);
2192 
2193 		if (QDF_IS_STATUS_ERROR(status)) {
2194 			direct_buf_rx_err("DBR data get failed");
2195 			qdf_mem_free(dbr_rsp.dbr_entries);
2196 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2197 			return QDF_STATUS_E_FAILURE;
2198 		}
2199 
2200 		dbr_data.meta_data_valid = false;
2201 		if (i < dbr_rsp.num_meta_data_entry) {
2202 			if (wmi_extract_dbr_buf_metadata(
2203 				wmi_handle, data_buf, i,
2204 				&dbr_data.meta_data) == QDF_STATUS_SUCCESS)
2205 				dbr_data.meta_data_valid = true;
2206 		}
2207 
2208 		target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id,
2209 						   DBR_RING_DEBUG_EVENT_RX,
2210 						   srng_id);
2211 		if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) {
2212 			status = target_if_dbr_replenish_ring(pdev, mod_param,
2213 							      dbr_data.vaddr,
2214 							      cookie);
2215 
2216 			target_if_dbr_add_ring_debug_entry(
2217 				pdev, dbr_rsp.mod_id,
2218 				DBR_RING_DEBUG_EVENT_REPLENISH_RING,
2219 				srng_id);
2220 
2221 			if (QDF_IS_STATUS_ERROR(status)) {
2222 				direct_buf_rx_err("Ring replenish failed");
2223 				qdf_mem_free(dbr_rsp.dbr_entries);
2224 				wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2225 				return QDF_STATUS_E_FAILURE;
2226 			}
2227 		}
2228 	}
2229 
2230 	qdf_mem_free(dbr_rsp.dbr_entries);
2231 	wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2232 
2233 	return ret;
2234 }
2235 
2236 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev,
2237 			struct direct_buf_rx_psoc_obj *dbr_psoc_obj,
2238 			struct direct_buf_rx_module_param *mod_param)
2239 {
2240 	uint32_t idx;
2241 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2242 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
2243 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2244 
2245 	direct_buf_rx_enter();
2246 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2247 	dbr_ring_cap = mod_param->dbr_ring_cap;
2248 	dbr_buf_pool = mod_param->dbr_buf_pool;
2249 
2250 	direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK",
2251 			   dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool);
2252 
2253 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
2254 		qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev,
2255 			(qdf_dma_addr_t)dbr_buf_pool[idx].paddr,
2256 			QDF_DMA_FROM_DEVICE,
2257 			dbr_ring_cap->min_buf_size);
2258 		target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size,
2259 				      dbr_buf_pool[idx].vaddr,
2260 				      dbr_buf_pool[idx].offset,
2261 				      dbr_ring_cap->min_buf_align,
2262 				      mod_param->mod_id);
2263 	}
2264 
2265 	return QDF_STATUS_SUCCESS;
2266 }
2267 
2268 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev,
2269 			struct direct_buf_rx_module_param *mod_param)
2270 {
2271 	struct wlan_objmgr_psoc *psoc;
2272 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2273 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2274 
2275 	direct_buf_rx_enter();
2276 	psoc = wlan_pdev_get_psoc(pdev);
2277 	if (!psoc) {
2278 		direct_buf_rx_err("psoc is null");
2279 		return QDF_STATUS_E_FAILURE;
2280 	}
2281 
2282 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2283 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2284 
2285 	if (!dbr_psoc_obj) {
2286 		direct_buf_rx_err("dir buf rx psoc object is null");
2287 		return QDF_STATUS_E_FAILURE;
2288 	}
2289 	direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj);
2290 
2291 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2292 	if (dbr_ring_cfg) {
2293 		target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param);
2294 		hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng);
2295 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
2296 					dbr_psoc_obj->osdev->dev,
2297 					dbr_ring_cfg->ring_alloc_size,
2298 					dbr_ring_cfg->base_vaddr_unaligned,
2299 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
2300 	}
2301 
2302 	return QDF_STATUS_SUCCESS;
2303 }
2304 
2305 static QDF_STATUS target_if_dbr_deinit_srng(
2306 			struct wlan_objmgr_pdev *pdev,
2307 			struct direct_buf_rx_module_param *mod_param)
2308 {
2309 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2310 
2311 	direct_buf_rx_enter();
2312 	dbr_buf_pool = mod_param->dbr_buf_pool;
2313 	direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool);
2314 	target_if_dbr_deinit_ring(pdev, mod_param);
2315 	if (mod_param->dbr_buf_pool)
2316 		qdf_mem_free(dbr_buf_pool);
2317 	mod_param->dbr_buf_pool = NULL;
2318 
2319 	return QDF_STATUS_SUCCESS;
2320 }
2321 
2322 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev,
2323 			struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
2324 			enum DBR_MODULE mod_id, uint8_t srng_id)
2325 {
2326 	struct direct_buf_rx_module_param *mod_param;
2327 
2328 	direct_buf_rx_enter();
2329 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
2330 
2331 	if (!mod_param) {
2332 		direct_buf_rx_err("dir buf rx module param is null");
2333 		return QDF_STATUS_E_FAILURE;
2334 	}
2335 	direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK",
2336 			    mod_param, mod_param->dbr_ring_cap);
2337 
2338 	if (!mod_param->registered) {
2339 		direct_buf_rx_err("module(%d) srng(%d) was not registered",
2340 				  mod_id, srng_id);
2341 		return QDF_STATUS_SUCCESS;
2342 	}
2343 
2344 	target_if_dbr_deinit_srng(pdev, mod_param);
2345 	if (mod_param->dbr_ring_cap)
2346 		qdf_mem_free(mod_param->dbr_ring_cap);
2347 	mod_param->dbr_ring_cap = NULL;
2348 	if (mod_param->dbr_ring_cfg)
2349 		qdf_mem_free(mod_param->dbr_ring_cfg);
2350 	mod_param->dbr_ring_cfg = NULL;
2351 
2352 	mod_param->registered = false;
2353 
2354 	return QDF_STATUS_SUCCESS;
2355 }
2356 
2357 QDF_STATUS target_if_direct_buf_rx_register_events(
2358 				struct wlan_objmgr_psoc *psoc)
2359 {
2360 	QDF_STATUS ret;
2361 
2362 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
2363 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
2364 		return QDF_STATUS_E_INVAL;
2365 	}
2366 
2367 	ret = wmi_unified_register_event_handler(
2368 			get_wmi_unified_hdl_from_psoc(psoc),
2369 			wmi_dma_buf_release_event_id,
2370 			target_if_direct_buf_rx_rsp_event_handler,
2371 			WMI_RX_UMAC_CTX);
2372 
2373 	if (QDF_IS_STATUS_ERROR(ret))
2374 		direct_buf_rx_debug("event handler not supported, ret=%d", ret);
2375 
2376 	return QDF_STATUS_SUCCESS;
2377 }
2378 
2379 QDF_STATUS target_if_direct_buf_rx_unregister_events(
2380 				struct wlan_objmgr_psoc *psoc)
2381 {
2382 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
2383 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
2384 		return QDF_STATUS_E_INVAL;
2385 	}
2386 
2387 	wmi_unified_unregister_event_handler(
2388 			get_wmi_unified_hdl_from_psoc(psoc),
2389 			wmi_dma_buf_release_event_id);
2390 
2391 	return QDF_STATUS_SUCCESS;
2392 }
2393 
2394 QDF_STATUS target_if_direct_buf_rx_print_ring_stat(
2395 				struct wlan_objmgr_pdev *pdev)
2396 {
2397 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2398 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2399 	struct wlan_objmgr_psoc *psoc;
2400 	void *srng, *hal_soc;
2401 	uint32_t hp = 0, tp = 0;
2402 	struct direct_buf_rx_module_param *mod_param;
2403 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2404 	uint8_t num_modules, mod_idx;
2405 	uint8_t srng_id;
2406 
2407 	if (!pdev) {
2408 		direct_buf_rx_err("pdev is null");
2409 		return QDF_STATUS_E_INVAL;
2410 	}
2411 
2412 	psoc = wlan_pdev_get_psoc(pdev);
2413 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2414 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2415 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2416 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2417 	hal_soc = dbr_psoc_obj->hal_soc;
2418 	num_modules = dbr_pdev_obj->num_modules;
2419 	direct_buf_rx_debug("--------------------------------------------------");
2420 	direct_buf_rx_debug("| Module ID |    Module    | Head Idx | Tail Idx |");
2421 	direct_buf_rx_debug("--------------------------------------------------");
2422 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
2423 		for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
2424 			mod_param =
2425 				&dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id];
2426 			dbr_ring_cfg = mod_param->dbr_ring_cfg;
2427 			if (!dbr_ring_cfg) {
2428 				direct_buf_rx_info("dbr_ring_cfg is NULL");
2429 				direct_buf_rx_info("mod id %d mod %s", mod_idx,
2430 						   g_dbr_module_name[mod_idx].
2431 						   module_name_str);
2432 				continue;
2433 			}
2434 			srng = dbr_ring_cfg->srng;
2435 			hal_get_sw_hptp(hal_soc, srng, &tp, &hp);
2436 			tp = qdf_le32_to_cpu(tp);
2437 			direct_buf_rx_debug("|%11d|%14s|%10x|%10x|",
2438 					    mod_idx, g_dbr_module_name[mod_idx].
2439 					    module_name_str,
2440 					    hp, tp);
2441 		}
2442 	}
2443 	direct_buf_rx_debug("--------------------------------------------------");
2444 
2445 	return QDF_STATUS_SUCCESS;
2446 }
2447 
2448 QDF_STATUS
2449 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev,
2450 					struct module_ring_params *param,
2451 					uint8_t mod_id, uint8_t srng_id)
2452 {
2453 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2454 	struct direct_buf_rx_module_param *dbr_mod_param;
2455 
2456 	if (!pdev) {
2457 		direct_buf_rx_err("pdev context passed is null");
2458 		return QDF_STATUS_E_INVAL;
2459 	}
2460 
2461 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
2462 			(pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2463 
2464 	if (!dbr_pdev_obj) {
2465 		direct_buf_rx_err("dir buf rx object is null");
2466 		return QDF_STATUS_E_FAILURE;
2467 	}
2468 
2469 	if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) {
2470 		direct_buf_rx_err("invalid params, mod id %d, srng id %d",
2471 				  mod_id, srng_id);
2472 		return QDF_STATUS_E_INVAL;
2473 	}
2474 
2475 	dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
2476 	param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr;
2477 	param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size;
2478 
2479 	return QDF_STATUS_SUCCESS;
2480 }
2481