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