xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
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 	dbr_psoc_obj->handler_ctx = WMI_RX_UMAC_CTX;
827 
828 	return status;
829 
830 attach_error:
831 	qdf_mem_free(dbr_psoc_obj);
832 
833 	return status;
834 }
835 
836 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler(
837 	struct wlan_objmgr_psoc *psoc, void *data)
838 {
839 	QDF_STATUS status;
840 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
841 
842 	direct_buf_rx_enter();
843 
844 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
845 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
846 
847 	if (!dbr_psoc_obj) {
848 		direct_buf_rx_err("dir buf rx psoc obj is null");
849 		return QDF_STATUS_E_FAILURE;
850 	}
851 
852 	target_if_dbr_deinit_mem_list(dbr_psoc_obj);
853 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
854 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
855 				dbr_psoc_obj);
856 
857 	if (status != QDF_STATUS_SUCCESS) {
858 		direct_buf_rx_err("failed to detach dir buf rx component %d",
859 				  status);
860 	}
861 
862 	qdf_mem_free(dbr_psoc_obj);
863 
864 	return status;
865 }
866 
867 #if defined(WLAN_DEBUGFS) && defined(DIRECT_BUF_RX_DEBUG)
868 /**
869  * target_if_dbr_debugfs_show_ring_debug() - Function to display ring debug
870  * entries in debugfs
871  * @file: qdf debugfs file handler
872  * @arg: pointer to DBR debugfs private object
873  *
874  * Return: QDF_STATUS of operation
875  */
876 static QDF_STATUS target_if_dbr_debugfs_show_ring_debug(
877 	qdf_debugfs_file_t file, void *arg)
878 {
879 	struct dbr_debugfs_priv *priv = arg;
880 
881 	return target_if_dbr_print_ring_debug_entries(qdf_debugfs_printer,
882 						      file, priv->dbr_pdev_obj,
883 						      priv->mod_id,
884 						      priv->srng_id);
885 }
886 
887 /**
888  * target_if_dbr_mod_debugfs_init() - Init debugfs for a given module
889  * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module
890  * @mod_id: Module ID corresponding to this ring
891  *
892  * Return: QDF_STATUS of operation
893  */
894 static QDF_STATUS target_if_dbr_mod_debugfs_init(
895 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
896 	enum DBR_MODULE mod_id)
897 {
898 	struct direct_buf_rx_module_debug *mod_debug;
899 
900 	mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj,
901 								  mod_id);
902 
903 	if (!mod_debug)
904 		return QDF_STATUS_E_INVAL;
905 
906 	if (mod_debug->debugfs_entry) {
907 		direct_buf_rx_err("debugfs mod entry was already created for %s module",
908 				  g_dbr_module_name[mod_id].module_name_str);
909 		return QDF_STATUS_SUCCESS;
910 	}
911 
912 	mod_debug->debugfs_entry =
913 	    qdf_debugfs_create_dir(g_dbr_module_name[mod_id].module_name_str,
914 				   dbr_pdev_obj->debugfs_entry);
915 
916 	if (!mod_debug->debugfs_entry) {
917 		direct_buf_rx_err("error while creating direct_buf debugfs entry for %s module",
918 				  g_dbr_module_name[mod_id].module_name_str);
919 		return QDF_STATUS_E_FAILURE;
920 	}
921 
922 	return QDF_STATUS_SUCCESS;
923 }
924 
925 /**
926  * target_if_dbr_ring_debugfs_init() - Init debugfs for a given ring
927  * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module
928  * @mod_id: Module ID corresponding to this ring
929  * @srng_id: srng ID corresponding to this ring
930  *
931  * Return: QDF_STATUS of operation
932  */
933 static QDF_STATUS target_if_dbr_ring_debugfs_init(
934 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
935 	enum DBR_MODULE mod_id, uint8_t srng_id)
936 {
937 	struct direct_buf_rx_module_debug *mod_debug;
938 	struct direct_buf_rx_ring_debug *ring_debug;
939 	struct dbr_debugfs_priv *priv;
940 	char debug_file_name[32];
941 
942 	mod_debug = target_if_get_dbr_mod_debug_from_dbr_pdev_obj(dbr_pdev_obj,
943 								  mod_id);
944 
945 	if (!mod_debug)
946 		return QDF_STATUS_E_INVAL;
947 
948 	ring_debug = &mod_debug->dbr_ring_debug[srng_id];
949 
950 	if (!mod_debug->debugfs_entry) {
951 		direct_buf_rx_err("error mod_debug->debugfs_entry not created");
952 		return QDF_STATUS_E_FAILURE;
953 	}
954 
955 	if (ring_debug->debugfs_entry) {
956 		direct_buf_rx_err("debugfs file for %d ring under %s module already created",
957 				   srng_id,
958 				   g_dbr_module_name[mod_id].module_name_str);
959 		return QDF_STATUS_SUCCESS;
960 	}
961 
962 	qdf_snprintf(debug_file_name, sizeof(debug_file_name),
963 		     "ring_%d", srng_id);
964 
965 	// Allocate debugfs ops
966 	ring_debug->debugfs_fops =
967 		qdf_mem_malloc(sizeof(*ring_debug->debugfs_fops));
968 	if (!ring_debug->debugfs_fops) {
969 		direct_buf_rx_err("error in allocating debugfs ops");
970 		return QDF_STATUS_E_NOMEM;
971 	}
972 
973 	// Allocate private data
974 	priv = qdf_mem_malloc(sizeof(*priv));
975 	if (!priv) {
976 		direct_buf_rx_err("error in creating debugfs private data");
977 		goto priv_alloc_fail;
978 	}
979 	priv->dbr_pdev_obj = dbr_pdev_obj;
980 	priv->mod_id = mod_id;
981 	priv->srng_id = srng_id;
982 
983 	/* Fill in the debugfs ops for this ring.
984 	 * When the output time comes, the 'show' function will be
985 	 * called with 'priv' as an argument.
986 	 */
987 	ring_debug->debugfs_fops->show = target_if_dbr_debugfs_show_ring_debug;
988 	ring_debug->debugfs_fops->priv = priv;
989 
990 	ring_debug->debugfs_entry =
991 		qdf_debugfs_create_file_simplified(
992 				    debug_file_name,
993 				    (QDF_FILE_USR_READ | QDF_FILE_GRP_READ |
994 				    QDF_FILE_OTH_READ),
995 				    mod_debug->debugfs_entry,
996 				    ring_debug->debugfs_fops);
997 
998 	if (!ring_debug->debugfs_entry) {
999 		direct_buf_rx_err("error while creating direct_buf debugfs file for %d ring under %s module",
1000 				  srng_id,
1001 				  g_dbr_module_name[mod_id].module_name_str);
1002 		goto file_creation_fail;
1003 	}
1004 
1005 	return QDF_STATUS_SUCCESS;
1006 
1007 file_creation_fail:
1008 	qdf_mem_free(ring_debug->debugfs_fops->priv);
1009 
1010 priv_alloc_fail:
1011 	qdf_mem_free(ring_debug->debugfs_fops);
1012 	ring_debug->debugfs_fops = NULL;
1013 	return QDF_STATUS_E_NOMEM;
1014 }
1015 
1016 /**
1017  * target_if_dbr_mod_debugfs_deinit() - De-init debugfs for a given module
1018  * @mod_debug: Pointer to direct_buf_rx_module_debug structure
1019  *
1020  * Return: void
1021  */
1022 static void target_if_dbr_mod_debugfs_deinit(
1023 			struct direct_buf_rx_module_debug *mod_debug)
1024 {
1025 	if (!mod_debug) {
1026 		direct_buf_rx_err("mod_debug is null");
1027 		return;
1028 	}
1029 
1030 	if (mod_debug->debugfs_entry) {
1031 		qdf_debugfs_remove_file(mod_debug->debugfs_entry);
1032 		mod_debug->debugfs_entry = NULL;
1033 	}
1034 }
1035 
1036 /**
1037  * target_if_dbr_ring_debugfs_deinit() - De-init debugfs for a given ring
1038  * @ring_debug: Pointer to direct_buf_rx_ring_debug structure
1039  *
1040  * Return: void
1041  */
1042 static void target_if_dbr_ring_debugfs_deinit(
1043 	struct direct_buf_rx_ring_debug *ring_debug)
1044 {
1045 	if (!ring_debug) {
1046 		direct_buf_rx_err("ring_debug is null");
1047 		return;
1048 	}
1049 
1050 	if (ring_debug->debugfs_entry) {
1051 		qdf_debugfs_remove_file(ring_debug->debugfs_entry);
1052 		ring_debug->debugfs_entry = NULL;
1053 	}
1054 
1055 	// Free the private data and debugfs ops of this ring
1056 	if (ring_debug->debugfs_fops) {
1057 		qdf_mem_free(ring_debug->debugfs_fops->priv);
1058 		qdf_mem_free(ring_debug->debugfs_fops);
1059 		ring_debug->debugfs_fops = NULL;
1060 	}
1061 }
1062 #endif /* WLAN_DEBUGFS && DIRECT_BUF_RX_DEBUG */
1063 
1064 #ifdef DIRECT_BUF_RX_DEBUG
1065 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev,
1066 					 uint8_t mod_id)
1067 {
1068 	struct direct_buf_rx_module_debug *mod_debug;
1069 	struct direct_buf_rx_ring_debug *ring_debug;
1070 	uint8_t srng_id;
1071 
1072 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1073 	if (!mod_debug)
1074 		return QDF_STATUS_E_INVAL;
1075 
1076 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1077 		ring_debug = &mod_debug->dbr_ring_debug[srng_id];
1078 		if (!ring_debug->entries) {
1079 			direct_buf_rx_debug("DBR ring debug for module %d srng %d was already disabled",
1080 					   mod_id, srng_id);
1081 			continue;
1082 		}
1083 		/* De-init debugsfs for this ring */
1084 		target_if_dbr_ring_debugfs_deinit(ring_debug);
1085 		qdf_mem_free(ring_debug->entries);
1086 		ring_debug->entries = NULL;
1087 		ring_debug->ring_debug_idx = 0;
1088 		ring_debug->num_ring_debug_entries = 0;
1089 		direct_buf_rx_info("DBR ring debug for module %d srng %d is now stopped",
1090 				   mod_id, srng_id);
1091 	}
1092 	target_if_dbr_mod_debugfs_deinit(mod_debug);
1093 
1094 	return QDF_STATUS_SUCCESS;
1095 }
1096 
1097 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev,
1098 					  uint8_t mod_id,
1099 					  uint32_t num_ring_debug_entries)
1100 {
1101 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1102 	struct direct_buf_rx_module_debug *mod_debug;
1103 	struct direct_buf_rx_ring_debug *ring_debug;
1104 	uint8_t srng_id;
1105 
1106 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1107 
1108 	if (!mod_debug)
1109 		return QDF_STATUS_E_INVAL;
1110 
1111 	if (num_ring_debug_entries > DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES) {
1112 		direct_buf_rx_err("Requested number of ring debug entries(%d) exceed the maximum entries allowed(%d)",
1113 				  num_ring_debug_entries,
1114 				  DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES);
1115 
1116 		return QDF_STATUS_E_FAILURE;
1117 	}
1118 
1119 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
1120 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1121 
1122 	target_if_dbr_mod_debugfs_init(dbr_pdev_obj, mod_id);
1123 
1124 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1125 		ring_debug = &mod_debug->dbr_ring_debug[srng_id];
1126 
1127 		if (ring_debug->entries) {
1128 			direct_buf_rx_err("DBR ring debug for module %d srng %d was already enabled",
1129 					  mod_id, srng_id);
1130 			continue;
1131 		}
1132 
1133 		ring_debug->entries = qdf_mem_malloc(
1134 					num_ring_debug_entries *
1135 					sizeof(*ring_debug->entries));
1136 
1137 		if (!ring_debug->entries)
1138 			return QDF_STATUS_E_NOMEM;
1139 
1140 		ring_debug->ring_debug_idx = 0;
1141 		ring_debug->num_ring_debug_entries = num_ring_debug_entries;
1142 		/* Init debugsfs for this ring */
1143 		target_if_dbr_ring_debugfs_init(
1144 			dbr_pdev_obj,
1145 			mod_id, srng_id);
1146 		direct_buf_rx_info("DBR ring debug for module %d srng %d is now started",
1147 				    mod_id, srng_id);
1148 	}
1149 	return QDF_STATUS_SUCCESS;
1150 }
1151 
1152 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
1153 						uint8_t mod_id, uint32_t value)
1154 {
1155 	struct direct_buf_rx_module_debug *mod_debug;
1156 
1157 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1158 
1159 	if (!mod_debug)
1160 		return QDF_STATUS_E_INVAL;
1161 
1162 	mod_debug->poisoning_enabled = true;
1163 	mod_debug->poison_value = value; /* Save the poison value */
1164 
1165 	direct_buf_rx_debug("DBR buffer poisoning for module %d is now started",
1166 			    mod_id);
1167 	return QDF_STATUS_SUCCESS;
1168 }
1169 
1170 QDF_STATUS target_if_dbr_stop_buffer_poisoning(
1171 	struct wlan_objmgr_pdev *pdev,
1172 	uint8_t mod_id)
1173 {
1174 	struct direct_buf_rx_module_debug *mod_debug;
1175 
1176 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1177 
1178 	if (!mod_debug)
1179 		return QDF_STATUS_E_INVAL;
1180 
1181 	mod_debug->poisoning_enabled = false;
1182 	mod_debug->poison_value = 0;
1183 
1184 	direct_buf_rx_debug("DBR buffer poisoning for module %d is now stopped",
1185 			    mod_id);
1186 	return QDF_STATUS_SUCCESS;
1187 }
1188 
1189 /**
1190  * target_if_dbr_fill_buffer_u32() - Fill buffer with an unsigned 32-bit value
1191  * @buffer: pointer to the buffer
1192  * @num_bytes: Size of the destination buffer in bytes
1193  * @value: Unsigned 32-bit value to be copied
1194  *
1195  * Return : void
1196  */
1197 static void
1198 target_if_dbr_fill_buffer_u32(uint8_t *buffer, uint32_t num_bytes,
1199 			      uint32_t value)
1200 {
1201 	uint32_t *bufp;
1202 	uint32_t idx;
1203 	uint32_t size = (num_bytes >> 2);
1204 
1205 	if (!buffer) {
1206 		direct_buf_rx_err("buffer empty");
1207 		return;
1208 	}
1209 
1210 	bufp = (uint32_t *)buffer;
1211 
1212 	for (idx = 0; idx < size; ++idx) {
1213 		*bufp = value;
1214 		++bufp;
1215 	}
1216 }
1217 
1218 /**
1219  * target_if_dbr_debug_poison_buffer() - Poison a given DBR buffer
1220  * @pdev: pointer to pdev object
1221  * @mod_id: Module ID of the owner of the buffer
1222  * @aligned_vaddr: Virtual address(aligned) of the buffer
1223  * @size: Size of the buffer
1224  *
1225  * Value with which the buffers will be poisoned would have been saved
1226  * while starting the buffer poisoning for the module, use that value.
1227  *
1228  * Return : QDF status of operation
1229  */
1230 static QDF_STATUS target_if_dbr_debug_poison_buffer(
1231 	struct wlan_objmgr_pdev *pdev,
1232 	uint32_t mod_id, void *aligned_vaddr, uint32_t size)
1233 {
1234 	struct direct_buf_rx_module_debug *mod_debug;
1235 
1236 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
1237 
1238 	if (!mod_debug)
1239 		return QDF_STATUS_E_INVAL;
1240 
1241 	if (mod_debug->poisoning_enabled) {
1242 		target_if_dbr_fill_buffer_u32(aligned_vaddr, size,
1243 					      mod_debug->poison_value);
1244 	}
1245 
1246 	return QDF_STATUS_SUCCESS;
1247 }
1248 
1249 static inline void target_if_dbr_qdf_show_ring_debug(
1250 	struct wlan_objmgr_pdev *pdev,
1251 	uint8_t mod_id, uint8_t srng_id)
1252 {
1253 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj =
1254 			wlan_objmgr_pdev_get_comp_private_obj(
1255 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1256 
1257 	target_if_dbr_print_ring_debug_entries(
1258 			target_if_dbr_qdf_err_printer,
1259 			NULL, dbr_pdev_obj,
1260 			mod_id, srng_id);
1261 }
1262 #else
1263 QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev,
1264 					 uint8_t mod_id)
1265 {
1266 	return QDF_STATUS_SUCCESS;
1267 }
1268 
1269 QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev,
1270 					  uint8_t mod_id,
1271 					  uint32_t num_ring_debug_entries)
1272 {
1273 	return QDF_STATUS_SUCCESS;
1274 }
1275 
1276 QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
1277 						uint8_t mod_id, uint32_t value)
1278 {
1279 	return QDF_STATUS_SUCCESS;
1280 }
1281 
1282 QDF_STATUS target_if_dbr_stop_buffer_poisoning(
1283 		struct wlan_objmgr_pdev *pdev,
1284 		uint8_t mod_id)
1285 {
1286 	return QDF_STATUS_SUCCESS;
1287 }
1288 
1289 static QDF_STATUS target_if_dbr_debug_poison_buffer(
1290 	struct wlan_objmgr_pdev *pdev,
1291 	uint32_t mod_id, void *aligned_vaddr, uint32_t size)
1292 {
1293 	return QDF_STATUS_SUCCESS;
1294 }
1295 
1296 static inline void target_if_dbr_qdf_show_ring_debug(
1297 	struct wlan_objmgr_pdev *pdev,
1298 	uint8_t mod_id, uint8_t srng_id)
1299 {
1300 }
1301 #endif /* DIRECT_BUF_RX_DEBUG */
1302 
1303 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev,
1304 			struct direct_buf_rx_module_param *mod_param,
1305 			void *aligned_vaddr, uint32_t cookie)
1306 {
1307 	uint32_t *ring_entry;
1308 	uint32_t dw_lo, dw_hi = 0, map_status;
1309 	void *hal_soc, *srng;
1310 	qdf_dma_addr_t paddr;
1311 	struct wlan_objmgr_psoc *psoc;
1312 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1313 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1314 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1315 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1316 
1317 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1318 	dbr_ring_cap = mod_param->dbr_ring_cap;
1319 	dbr_buf_pool = mod_param->dbr_buf_pool;
1320 
1321 	psoc = wlan_pdev_get_psoc(pdev);
1322 
1323 	if (!psoc) {
1324 		direct_buf_rx_err("psoc is null");
1325 		return QDF_STATUS_E_FAILURE;
1326 	}
1327 
1328 	if (cookie >= mod_param->dbr_ring_cfg->num_ptr) {
1329 		direct_buf_rx_err("invalid cookie %d", cookie);
1330 		return QDF_STATUS_E_INVAL;
1331 	}
1332 
1333 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1334 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1335 
1336 	if (!dbr_psoc_obj) {
1337 		direct_buf_rx_err("dir buf rx psoc object is null");
1338 		return QDF_STATUS_E_FAILURE;
1339 	}
1340 
1341 	hal_soc = dbr_psoc_obj->hal_soc;
1342 	srng = dbr_ring_cfg->srng;
1343 	if (!aligned_vaddr) {
1344 		direct_buf_rx_err("aligned vaddr is null");
1345 		return QDF_STATUS_SUCCESS;
1346 	}
1347 
1348 	target_if_dbr_debug_poison_buffer(
1349 			pdev, mod_param->mod_id, aligned_vaddr,
1350 			dbr_ring_cap->min_buf_size);
1351 
1352 	map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev,
1353 					       aligned_vaddr,
1354 					       QDF_DMA_FROM_DEVICE,
1355 					       dbr_ring_cap->min_buf_size,
1356 					       &paddr);
1357 	if (map_status) {
1358 		direct_buf_rx_err("mem map failed status = %d", map_status);
1359 		return QDF_STATUS_E_FAILURE;
1360 	}
1361 
1362 	QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align));
1363 	dbr_buf_pool[cookie].paddr = paddr;
1364 
1365 	hal_le_srng_access_start_in_cpu_order(hal_soc, srng);
1366 	ring_entry = hal_srng_src_get_next(hal_soc, srng);
1367 
1368 	if (!ring_entry) {
1369 		target_if_dbr_qdf_show_ring_debug(pdev, mod_param->mod_id,
1370 						  mod_param->srng_id);
1371 		QDF_BUG(0);
1372 	}
1373 
1374 	dw_lo = (uint64_t)paddr & 0xFFFFFFFF;
1375 	WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32);
1376 	WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie);
1377 	*ring_entry = qdf_cpu_to_le32(dw_lo);
1378 	ring_entry++;
1379 	*ring_entry = qdf_cpu_to_le32(dw_hi);
1380 	hal_le_srng_access_end_in_cpu_order(hal_soc, srng);
1381 
1382 	return QDF_STATUS_SUCCESS;
1383 }
1384 
1385 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev,
1386 			  struct direct_buf_rx_module_param *mod_param)
1387 {
1388 	uint32_t idx;
1389 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1390 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1391 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1392 	void *buf_vaddr_unaligned, *buf_vaddr_aligned;
1393 	QDF_STATUS status;
1394 	uint8_t offset = 0;
1395 
1396 	direct_buf_rx_enter();
1397 
1398 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1399 	dbr_ring_cap = mod_param->dbr_ring_cap;
1400 	dbr_buf_pool = mod_param->dbr_buf_pool;
1401 
1402 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
1403 		buf_vaddr_unaligned =
1404 			target_if_dbr_mem_get(pdev, &dbr_ring_cap->min_buf_size,
1405 					      &offset,
1406 					      dbr_ring_cap->min_buf_align,
1407 					      mod_param->mod_id);
1408 		if (!buf_vaddr_unaligned) {
1409 			direct_buf_rx_err("dir buf rx ring alloc failed");
1410 			return QDF_STATUS_E_NOMEM;
1411 		}
1412 
1413 		dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned;
1414 		dbr_buf_pool[idx].offset = offset;
1415 		dbr_buf_pool[idx].cookie = idx;
1416 		buf_vaddr_aligned = buf_vaddr_unaligned + offset;
1417 		status = target_if_dbr_replenish_ring(pdev, mod_param,
1418 						      buf_vaddr_aligned, idx);
1419 		if (QDF_IS_STATUS_ERROR(status)) {
1420 			direct_buf_rx_err("replenish failed with status : %d",
1421 					  status);
1422 			target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size,
1423 					      buf_vaddr_unaligned, offset,
1424 					      dbr_ring_cap->min_buf_align,
1425 					      mod_param->mod_id);
1426 			return QDF_STATUS_E_FAILURE;
1427 		}
1428 	}
1429 
1430 	direct_buf_rx_exit();
1431 
1432 	return QDF_STATUS_SUCCESS;
1433 }
1434 
1435 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev,
1436 			struct direct_buf_rx_module_param *mod_param)
1437 {
1438 	void *srng;
1439 	uint32_t num_entries, ring_alloc_size, max_entries, entry_size;
1440 	qdf_dma_addr_t paddr;
1441 	struct hal_srng_params ring_params = {0};
1442 	struct wlan_objmgr_psoc *psoc;
1443 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1444 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1445 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1446 	QDF_STATUS status;
1447 
1448 	direct_buf_rx_enter();
1449 
1450 	psoc = wlan_pdev_get_psoc(pdev);
1451 
1452 	if (!psoc) {
1453 		direct_buf_rx_err("psoc is null");
1454 		return QDF_STATUS_E_FAILURE;
1455 	}
1456 
1457 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1458 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1459 
1460 	if (!dbr_psoc_obj) {
1461 		direct_buf_rx_err("dir buf rx psoc object is null");
1462 		return QDF_STATUS_E_FAILURE;
1463 	}
1464 
1465 	if (!dbr_psoc_obj->hal_soc ||
1466 	    !dbr_psoc_obj->osdev) {
1467 		direct_buf_rx_err("dir buf rx target attach failed");
1468 		return QDF_STATUS_E_FAILURE;
1469 	}
1470 
1471 	max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc,
1472 					   DIR_BUF_RX_DMA_SRC);
1473 	entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc,
1474 					    DIR_BUF_RX_DMA_SRC);
1475 	direct_buf_rx_debug("Max Entries = %d", max_entries);
1476 	direct_buf_rx_debug("Entry Size = %d", entry_size);
1477 
1478 	status = populate_dbr_cap_mod_param(pdev, mod_param);
1479 	if (QDF_IS_STATUS_ERROR(status)) {
1480 		direct_buf_rx_err("Module cap population failed");
1481 		return QDF_STATUS_E_FAILURE;
1482 	}
1483 
1484 	dbr_ring_cap = mod_param->dbr_ring_cap;
1485 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1486 	num_entries = dbr_ring_cap->ring_elems_min > max_entries ?
1487 			max_entries : dbr_ring_cap->ring_elems_min;
1488 	direct_buf_rx_debug("Num entries = %d", num_entries);
1489 	dbr_ring_cfg->num_ptr = num_entries;
1490 	mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof(
1491 				struct direct_buf_rx_buf_info));
1492 	if (!mod_param->dbr_buf_pool)
1493 		return QDF_STATUS_E_NOMEM;
1494 
1495 	ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1;
1496 	dbr_ring_cfg->ring_alloc_size = ring_alloc_size;
1497 	direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj);
1498 	dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent(
1499 		dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size,
1500 		&paddr);
1501 	direct_buf_rx_debug("vaddr aligned allocated");
1502 	dbr_ring_cfg->base_paddr_unaligned = paddr;
1503 	if (!dbr_ring_cfg->base_vaddr_unaligned) {
1504 		direct_buf_rx_err("dir buf rx vaddr alloc failed");
1505 		qdf_mem_free(mod_param->dbr_buf_pool);
1506 		return QDF_STATUS_E_NOMEM;
1507 	}
1508 
1509 	/* Alignment is defined to 8 for now. Will be advertised by FW */
1510 	dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup(
1511 		(uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned,
1512 		DBR_RING_BASE_ALIGN);
1513 	ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned;
1514 	dbr_ring_cfg->base_paddr_aligned = qdf_roundup(
1515 		(uint64_t)dbr_ring_cfg->base_paddr_unaligned,
1516 		DBR_RING_BASE_ALIGN);
1517 	ring_params.ring_base_paddr =
1518 		(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned;
1519 	ring_params.num_entries = num_entries;
1520 	srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC,
1521 			      mod_param->mod_id,
1522 			      mod_param->pdev_id, &ring_params, 0);
1523 
1524 	if (!srng) {
1525 		direct_buf_rx_err("srng setup failed");
1526 		qdf_mem_free(mod_param->dbr_buf_pool);
1527 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
1528 					dbr_psoc_obj->osdev->dev,
1529 					ring_alloc_size,
1530 					dbr_ring_cfg->base_vaddr_unaligned,
1531 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
1532 		return QDF_STATUS_E_FAILURE;
1533 	}
1534 	dbr_ring_cfg->srng = srng;
1535 	dbr_ring_cfg->tail_idx_addr =
1536 		hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng);
1537 	dbr_ring_cfg->head_idx_addr =
1538 		hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng);
1539 	dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size;
1540 
1541 	return target_if_dbr_fill_ring(pdev, mod_param);
1542 }
1543 
1544 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev,
1545 			struct direct_buf_rx_module_param *mod_param)
1546 {
1547 	QDF_STATUS status;
1548 
1549 	direct_buf_rx_debug("Init DBR srng");
1550 
1551 	if (!mod_param) {
1552 		direct_buf_rx_err("dir buf rx module param is null");
1553 		return QDF_STATUS_E_INVAL;
1554 	}
1555 
1556 	mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof(
1557 					struct direct_buf_rx_ring_cap));
1558 
1559 	if (!mod_param->dbr_ring_cap)
1560 		return QDF_STATUS_E_NOMEM;
1561 
1562 	/* Allocate memory for DBR Ring Config */
1563 	mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof(
1564 					struct direct_buf_rx_ring_cfg));
1565 
1566 	if (!mod_param->dbr_ring_cfg) {
1567 		qdf_mem_free(mod_param->dbr_ring_cap);
1568 		return QDF_STATUS_E_NOMEM;
1569 	}
1570 
1571 	status = target_if_dbr_init_ring(pdev, mod_param);
1572 
1573 	if (QDF_IS_STATUS_ERROR(status)) {
1574 		direct_buf_rx_err("DBR ring init failed");
1575 		qdf_mem_free(mod_param->dbr_ring_cfg);
1576 		qdf_mem_free(mod_param->dbr_ring_cap);
1577 		return QDF_STATUS_E_FAILURE;
1578 	}
1579 
1580 	return QDF_STATUS_SUCCESS;
1581 }
1582 
1583 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev,
1584 			struct direct_buf_rx_module_param *mod_param)
1585 {
1586 	QDF_STATUS status;
1587 	struct wlan_objmgr_psoc *psoc;
1588 	wmi_unified_t wmi_hdl;
1589 	struct direct_buf_rx_cfg_req dbr_cfg_req = {0};
1590 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1591 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1592 	struct dbr_module_config *dbr_config;
1593 
1594 	direct_buf_rx_enter();
1595 
1596 	psoc = wlan_pdev_get_psoc(pdev);
1597 	if (!psoc) {
1598 		direct_buf_rx_err("psoc is null");
1599 		return QDF_STATUS_E_FAILURE;
1600 	}
1601 
1602 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1603 	dbr_ring_cap = mod_param->dbr_ring_cap;
1604 	dbr_config = &mod_param->dbr_config;
1605 	wmi_hdl = lmac_get_pdev_wmi_handle(pdev);
1606 	if (!wmi_hdl) {
1607 		direct_buf_rx_err("WMI handle null. Can't send WMI CMD");
1608 		return QDF_STATUS_E_INVAL;
1609 	}
1610 
1611 	direct_buf_rx_debug("Sending DBR Ring CFG to target");
1612 	dbr_cfg_req.pdev_id = mod_param->pdev_id;
1613 	/* Module ID numbering starts from 1 in FW. need to fix it */
1614 	dbr_cfg_req.mod_id = mod_param->mod_id;
1615 	dbr_cfg_req.base_paddr_lo =
1616 		qdf_get_lower_32_bits(dbr_ring_cfg->base_paddr_aligned);
1617 	dbr_cfg_req.base_paddr_hi =
1618 		qdf_get_upper_32_bits(dbr_ring_cfg->base_paddr_aligned);
1619 	dbr_cfg_req.head_idx_paddr_lo =
1620 		qdf_get_lower_32_bits(dbr_ring_cfg->head_idx_addr);
1621 	dbr_cfg_req.head_idx_paddr_hi =
1622 		qdf_get_upper_32_bits(dbr_ring_cfg->head_idx_addr);
1623 	dbr_cfg_req.tail_idx_paddr_lo =
1624 		qdf_get_lower_32_bits(dbr_ring_cfg->tail_idx_addr);
1625 	dbr_cfg_req.tail_idx_paddr_hi =
1626 		qdf_get_upper_32_bits(dbr_ring_cfg->tail_idx_addr);
1627 	dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min;
1628 	dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size;
1629 	dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event;
1630 	dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms;
1631 	direct_buf_rx_debug("pdev id %d mod id %d base addr lo %x\n"
1632 			    "base addr hi %x head idx addr lo %x\n"
1633 			    "head idx addr hi %x tail idx addr lo %x\n"
1634 			    "tail idx addr hi %x num ptr %d\n"
1635 			    "num resp %d event timeout %d\n",
1636 			    dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id,
1637 			    dbr_cfg_req.base_paddr_lo,
1638 			    dbr_cfg_req.base_paddr_hi,
1639 			    dbr_cfg_req.head_idx_paddr_lo,
1640 			    dbr_cfg_req.head_idx_paddr_hi,
1641 			    dbr_cfg_req.tail_idx_paddr_lo,
1642 			    dbr_cfg_req.tail_idx_paddr_hi,
1643 			    dbr_cfg_req.num_elems,
1644 			    dbr_cfg_req.num_resp_per_event,
1645 			    dbr_cfg_req.event_timeout_ms);
1646 	status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req);
1647 
1648 	return status;
1649 }
1650 
1651 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev,
1652 				struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
1653 				enum DBR_MODULE mod_id, uint8_t srng_id)
1654 {
1655 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1656 	struct direct_buf_rx_module_param *mod_param;
1657 
1658 	direct_buf_rx_debug("Init DBR ring for module %d, srng %d",
1659 			    mod_id, srng_id);
1660 
1661 	if (!dbr_pdev_obj) {
1662 		direct_buf_rx_err("dir buf rx object is null");
1663 		return QDF_STATUS_E_INVAL;
1664 	}
1665 
1666 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
1667 
1668 	if (!mod_param) {
1669 		direct_buf_rx_err("dir buf rx module param is null");
1670 		return QDF_STATUS_E_FAILURE;
1671 	}
1672 
1673 	direct_buf_rx_debug("mod_param %pK", mod_param);
1674 
1675 	mod_param->mod_id = mod_id;
1676 	mod_param->pdev_id = dbr_get_pdev_id(
1677 				srng_id, wlan_objmgr_pdev_get_pdev_id(pdev));
1678 	mod_param->srng_id = srng_id;
1679 
1680 	/* Initialize DMA ring now */
1681 	status = target_if_dbr_init_srng(pdev, mod_param);
1682 	if (QDF_IS_STATUS_ERROR(status)) {
1683 		direct_buf_rx_err("DBR ring init failed %d", status);
1684 		return status;
1685 	}
1686 
1687 	mod_param->srng_initialized = true;
1688 
1689 	/* Send CFG request command to firmware */
1690 	status = target_if_dbr_cfg_tgt(pdev, mod_param);
1691 	if (QDF_IS_STATUS_ERROR(status)) {
1692 		direct_buf_rx_err("DBR config to target failed %d", status);
1693 		goto dbr_srng_init_failed;
1694 	}
1695 
1696 	return QDF_STATUS_SUCCESS;
1697 
1698 dbr_srng_init_failed:
1699 	target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id);
1700 	return status;
1701 }
1702 
1703 QDF_STATUS target_if_direct_buf_rx_module_register(
1704 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id,
1705 			struct dbr_module_config *dbr_config,
1706 			bool (*dbr_rsp_handler)
1707 			     (struct wlan_objmgr_pdev *pdev,
1708 			      struct direct_buf_rx_data *dbr_data))
1709 {
1710 	QDF_STATUS status;
1711 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1712 	struct dbr_module_config *config = NULL;
1713 	struct direct_buf_rx_module_param *mod_param;
1714 	uint8_t srng_id;
1715 
1716 	if (!pdev) {
1717 		direct_buf_rx_err("pdev context passed is null");
1718 		return QDF_STATUS_E_INVAL;
1719 	}
1720 
1721 	if (!dbr_rsp_handler) {
1722 		direct_buf_rx_err("Response handler is null");
1723 		return QDF_STATUS_E_INVAL;
1724 	}
1725 
1726 	if (mod_id >= DBR_MODULE_MAX) {
1727 		direct_buf_rx_err("Invalid module id");
1728 		return QDF_STATUS_E_INVAL;
1729 	}
1730 
1731 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1732 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1733 
1734 	if (!dbr_pdev_obj) {
1735 		direct_buf_rx_err("dir buf rx object is null");
1736 		return QDF_STATUS_E_FAILURE;
1737 	}
1738 
1739 	direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj);
1740 
1741 	if (!dbr_pdev_obj->dbr_mod_param) {
1742 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
1743 		return QDF_STATUS_E_FAILURE;
1744 	}
1745 
1746 	if (mod_id >= dbr_pdev_obj->num_modules) {
1747 		direct_buf_rx_err("Module %d not supported in target", mod_id);
1748 		return QDF_STATUS_E_FAILURE;
1749 	}
1750 
1751 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1752 		mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1753 		config = &mod_param->dbr_config;
1754 		mod_param->dbr_rsp_handler = dbr_rsp_handler;
1755 		*config = *dbr_config;
1756 
1757 		status = target_if_init_dbr_ring(pdev, dbr_pdev_obj,
1758 						 (enum DBR_MODULE)mod_id,
1759 						 srng_id);
1760 		if (QDF_IS_STATUS_ERROR(status))
1761 			direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d",
1762 					  srng_id, status);
1763 	}
1764 
1765 	return status;
1766 }
1767 
1768 QDF_STATUS target_if_direct_buf_rx_module_unregister(
1769 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id)
1770 {
1771 	QDF_STATUS status;
1772 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1773 	uint8_t srng_id;
1774 
1775 	if (!pdev) {
1776 		direct_buf_rx_err("pdev context passed is null");
1777 		return QDF_STATUS_E_INVAL;
1778 	}
1779 
1780 	if (mod_id >= DBR_MODULE_MAX) {
1781 		direct_buf_rx_err("Invalid module id");
1782 		return QDF_STATUS_E_INVAL;
1783 	}
1784 
1785 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
1786 			(pdev,
1787 			 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1788 
1789 	if (!dbr_pdev_obj) {
1790 		direct_buf_rx_err("dir buf rx object is null");
1791 		return QDF_STATUS_E_FAILURE;
1792 	}
1793 
1794 	direct_buf_rx_debug("Dbr pdev obj %pK", dbr_pdev_obj);
1795 
1796 	if (!dbr_pdev_obj->dbr_mod_param) {
1797 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
1798 		return QDF_STATUS_E_FAILURE;
1799 	}
1800 
1801 	if (mod_id >= dbr_pdev_obj->num_modules) {
1802 		direct_buf_rx_err("Module %d not supported in target", mod_id);
1803 		return QDF_STATUS_E_FAILURE;
1804 	}
1805 
1806 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1807 		status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj,
1808 						   mod_id, srng_id);
1809 		direct_buf_rx_info("status %d", status);
1810 	}
1811 
1812 	return status;
1813 }
1814 
1815 static void *target_if_dbr_vaddr_lookup(
1816 			struct direct_buf_rx_module_param *mod_param,
1817 			qdf_dma_addr_t paddr, uint32_t cookie)
1818 {
1819 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1820 
1821 	dbr_buf_pool = mod_param->dbr_buf_pool;
1822 
1823 	if (cookie >= mod_param->dbr_ring_cfg->num_ptr) {
1824 		direct_buf_rx_err("invalid cookie %d", cookie);
1825 		return NULL;
1826 	}
1827 
1828 	if (dbr_buf_pool[cookie].paddr == paddr) {
1829 		return dbr_buf_pool[cookie].vaddr +
1830 				dbr_buf_pool[cookie].offset;
1831 	}
1832 	direct_buf_rx_debug("Invalid paddr, cookie %d, pool paddr %pK, paddr %pK",
1833 			    cookie, (void *)dbr_buf_pool[cookie].paddr,
1834 			    (void *)paddr);
1835 
1836 	return NULL;
1837 }
1838 
1839 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev,
1840 				       uint8_t mod_id, qdf_dma_addr_t paddr,
1841 				       uint32_t *cookie, uint8_t srng_id)
1842 {
1843 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1844 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1845 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1846 	struct direct_buf_rx_module_param *mod_param;
1847 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
1848 	uint32_t idx;
1849 
1850 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
1851 	if (!dbr_pdev_obj) {
1852 		direct_buf_rx_err("dir buf rx object is null");
1853 		return QDF_STATUS_E_FAILURE;
1854 	}
1855 
1856 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1857 	if (!mod_param) {
1858 		direct_buf_rx_err("dir buf rx module param is null");
1859 		return QDF_STATUS_E_FAILURE;
1860 	}
1861 
1862 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1863 	dbr_buf_pool = mod_param->dbr_buf_pool;
1864 
1865 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
1866 		if (dbr_buf_pool[idx].paddr &&
1867 		    dbr_buf_pool[idx].paddr == paddr) {
1868 			*cookie = idx;
1869 			return QDF_STATUS_SUCCESS;
1870 		}
1871 	}
1872 
1873 	return QDF_STATUS_E_FAILURE;
1874 }
1875 
1876 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev,
1877 				     uint8_t mod_id, qdf_dma_addr_t paddr,
1878 				     uint32_t cookie, uint8_t srng_id)
1879 {
1880 	struct direct_buf_rx_module_param *mod_param;
1881 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1882 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
1883 	void *vaddr;
1884 	QDF_STATUS status;
1885 
1886 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
1887 	if (!dbr_pdev_obj) {
1888 		direct_buf_rx_err("dir buf rx object is null");
1889 		return QDF_STATUS_E_FAILURE;
1890 	}
1891 
1892 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1893 	if (!mod_param) {
1894 		direct_buf_rx_err("dir buf rx module param is null");
1895 		return QDF_STATUS_E_FAILURE;
1896 	}
1897 
1898 	vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie);
1899 	if (!vaddr)
1900 		return QDF_STATUS_E_FAILURE;
1901 
1902 	status = target_if_dbr_replenish_ring(pdev, mod_param,
1903 					      vaddr, cookie);
1904 	if (QDF_IS_STATUS_ERROR(status)) {
1905 		direct_buf_rx_err("Ring replenish failed");
1906 		return QDF_STATUS_E_FAILURE;
1907 	}
1908 
1909 	return QDF_STATUS_SUCCESS;
1910 }
1911 
1912 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev,
1913 			struct direct_buf_rx_module_param *mod_param,
1914 			struct direct_buf_rx_rsp *dbr_rsp,
1915 			struct direct_buf_rx_data *dbr_data,
1916 			uint8_t idx, uint32_t *cookie)
1917 {
1918 	qdf_dma_addr_t paddr = 0;
1919 	uint32_t addr_hi;
1920 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1921 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1922 	struct wlan_objmgr_psoc *psoc;
1923 
1924 	psoc = wlan_pdev_get_psoc(pdev);
1925 	if (!psoc) {
1926 		direct_buf_rx_err("psoc is null");
1927 		return QDF_STATUS_E_FAILURE;
1928 	}
1929 
1930 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1931 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1932 
1933 	if (!dbr_psoc_obj) {
1934 		direct_buf_rx_err("dir buf rx psoc object is null");
1935 		return QDF_STATUS_E_FAILURE;
1936 	}
1937 
1938 	dbr_ring_cap = mod_param->dbr_ring_cap;
1939 	addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET(
1940 				dbr_rsp->dbr_entries[idx].paddr_hi);
1941 	paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 |
1942 				  dbr_rsp->dbr_entries[idx].paddr_lo);
1943 	*cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET(
1944 				dbr_rsp->dbr_entries[idx].paddr_hi);
1945 	dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie);
1946 
1947 	if (!dbr_data->vaddr) {
1948 		direct_buf_rx_debug("dbr vaddr lookup failed, cookie %d, hi %x, lo %x",
1949 				    *cookie, dbr_rsp->dbr_entries[idx].paddr_hi,
1950 				    dbr_rsp->dbr_entries[idx].paddr_lo);
1951 		return QDF_STATUS_E_FAILURE;
1952 	}
1953 
1954 	dbr_data->cookie = *cookie;
1955 	dbr_data->paddr = paddr;
1956 	direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK",
1957 			    dbr_data->cookie, dbr_data->vaddr);
1958 	dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len;
1959 	qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr,
1960 				    QDF_DMA_FROM_DEVICE,
1961 				    dbr_ring_cap->min_buf_size);
1962 
1963 	return QDF_STATUS_SUCCESS;
1964 }
1965 
1966 #ifdef DBR_MULTI_SRNG_ENABLE
1967 /**
1968  * dbr_get_pdev_and_srng_id() - get pdev object and srng id
1969  *
1970  * @psoc: pointer to psoc object
1971  * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid
1972  * @srng_id:  pointer to return srng id
1973  *
1974  * Return : pointer to pdev
1975  */
1976 static struct wlan_objmgr_pdev *
1977 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1978 			 uint8_t *srng_id)
1979 {
1980 	struct wlan_objmgr_pdev *pdev;
1981 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
1982 
1983 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
1984 	if (!pdev) {
1985 		pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC,
1986 						  dbr_mod_id);
1987 		if (pdev) {
1988 			direct_buf_rx_debug("update srng id from %d to %d",
1989 					    *srng_id, pdev_id);
1990 			*srng_id = pdev_id;
1991 		}
1992 	}
1993 
1994 	return pdev;
1995 }
1996 #else
1997 static struct wlan_objmgr_pdev *
1998 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
1999 			 uint8_t *srng_id)
2000 {
2001 	struct wlan_objmgr_pdev *pdev;
2002 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
2003 
2004 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
2005 
2006 	return pdev;
2007 }
2008 #endif
2009 
2010 #ifdef DIRECT_BUF_RX_DEBUG
2011 /**
2012  * target_if_dbr_add_ring_debug_entry() - Add a DBR ring debug entry
2013  * @pdev: pointer to pdev object
2014  * @mod_id: Module ID
2015  * @event: ring debug event
2016  *
2017  * Log the given event, head and tail pointers of DBR ring of the given module
2018  * into its ring debug data structure.
2019  * Also, log the timestamp at the time of logging.
2020  */
2021 static void target_if_dbr_add_ring_debug_entry(
2022 	struct wlan_objmgr_pdev *pdev,
2023 	uint32_t mod_id,
2024 	enum DBR_RING_DEBUG_EVENT event,
2025 	uint8_t srng_id)
2026 {
2027 	struct wlan_objmgr_psoc *psoc;
2028 	void *hal_soc, *srng;
2029 	uint32_t hp = 0, tp = 0;
2030 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2031 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2032 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2033 	struct direct_buf_rx_module_debug *mod_debug;
2034 	struct direct_buf_rx_module_param *mod_param;
2035 	struct direct_buf_rx_ring_debug *ring_debug;
2036 	struct direct_buf_rx_ring_debug_entry *entry;
2037 
2038 	mod_debug = target_if_get_dbr_mod_debug_from_pdev(pdev, mod_id);
2039 
2040 	if (!mod_debug)
2041 		return;
2042 
2043 	psoc = wlan_pdev_get_psoc(pdev);
2044 
2045 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
2046 				pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2047 
2048 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
2049 				psoc, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2050 
2051 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
2052 	if (!mod_param) {
2053 		direct_buf_rx_err("dir buf rx module param is null");
2054 		return;
2055 	}
2056 
2057 	hal_soc = dbr_psoc_obj->hal_soc;
2058 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2059 	srng = dbr_ring_cfg->srng;
2060 	ring_debug = &mod_debug->dbr_ring_debug[srng_id];
2061 
2062 	if (ring_debug->entries) {
2063 		if (hal_le_srng_access_start_in_cpu_order(hal_soc, srng)) {
2064 			direct_buf_rx_err("module %d - HAL srng access failed",
2065 					  mod_id);
2066 			return;
2067 		}
2068 		hal_get_sw_hptp(hal_soc, srng, &tp, &hp);
2069 		hal_le_srng_access_end_in_cpu_order(hal_soc, srng);
2070 		tp = qdf_le32_to_cpu(tp);
2071 		entry = &ring_debug->entries[ring_debug->ring_debug_idx];
2072 
2073 		entry->head_idx = hp;
2074 		entry->tail_idx = tp;
2075 		entry->timestamp = qdf_get_log_timestamp();
2076 		entry->event = event;
2077 
2078 		ring_debug->ring_debug_idx++;
2079 		if (ring_debug->ring_debug_idx ==
2080 			ring_debug->num_ring_debug_entries)
2081 			ring_debug->ring_debug_idx = 0;
2082 	}
2083 }
2084 
2085 #else
2086 static void target_if_dbr_add_ring_debug_entry(
2087 	struct wlan_objmgr_pdev *pdev,
2088 	uint32_t mod_id,
2089 	enum DBR_RING_DEBUG_EVENT event,
2090 	uint8_t srng_id)
2091 {
2092 }
2093 #endif /* DIRECT_BUF_RX_DEBUG */
2094 
2095 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn,
2096 						uint8_t *data_buf,
2097 						uint32_t data_len)
2098 {
2099 	int ret = 0;
2100 	uint8_t i = 0;
2101 	QDF_STATUS status;
2102 	uint32_t cookie = 0;
2103 	struct direct_buf_rx_rsp dbr_rsp = {0};
2104 	struct direct_buf_rx_data dbr_data = {0};
2105 	struct wlan_objmgr_psoc *psoc;
2106 	struct wlan_objmgr_pdev *pdev;
2107 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2108 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2109 	struct direct_buf_rx_module_param *mod_param;
2110 	struct wmi_unified *wmi_handle;
2111 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
2112 	uint8_t srng_id = 0;
2113 
2114 	direct_buf_rx_enter();
2115 
2116 	psoc = target_if_get_psoc_from_scn_hdl(scn);
2117 	if (!psoc) {
2118 		direct_buf_rx_err("psoc is null");
2119 		return QDF_STATUS_E_FAILURE;
2120 	}
2121 
2122 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
2123 	if (!wmi_handle) {
2124 		direct_buf_rx_err("WMI handle is null");
2125 		return QDF_STATUS_E_FAILURE;
2126 	}
2127 
2128 	if (wmi_extract_dbr_buf_release_fixed(
2129 		wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) {
2130 		direct_buf_rx_err("unable to extract DBR rsp fixed param");
2131 		return QDF_STATUS_E_FAILURE;
2132 	}
2133 
2134 	direct_buf_rx_debug("Num buf release entry = %d",
2135 			    dbr_rsp.num_buf_release_entry);
2136 
2137 	pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id,
2138 					&srng_id);
2139 	if (!pdev || (srng_id >= DBR_SRNG_NUM)) {
2140 		direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d",
2141 				  pdev, srng_id);
2142 		return QDF_STATUS_E_INVAL;
2143 	}
2144 
2145 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2146 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2147 
2148 	if (!dbr_pdev_obj) {
2149 		direct_buf_rx_err("dir buf rx object is null");
2150 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2151 		return QDF_STATUS_E_FAILURE;
2152 	}
2153 
2154 	if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) {
2155 		direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id);
2156 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2157 		return QDF_STATUS_E_FAILURE;
2158 	}
2159 	mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]);
2160 
2161 	if (!mod_param) {
2162 		direct_buf_rx_err("dir buf rx module param is null");
2163 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2164 		return QDF_STATUS_E_FAILURE;
2165 	}
2166 
2167 	dbr_buf_pool = mod_param->dbr_buf_pool;
2168 	dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry *
2169 					sizeof(struct direct_buf_rx_entry));
2170 	if (!dbr_rsp.dbr_entries) {
2171 		direct_buf_rx_err("invalid dbr_entries");
2172 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2173 		return QDF_STATUS_E_FAILURE;
2174 	}
2175 
2176 	if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) {
2177 		direct_buf_rx_err("More than expected number of metadata");
2178 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2179 		return QDF_STATUS_E_FAILURE;
2180 	}
2181 
2182 	for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) {
2183 		if (wmi_extract_dbr_buf_release_entry(
2184 			wmi_handle, data_buf, i,
2185 			&dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) {
2186 			direct_buf_rx_err("Unable to extract DBR buf entry %d",
2187 					  i+1);
2188 			qdf_mem_free(dbr_rsp.dbr_entries);
2189 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2190 			return QDF_STATUS_E_FAILURE;
2191 		}
2192 		status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp,
2193 						&dbr_data, i, &cookie);
2194 
2195 		if (QDF_IS_STATUS_ERROR(status)) {
2196 			direct_buf_rx_err("DBR data get failed");
2197 			qdf_mem_free(dbr_rsp.dbr_entries);
2198 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2199 			return QDF_STATUS_E_FAILURE;
2200 		}
2201 
2202 		dbr_data.meta_data_valid = false;
2203 		if (i < dbr_rsp.num_meta_data_entry) {
2204 			if (wmi_extract_dbr_buf_metadata(
2205 				wmi_handle, data_buf, i,
2206 				&dbr_data.meta_data) == QDF_STATUS_SUCCESS)
2207 				dbr_data.meta_data_valid = true;
2208 		}
2209 
2210 		target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id,
2211 						   DBR_RING_DEBUG_EVENT_RX,
2212 						   srng_id);
2213 		if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) {
2214 			status = target_if_dbr_replenish_ring(pdev, mod_param,
2215 							      dbr_data.vaddr,
2216 							      cookie);
2217 
2218 			target_if_dbr_add_ring_debug_entry(
2219 				pdev, dbr_rsp.mod_id,
2220 				DBR_RING_DEBUG_EVENT_REPLENISH_RING,
2221 				srng_id);
2222 
2223 			if (QDF_IS_STATUS_ERROR(status)) {
2224 				direct_buf_rx_err("Ring replenish failed");
2225 				qdf_mem_free(dbr_rsp.dbr_entries);
2226 				wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2227 				return QDF_STATUS_E_FAILURE;
2228 			}
2229 		}
2230 	}
2231 
2232 	qdf_mem_free(dbr_rsp.dbr_entries);
2233 	wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
2234 
2235 	return ret;
2236 }
2237 
2238 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev,
2239 			struct direct_buf_rx_psoc_obj *dbr_psoc_obj,
2240 			struct direct_buf_rx_module_param *mod_param)
2241 {
2242 	uint32_t idx;
2243 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2244 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
2245 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2246 
2247 	direct_buf_rx_enter();
2248 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2249 	dbr_ring_cap = mod_param->dbr_ring_cap;
2250 	dbr_buf_pool = mod_param->dbr_buf_pool;
2251 
2252 	direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK",
2253 			   dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool);
2254 
2255 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
2256 		qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev,
2257 			(qdf_dma_addr_t)dbr_buf_pool[idx].paddr,
2258 			QDF_DMA_FROM_DEVICE,
2259 			dbr_ring_cap->min_buf_size);
2260 		target_if_dbr_mem_put(pdev, dbr_ring_cap->min_buf_size,
2261 				      dbr_buf_pool[idx].vaddr,
2262 				      dbr_buf_pool[idx].offset,
2263 				      dbr_ring_cap->min_buf_align,
2264 				      mod_param->mod_id);
2265 	}
2266 
2267 	return QDF_STATUS_SUCCESS;
2268 }
2269 
2270 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev,
2271 			struct direct_buf_rx_module_param *mod_param)
2272 {
2273 	struct wlan_objmgr_psoc *psoc;
2274 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2275 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2276 
2277 	direct_buf_rx_enter();
2278 	psoc = wlan_pdev_get_psoc(pdev);
2279 	if (!psoc) {
2280 		direct_buf_rx_err("psoc is null");
2281 		return QDF_STATUS_E_FAILURE;
2282 	}
2283 
2284 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2285 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2286 
2287 	if (!dbr_psoc_obj) {
2288 		direct_buf_rx_err("dir buf rx psoc object is null");
2289 		return QDF_STATUS_E_FAILURE;
2290 	}
2291 	direct_buf_rx_debug("dbr_psoc_obj %pK", dbr_psoc_obj);
2292 
2293 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
2294 	if (dbr_ring_cfg) {
2295 		target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param);
2296 		hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng);
2297 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
2298 					dbr_psoc_obj->osdev->dev,
2299 					dbr_ring_cfg->ring_alloc_size,
2300 					dbr_ring_cfg->base_vaddr_unaligned,
2301 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
2302 	}
2303 
2304 	return QDF_STATUS_SUCCESS;
2305 }
2306 
2307 static QDF_STATUS target_if_dbr_deinit_srng(
2308 			struct wlan_objmgr_pdev *pdev,
2309 			struct direct_buf_rx_module_param *mod_param)
2310 {
2311 	struct direct_buf_rx_buf_info *dbr_buf_pool;
2312 
2313 	direct_buf_rx_enter();
2314 	dbr_buf_pool = mod_param->dbr_buf_pool;
2315 	direct_buf_rx_debug("dbr buf pool %pK", dbr_buf_pool);
2316 	target_if_dbr_deinit_ring(pdev, mod_param);
2317 	if (mod_param->dbr_buf_pool)
2318 		qdf_mem_free(dbr_buf_pool);
2319 	mod_param->dbr_buf_pool = NULL;
2320 
2321 	return QDF_STATUS_SUCCESS;
2322 }
2323 
2324 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev,
2325 			struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
2326 			enum DBR_MODULE mod_id, uint8_t srng_id)
2327 {
2328 	struct direct_buf_rx_module_param *mod_param;
2329 
2330 	direct_buf_rx_enter();
2331 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
2332 
2333 	if (!mod_param) {
2334 		direct_buf_rx_err("dir buf rx module param is null");
2335 		return QDF_STATUS_E_FAILURE;
2336 	}
2337 	direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK",
2338 			    mod_param, mod_param->dbr_ring_cap);
2339 
2340 	if (!mod_param->srng_initialized) {
2341 		direct_buf_rx_err("module(%d) srng(%d) was not initialized",
2342 				  mod_id, srng_id);
2343 		return QDF_STATUS_SUCCESS;
2344 	}
2345 
2346 	target_if_dbr_deinit_srng(pdev, mod_param);
2347 	if (mod_param->dbr_ring_cap)
2348 		qdf_mem_free(mod_param->dbr_ring_cap);
2349 	mod_param->dbr_ring_cap = NULL;
2350 	if (mod_param->dbr_ring_cfg)
2351 		qdf_mem_free(mod_param->dbr_ring_cfg);
2352 	mod_param->dbr_ring_cfg = NULL;
2353 
2354 	mod_param->srng_initialized = false;
2355 
2356 	return QDF_STATUS_SUCCESS;
2357 }
2358 
2359 QDF_STATUS target_if_direct_buf_rx_register_events(
2360 				struct wlan_objmgr_psoc *psoc)
2361 {
2362 	QDF_STATUS ret;
2363 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2364 
2365 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
2366 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
2367 		return QDF_STATUS_E_INVAL;
2368 	}
2369 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(
2370 			psoc,
2371 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2372 
2373 	if (!dbr_psoc_obj) {
2374 		direct_buf_rx_err("dir buf rx psoc object is null");
2375 		return QDF_STATUS_E_FAILURE;
2376 	}
2377 
2378 	ret = wmi_unified_register_event_handler(
2379 			get_wmi_unified_hdl_from_psoc(psoc),
2380 			wmi_dma_buf_release_event_id,
2381 			target_if_direct_buf_rx_rsp_event_handler,
2382 			dbr_psoc_obj->handler_ctx);
2383 
2384 	direct_buf_rx_info("DBR Handler Context %d", dbr_psoc_obj->handler_ctx);
2385 	if (QDF_IS_STATUS_ERROR(ret))
2386 		direct_buf_rx_debug("event handler not supported, ret=%d", ret);
2387 
2388 	return QDF_STATUS_SUCCESS;
2389 }
2390 
2391 QDF_STATUS target_if_direct_buf_rx_unregister_events(
2392 				struct wlan_objmgr_psoc *psoc)
2393 {
2394 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
2395 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
2396 		return QDF_STATUS_E_INVAL;
2397 	}
2398 
2399 	wmi_unified_unregister_event_handler(
2400 			get_wmi_unified_hdl_from_psoc(psoc),
2401 			wmi_dma_buf_release_event_id);
2402 
2403 	return QDF_STATUS_SUCCESS;
2404 }
2405 
2406 QDF_STATUS target_if_direct_buf_rx_print_ring_stat(
2407 				struct wlan_objmgr_pdev *pdev)
2408 {
2409 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
2410 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2411 	struct wlan_objmgr_psoc *psoc;
2412 	void *srng, *hal_soc;
2413 	uint32_t hp = 0, tp = 0;
2414 	struct direct_buf_rx_module_param *mod_param;
2415 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
2416 	uint8_t num_modules, mod_idx;
2417 	uint8_t srng_id;
2418 
2419 	if (!pdev) {
2420 		direct_buf_rx_err("pdev is null");
2421 		return QDF_STATUS_E_INVAL;
2422 	}
2423 
2424 	psoc = wlan_pdev_get_psoc(pdev);
2425 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2426 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2427 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2428 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2429 	hal_soc = dbr_psoc_obj->hal_soc;
2430 	num_modules = dbr_pdev_obj->num_modules;
2431 	direct_buf_rx_debug("--------------------------------------------------");
2432 	direct_buf_rx_debug("| Module ID |    Module    | Head Idx | Tail Idx |");
2433 	direct_buf_rx_debug("--------------------------------------------------");
2434 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
2435 		for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
2436 			mod_param =
2437 				&dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id];
2438 			dbr_ring_cfg = mod_param->dbr_ring_cfg;
2439 			if (!dbr_ring_cfg) {
2440 				direct_buf_rx_info("dbr_ring_cfg is NULL");
2441 				direct_buf_rx_info("mod id %d mod %s", mod_idx,
2442 						   g_dbr_module_name[mod_idx].
2443 						   module_name_str);
2444 				continue;
2445 			}
2446 			srng = dbr_ring_cfg->srng;
2447 			hal_get_sw_hptp(hal_soc, srng, &tp, &hp);
2448 			tp = qdf_le32_to_cpu(tp);
2449 			direct_buf_rx_debug("|%11d|%14s|%10x|%10x|",
2450 					    mod_idx, g_dbr_module_name[mod_idx].
2451 					    module_name_str,
2452 					    hp, tp);
2453 		}
2454 	}
2455 	direct_buf_rx_debug("--------------------------------------------------");
2456 
2457 	return QDF_STATUS_SUCCESS;
2458 }
2459 
2460 QDF_STATUS
2461 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev,
2462 					struct module_ring_params *param,
2463 					uint8_t mod_id, uint8_t srng_id)
2464 {
2465 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
2466 	struct direct_buf_rx_module_param *dbr_mod_param;
2467 
2468 	if (!pdev) {
2469 		direct_buf_rx_err("pdev context passed is null");
2470 		return QDF_STATUS_E_INVAL;
2471 	}
2472 
2473 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
2474 			(pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
2475 
2476 	if (!dbr_pdev_obj) {
2477 		direct_buf_rx_err("dir buf rx object is null");
2478 		return QDF_STATUS_E_FAILURE;
2479 	}
2480 
2481 	if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) {
2482 		direct_buf_rx_err("invalid params, mod id %d, srng id %d",
2483 				  mod_id, srng_id);
2484 		return QDF_STATUS_E_INVAL;
2485 	}
2486 
2487 	dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
2488 	param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr;
2489 	param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size;
2490 
2491 	return QDF_STATUS_SUCCESS;
2492 }
2493