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