xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c (revision a175314c51a4ce5cec2835cc8a8c7dc0c1810915)
1 /*
2  * Copyright (c) 2017-2018 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 "wmi_unified_api.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 };
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 	struct wlan_psoc_host_service_ext_param *ext_svc_param;
47 
48 	psoc = wlan_pdev_get_psoc(pdev);
49 
50 	if (psoc == NULL) {
51 		direct_buf_rx_err("psoc is null");
52 		return 0;
53 	}
54 
55 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
56 	if (tgt_psoc_info == NULL) {
57 		direct_buf_rx_err("target_psoc_info is null");
58 		return 0;
59 	}
60 	ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info);
61 	num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps;
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 
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 	struct wlan_psoc_host_service_ext_param *ext_svc_param;
85 
86 	psoc = wlan_pdev_get_psoc(pdev);
87 
88 	if (psoc == NULL) {
89 		direct_buf_rx_err("psoc is null");
90 		return QDF_STATUS_E_INVAL;
91 	}
92 
93 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
94 	if (tgt_psoc_info == NULL) {
95 		direct_buf_rx_err("target_psoc_info is null");
96 		return QDF_STATUS_E_INVAL;
97 	}
98 
99 	ext_svc_param = target_psoc_get_service_ext_param(tgt_psoc_info);
100 	num_dbr_ring_caps = ext_svc_param->num_dbr_ring_caps;
101 	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
102 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
103 
104 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
105 		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) {
106 			if (dbr_ring_cap[cap_idx].mod_id == mod_id) {
107 				mod_param->dbr_ring_cap->ring_elems_min =
108 					dbr_ring_cap[cap_idx].ring_elems_min;
109 				mod_param->dbr_ring_cap->min_buf_size =
110 					dbr_ring_cap[cap_idx].min_buf_size;
111 				mod_param->dbr_ring_cap->min_buf_align =
112 					dbr_ring_cap[cap_idx].min_buf_align;
113 				cap_found = true;
114 			}
115 		}
116 	}
117 
118 	if (!cap_found) {
119 		direct_buf_rx_err("No cap found for module %d in pdev %d",
120 				  mod_id, pdev_id);
121 		return QDF_STATUS_E_FAILURE;
122 	}
123 
124 	return QDF_STATUS_SUCCESS;
125 }
126 
127 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler(
128 	struct wlan_objmgr_pdev *pdev, void *data)
129 {
130 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
131 	struct wlan_objmgr_psoc *psoc;
132 	uint8_t num_modules;
133 	QDF_STATUS status;
134 
135 	direct_buf_rx_enter();
136 
137 	if (pdev == NULL) {
138 		direct_buf_rx_err("pdev context passed is null");
139 		return QDF_STATUS_E_INVAL;
140 	}
141 
142 	psoc = wlan_pdev_get_psoc(pdev);
143 
144 	if (psoc == NULL) {
145 		direct_buf_rx_err("psoc is null");
146 		return QDF_STATUS_E_INVAL;
147 	}
148 
149 	dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj));
150 
151 	if (dbr_pdev_obj == NULL) {
152 		direct_buf_rx_err("Failed to allocate dir buf rx pdev obj");
153 		return QDF_STATUS_E_NOMEM;
154 	}
155 
156 	direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj);
157 
158 	status = wlan_objmgr_pdev_component_obj_attach(pdev,
159 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
160 					dbr_pdev_obj, QDF_STATUS_SUCCESS);
161 
162 	if (status != QDF_STATUS_SUCCESS) {
163 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
164 				  status);
165 		qdf_mem_free(dbr_pdev_obj);
166 		return status;
167 	}
168 
169 	num_modules = get_num_dbr_modules_per_pdev(pdev);
170 	direct_buf_rx_info("Number of modules = %d pdev %d", num_modules,
171 			   wlan_objmgr_pdev_get_pdev_id(pdev));
172 	dbr_pdev_obj->num_modules = num_modules;
173 
174 	if (!dbr_pdev_obj->num_modules) {
175 		direct_buf_rx_info("Number of modules = %d", num_modules);
176 		return QDF_STATUS_SUCCESS;
177 	}
178 
179 	dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules *
180 				sizeof(struct direct_buf_rx_module_param));
181 
182 	if (dbr_pdev_obj->dbr_mod_param == NULL) {
183 		direct_buf_rx_err("Failed to allocate dir buf rx mod param");
184 		wlan_objmgr_pdev_component_obj_detach(pdev,
185 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
186 					dbr_pdev_obj);
187 		qdf_mem_free(dbr_pdev_obj);
188 		return QDF_STATUS_E_NOMEM;
189 	}
190 
191 
192 	return QDF_STATUS_SUCCESS;
193 }
194 
195 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler(
196 	struct wlan_objmgr_pdev *pdev, void *data)
197 {
198 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
199 	QDF_STATUS status;
200 	uint8_t num_modules, mod_idx;
201 
202 	if (pdev == NULL) {
203 		direct_buf_rx_err("pdev context passed is null");
204 		return QDF_STATUS_E_INVAL;
205 	}
206 
207 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
208 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
209 
210 	if (dbr_pdev_obj == NULL) {
211 		direct_buf_rx_err("dir buf rx object is null");
212 		return QDF_STATUS_E_FAILURE;
213 	}
214 
215 	num_modules = dbr_pdev_obj->num_modules;
216 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++)
217 		target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_idx);
218 
219 	qdf_mem_free(dbr_pdev_obj->dbr_mod_param);
220 	dbr_pdev_obj->dbr_mod_param = NULL;
221 
222 	status = wlan_objmgr_pdev_component_obj_detach(pdev,
223 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
224 					dbr_pdev_obj);
225 
226 	if (status != QDF_STATUS_SUCCESS) {
227 		direct_buf_rx_err("failed to detach dir buf rx component %d",
228 				  status);
229 	}
230 
231 	qdf_mem_free(dbr_pdev_obj);
232 
233 	return status;
234 }
235 
236 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler(
237 	struct wlan_objmgr_psoc *psoc, void *data)
238 {
239 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
240 	QDF_STATUS status;
241 
242 	direct_buf_rx_enter();
243 
244 	if (psoc == NULL) {
245 		direct_buf_rx_err("psoc context passed is null");
246 		return QDF_STATUS_E_INVAL;
247 	}
248 
249 	dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj));
250 
251 	if (!dbr_psoc_obj) {
252 		direct_buf_rx_err("failed to alloc dir buf rx psoc obj");
253 		return QDF_STATUS_E_NOMEM;
254 	}
255 
256 	direct_buf_rx_info("Dbr psoc obj %pK", dbr_psoc_obj);
257 
258 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
259 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj,
260 			QDF_STATUS_SUCCESS);
261 
262 	if (status != QDF_STATUS_SUCCESS) {
263 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
264 				  status);
265 		goto attach_error;
266 	}
267 
268 	return status;
269 
270 attach_error:
271 	qdf_mem_free(dbr_psoc_obj);
272 
273 	return status;
274 }
275 
276 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler(
277 	struct wlan_objmgr_psoc *psoc, void *data)
278 {
279 	QDF_STATUS status;
280 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
281 
282 	direct_buf_rx_enter();
283 
284 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
285 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
286 
287 	if (!dbr_psoc_obj) {
288 		direct_buf_rx_err("dir buf rx psoc obj is null");
289 		return QDF_STATUS_E_FAILURE;
290 	}
291 
292 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
293 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
294 				dbr_psoc_obj);
295 
296 	if (status != QDF_STATUS_SUCCESS) {
297 		direct_buf_rx_err("failed to detach dir buf rx component %d",
298 				  status);
299 	}
300 
301 	qdf_mem_free(dbr_psoc_obj);
302 
303 	return status;
304 }
305 
306 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev,
307 			struct direct_buf_rx_module_param *mod_param,
308 			void *aligned_vaddr, uint32_t cookie)
309 {
310 	uint64_t *ring_entry;
311 	uint32_t dw_lo, dw_hi = 0, map_status;
312 	void *hal_soc, *srng;
313 	qdf_dma_addr_t paddr;
314 	struct wlan_objmgr_psoc *psoc;
315 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
316 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
317 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
318 	struct direct_buf_rx_buf_info *dbr_buf_pool;
319 
320 	direct_buf_rx_enter();
321 
322 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
323 	dbr_ring_cap = mod_param->dbr_ring_cap;
324 	dbr_buf_pool = mod_param->dbr_buf_pool;
325 
326 	psoc = wlan_pdev_get_psoc(pdev);
327 
328 	if (!psoc) {
329 		direct_buf_rx_err("psoc is null");
330 		return QDF_STATUS_E_FAILURE;
331 	}
332 
333 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
334 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
335 
336 	if (dbr_psoc_obj == NULL) {
337 		direct_buf_rx_err("dir buf rx psoc object is null");
338 		return QDF_STATUS_E_FAILURE;
339 	}
340 
341 	hal_soc = dbr_psoc_obj->hal_soc;
342 	srng = dbr_ring_cfg->srng;
343 	if (!aligned_vaddr) {
344 		direct_buf_rx_err("aligned vaddr is null");
345 		return QDF_STATUS_SUCCESS;
346 	}
347 
348 	map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev,
349 					       aligned_vaddr,
350 					       QDF_DMA_FROM_DEVICE,
351 					       dbr_ring_cap->min_buf_size,
352 					       &paddr);
353 	if (map_status) {
354 		direct_buf_rx_err("mem map failed status = %d", map_status);
355 		return QDF_STATUS_E_FAILURE;
356 	}
357 
358 	QDF_ASSERT(!((uint64_t)paddr & dbr_ring_cap->min_buf_align));
359 	dbr_buf_pool[cookie].paddr = paddr;
360 
361 	hal_srng_access_start(hal_soc, srng);
362 	ring_entry = hal_srng_src_get_next(hal_soc, srng);
363 	QDF_ASSERT(ring_entry != NULL);
364 	dw_lo = (uint64_t)paddr & 0xFFFFFFFF;
365 	WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32);
366 	WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie);
367 	direct_buf_rx_info("Cookie = %d", cookie);
368 	direct_buf_rx_info("dw_lo = %x dw_hi = %x", dw_lo, dw_hi);
369 	*ring_entry = (uint64_t)dw_hi << 32 | dw_lo;
370 	direct_buf_rx_info("Valid ring entry");
371 	hal_srng_access_end(hal_soc, srng);
372 
373 	return QDF_STATUS_SUCCESS;
374 }
375 
376 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev,
377 			  struct direct_buf_rx_module_param *mod_param)
378 {
379 	uint32_t idx;
380 	void *buf, *buf_aligned;
381 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
382 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
383 	struct direct_buf_rx_buf_info *dbr_buf_pool;
384 	QDF_STATUS status;
385 
386 	direct_buf_rx_enter();
387 
388 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
389 	dbr_ring_cap = mod_param->dbr_ring_cap;
390 	dbr_buf_pool = mod_param->dbr_buf_pool;
391 
392 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
393 		buf = qdf_mem_malloc(dbr_ring_cap->min_buf_size +
394 				dbr_ring_cap->min_buf_align - 1);
395 		if (!buf) {
396 			direct_buf_rx_err("dir buf rx ring buf alloc failed");
397 			return QDF_STATUS_E_NOMEM;
398 		}
399 		dbr_buf_pool[idx].vaddr = buf;
400 		buf_aligned = (void *)(uintptr_t)qdf_roundup(
401 				(uint64_t)(uintptr_t)buf, DBR_RING_BASE_ALIGN);
402 		dbr_buf_pool[idx].offset = buf_aligned - buf;
403 		dbr_buf_pool[idx].cookie = idx;
404 		status = target_if_dbr_replenish_ring(pdev, mod_param,
405 						      buf_aligned, idx);
406 		if (QDF_IS_STATUS_ERROR(status)) {
407 			direct_buf_rx_err("replenish failed with status : %d",
408 					  status);
409 			qdf_mem_free(buf);
410 			return QDF_STATUS_E_FAILURE;
411 		}
412 	}
413 
414 	return QDF_STATUS_SUCCESS;
415 }
416 
417 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev,
418 			struct direct_buf_rx_module_param *mod_param)
419 {
420 	void *srng;
421 	uint32_t num_entries, ring_alloc_size, max_entries, entry_size;
422 	qdf_dma_addr_t paddr;
423 	struct hal_srng_params ring_params = {0};
424 	struct wlan_objmgr_psoc *psoc;
425 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
426 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
427 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
428 	QDF_STATUS status;
429 
430 	direct_buf_rx_enter();
431 
432 	psoc = wlan_pdev_get_psoc(pdev);
433 
434 	if (!psoc) {
435 		direct_buf_rx_err("psoc is null");
436 		return QDF_STATUS_E_FAILURE;
437 	}
438 
439 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
440 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
441 
442 	if (dbr_psoc_obj == NULL) {
443 		direct_buf_rx_err("dir buf rx psoc object is null");
444 		return QDF_STATUS_E_FAILURE;
445 	}
446 
447 	if (dbr_psoc_obj->hal_soc == NULL ||
448 	    dbr_psoc_obj->osdev == NULL) {
449 		direct_buf_rx_err("dir buf rx target attach failed");
450 		return QDF_STATUS_E_FAILURE;
451 	}
452 
453 	max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc,
454 					   DIR_BUF_RX_DMA_SRC);
455 	entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc,
456 					    DIR_BUF_RX_DMA_SRC);
457 	direct_buf_rx_info("Max Entries = %d", max_entries);
458 	direct_buf_rx_info("Entry Size = %d", entry_size);
459 
460 	status = populate_dbr_cap_mod_param(pdev, mod_param);
461 	if (QDF_IS_STATUS_ERROR(status)) {
462 		direct_buf_rx_err("Module cap population failed");
463 		return QDF_STATUS_E_FAILURE;
464 	}
465 
466 	dbr_ring_cap = mod_param->dbr_ring_cap;
467 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
468 	num_entries = dbr_ring_cap->ring_elems_min > max_entries ?
469 			max_entries : dbr_ring_cap->ring_elems_min;
470 	direct_buf_rx_info("Num entries = %d", num_entries);
471 	dbr_ring_cfg->num_ptr = num_entries;
472 	mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof(
473 				struct direct_buf_rx_buf_info));
474 	if (!mod_param->dbr_buf_pool) {
475 		direct_buf_rx_err("dir buf rx buf pool alloc failed");
476 		return QDF_STATUS_E_NOMEM;
477 	}
478 
479 	ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1;
480 	dbr_ring_cfg->ring_alloc_size = ring_alloc_size;
481 	direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj);
482 	dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent(
483 		dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size,
484 		&paddr);
485 	direct_buf_rx_info("vaddr aligned allocated");
486 	dbr_ring_cfg->base_paddr_unaligned = paddr;
487 	if (!dbr_ring_cfg->base_vaddr_unaligned) {
488 		direct_buf_rx_err("dir buf rx vaddr alloc failed");
489 		qdf_mem_free(mod_param->dbr_buf_pool);
490 		return QDF_STATUS_E_NOMEM;
491 	}
492 
493 	/* Alignment is defined to 8 for now. Will be advertised by FW */
494 	dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup(
495 		(uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned,
496 		DBR_RING_BASE_ALIGN);
497 	ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned;
498 	dbr_ring_cfg->base_paddr_aligned = qdf_roundup(
499 		(uint64_t)dbr_ring_cfg->base_paddr_unaligned,
500 		DBR_RING_BASE_ALIGN);
501 	ring_params.ring_base_paddr =
502 		(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned;
503 	ring_params.num_entries = num_entries;
504 	srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC, 0,
505 			      wlan_objmgr_pdev_get_pdev_id(pdev), &ring_params);
506 
507 	if (!srng) {
508 		direct_buf_rx_err("srng setup failed");
509 		qdf_mem_free(mod_param->dbr_buf_pool);
510 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
511 					dbr_psoc_obj->osdev->dev,
512 					ring_alloc_size,
513 					dbr_ring_cfg->base_vaddr_unaligned,
514 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
515 		return QDF_STATUS_E_FAILURE;
516 	}
517 	dbr_ring_cfg->srng = srng;
518 	dbr_ring_cfg->tail_idx_addr =
519 		hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng);
520 	dbr_ring_cfg->head_idx_addr =
521 		hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng);
522 	dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size;
523 
524 	return target_if_dbr_fill_ring(pdev, mod_param);
525 }
526 
527 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev,
528 			struct direct_buf_rx_module_param *mod_param)
529 {
530 	QDF_STATUS status;
531 
532 	direct_buf_rx_info("Init DBR srng");
533 
534 	if (!mod_param) {
535 		direct_buf_rx_err("dir buf rx module param is null");
536 		return QDF_STATUS_E_INVAL;
537 	}
538 
539 	mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof(
540 					struct direct_buf_rx_ring_cap));
541 
542 	if (!mod_param->dbr_ring_cap) {
543 		direct_buf_rx_err("Ring cap alloc failed");
544 		return QDF_STATUS_E_NOMEM;
545 	}
546 
547 	/* Allocate memory for DBR Ring Config */
548 	mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof(
549 					struct direct_buf_rx_ring_cfg));
550 
551 	if (!mod_param->dbr_ring_cfg) {
552 		direct_buf_rx_err("Ring config alloc failed");
553 		qdf_mem_free(mod_param->dbr_ring_cap);
554 		return QDF_STATUS_E_NOMEM;
555 	}
556 
557 	status = target_if_dbr_init_ring(pdev, mod_param);
558 
559 	if (QDF_IS_STATUS_ERROR(status)) {
560 		direct_buf_rx_err("DBR ring init failed");
561 		qdf_mem_free(mod_param->dbr_ring_cfg);
562 		qdf_mem_free(mod_param->dbr_ring_cap);
563 		return QDF_STATUS_E_FAILURE;
564 	}
565 
566 	return QDF_STATUS_SUCCESS;
567 }
568 
569 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev,
570 			struct direct_buf_rx_module_param *mod_param)
571 {
572 	QDF_STATUS status;
573 	struct wlan_objmgr_psoc *psoc;
574 	void *wmi_hdl;
575 	struct direct_buf_rx_cfg_req dbr_cfg_req = {0};
576 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
577 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
578 
579 	direct_buf_rx_enter();
580 
581 	psoc = wlan_pdev_get_psoc(pdev);
582 	if (!psoc) {
583 		direct_buf_rx_err("psoc is null");
584 		return QDF_STATUS_E_FAILURE;
585 	}
586 
587 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
588 	dbr_ring_cap = mod_param->dbr_ring_cap;
589 	wmi_hdl = lmac_get_pdev_wmi_handle(pdev);
590 	if (!wmi_hdl) {
591 		direct_buf_rx_err("WMI handle null. Can't send WMI CMD");
592 		return QDF_STATUS_E_INVAL;
593 	}
594 
595 	direct_buf_rx_debug("Sending DBR Ring CFG to target");
596 	dbr_cfg_req.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
597 	/* Module ID numbering starts from 1 in FW. need to fix it */
598 	dbr_cfg_req.mod_id = mod_param->mod_id;
599 	dbr_cfg_req.base_paddr_lo = (uint64_t)dbr_ring_cfg->base_paddr_aligned
600 						& 0xFFFFFFFF;
601 	dbr_cfg_req.base_paddr_hi = (uint64_t)dbr_ring_cfg->base_paddr_aligned
602 						& 0xFFFFFFFF00000000;
603 	dbr_cfg_req.head_idx_paddr_lo = (uint64_t)dbr_ring_cfg->head_idx_addr
604 						& 0xFFFFFFFF;
605 	dbr_cfg_req.head_idx_paddr_hi = (uint64_t)dbr_ring_cfg->head_idx_addr
606 						& 0xFFFFFFFF00000000;
607 	dbr_cfg_req.tail_idx_paddr_lo = (uint64_t)dbr_ring_cfg->tail_idx_addr
608 						& 0xFFFFFFFF;
609 	dbr_cfg_req.tail_idx_paddr_hi = (uint64_t)dbr_ring_cfg->tail_idx_addr
610 						& 0xFFFFFFFF00000000;
611 	dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min;
612 	dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size;
613 	dbr_cfg_req.num_resp_per_event = DBR_NUM_RESP_PER_EVENT;
614 	dbr_cfg_req.event_timeout_ms = DBR_EVENT_TIMEOUT_IN_MS;
615 	direct_buf_rx_info("pdev id %d mod id %d base addr lo %x\n"
616 			   "base addr hi %x head idx addr lo %x\n"
617 			   "head idx addr hi %x tail idx addr lo %x\n"
618 			   "tail idx addr hi %x num ptr %d\n"
619 			   "num resp %d event timeout %d\n",
620 			   dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id,
621 			   dbr_cfg_req.base_paddr_lo, dbr_cfg_req.base_paddr_hi,
622 			   dbr_cfg_req.head_idx_paddr_lo,
623 			   dbr_cfg_req.head_idx_paddr_hi,
624 			   dbr_cfg_req.tail_idx_paddr_lo,
625 			   dbr_cfg_req.tail_idx_paddr_hi,
626 			   dbr_cfg_req.num_elems,
627 			   dbr_cfg_req.num_resp_per_event,
628 			   dbr_cfg_req.event_timeout_ms);
629 	status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req);
630 
631 	return status;
632 }
633 
634 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev,
635 				struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
636 				enum DBR_MODULE mod_id)
637 {
638 	QDF_STATUS status = QDF_STATUS_SUCCESS;
639 	struct direct_buf_rx_module_param *mod_param;
640 
641 	direct_buf_rx_info("Init DBR ring for module %d", mod_id);
642 
643 	if (!dbr_pdev_obj) {
644 		direct_buf_rx_err("dir buf rx object is null");
645 		return QDF_STATUS_E_INVAL;
646 	}
647 
648 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id]);
649 
650 	if (!mod_param) {
651 		direct_buf_rx_err("dir buf rx module param is null");
652 		return QDF_STATUS_E_FAILURE;
653 	}
654 
655 	direct_buf_rx_info("mod_param %pK", mod_param);
656 
657 	mod_param->mod_id = mod_id;
658 
659 	/* Initialize DMA ring now */
660 	status = target_if_dbr_init_srng(pdev, mod_param);
661 	if (QDF_IS_STATUS_ERROR(status)) {
662 		direct_buf_rx_err("DBR ring init failed %d", status);
663 		return status;
664 	}
665 
666 	/* Send CFG request command to firmware */
667 	status = target_if_dbr_cfg_tgt(pdev, mod_param);
668 	if (QDF_IS_STATUS_ERROR(status)) {
669 		direct_buf_rx_err("DBR config to target failed %d", status);
670 		goto dbr_srng_init_failed;
671 	}
672 
673 	return QDF_STATUS_SUCCESS;
674 
675 dbr_srng_init_failed:
676 	target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id);
677 	return status;
678 }
679 
680 QDF_STATUS target_if_direct_buf_rx_module_register(
681 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id,
682 			int (*dbr_rsp_handler)(struct wlan_objmgr_pdev *pdev,
683 				struct direct_buf_rx_data *dbr_data))
684 {
685 	QDF_STATUS status;
686 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
687 
688 	if (pdev == NULL) {
689 		direct_buf_rx_err("pdev context passed is null");
690 		return QDF_STATUS_E_INVAL;
691 	}
692 
693 	if (dbr_rsp_handler == NULL) {
694 		direct_buf_rx_err("Response handler is null");
695 		return QDF_STATUS_E_INVAL;
696 	}
697 
698 	if (mod_id >= DBR_MODULE_MAX) {
699 		direct_buf_rx_err("Invalid module id");
700 		return QDF_STATUS_E_INVAL;
701 	}
702 
703 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
704 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
705 
706 	if (dbr_pdev_obj == NULL) {
707 		direct_buf_rx_err("dir buf rx object is null");
708 		return QDF_STATUS_E_FAILURE;
709 	}
710 
711 	direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj);
712 
713 	if (!dbr_pdev_obj->dbr_mod_param) {
714 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
715 		return QDF_STATUS_E_FAILURE;
716 	}
717 
718 	if (mod_id >= dbr_pdev_obj->num_modules) {
719 		direct_buf_rx_err("Module %d not supported in target", mod_id);
720 		return QDF_STATUS_E_FAILURE;
721 	}
722 
723 	dbr_pdev_obj->dbr_mod_param[mod_id].dbr_rsp_handler =
724 			dbr_rsp_handler;
725 
726 	status = target_if_init_dbr_ring(pdev, dbr_pdev_obj,
727 					 (enum DBR_MODULE)mod_id);
728 
729 	return status;
730 }
731 
732 static void *target_if_dbr_vaddr_lookup(
733 			struct direct_buf_rx_module_param *mod_param,
734 			qdf_dma_addr_t paddr, uint32_t cookie)
735 {
736 	struct direct_buf_rx_buf_info *dbr_buf_pool;
737 
738 	dbr_buf_pool = mod_param->dbr_buf_pool;
739 
740 	if (dbr_buf_pool[cookie].paddr == paddr) {
741 		return dbr_buf_pool[cookie].vaddr +
742 				dbr_buf_pool[cookie].offset;
743 	}
744 
745 	direct_buf_rx_err("Incorrect paddr found on cookie slot");
746 	return NULL;
747 }
748 
749 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev,
750 			struct direct_buf_rx_module_param *mod_param,
751 			struct direct_buf_rx_rsp *dbr_rsp,
752 			struct direct_buf_rx_data *dbr_data,
753 			uint8_t idx, uint32_t *cookie)
754 {
755 	qdf_dma_addr_t paddr = 0;
756 	uint32_t addr_hi;
757 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
758 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
759 	struct wlan_objmgr_psoc *psoc;
760 
761 	psoc = wlan_pdev_get_psoc(pdev);
762 	if (!psoc) {
763 		direct_buf_rx_err("psoc is null");
764 		return QDF_STATUS_E_FAILURE;
765 	}
766 
767 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
768 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
769 
770 	if (dbr_psoc_obj == NULL) {
771 		direct_buf_rx_err("dir buf rx psoc object is null");
772 		return QDF_STATUS_E_FAILURE;
773 	}
774 
775 	dbr_ring_cap = mod_param->dbr_ring_cap;
776 	addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET(
777 				dbr_rsp->dbr_entries[idx].paddr_hi);
778 	paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 |
779 				  dbr_rsp->dbr_entries[idx].paddr_lo);
780 	*cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET(
781 				dbr_rsp->dbr_entries[idx].paddr_hi);
782 	direct_buf_rx_info("Cookie = %d", *cookie);
783 	dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie);
784 	direct_buf_rx_info("Vaddr look up = %x", dbr_data->vaddr);
785 	dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len;
786 	qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr,
787 				    QDF_DMA_FROM_DEVICE,
788 				    dbr_ring_cap->min_buf_size);
789 
790 	return QDF_STATUS_SUCCESS;
791 }
792 
793 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn,
794 						uint8_t *data_buf,
795 						uint32_t data_len)
796 {
797 	int ret = 0;
798 	uint8_t i = 0;
799 	QDF_STATUS status;
800 	uint32_t cookie = 0;
801 	struct direct_buf_rx_rsp dbr_rsp = {0};
802 	struct direct_buf_rx_data dbr_data = {0};
803 	struct wlan_objmgr_psoc *psoc;
804 	struct wlan_objmgr_pdev *pdev;
805 	struct direct_buf_rx_buf_info *dbr_buf_pool;
806 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
807 	struct direct_buf_rx_module_param *mod_param;
808 
809 	direct_buf_rx_enter();
810 
811 	psoc = target_if_get_psoc_from_scn_hdl(scn);
812 	if (!psoc) {
813 		direct_buf_rx_err("psoc is null");
814 		return QDF_STATUS_E_FAILURE;
815 	}
816 
817 	if (wmi_extract_dbr_buf_release_fixed(GET_WMI_HDL_FROM_PSOC(psoc),
818 			data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) {
819 		direct_buf_rx_err("unable to extract DBR rsp fixed param");
820 		return QDF_STATUS_E_FAILURE;
821 	}
822 
823 	direct_buf_rx_info("Num buf release entry = %d",
824 			   dbr_rsp.num_buf_release_entry);
825 
826 	pdev = wlan_objmgr_get_pdev_by_id(psoc, dbr_rsp.pdev_id,
827 					  WLAN_DIRECT_BUF_RX_ID);
828 	if (!pdev) {
829 		direct_buf_rx_err("pdev is null");
830 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DIRECT_BUF_RX_ID);
831 		return QDF_STATUS_E_INVAL;
832 	}
833 
834 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
835 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
836 
837 	if (dbr_pdev_obj == NULL) {
838 		direct_buf_rx_err("dir buf rx object is null");
839 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DIRECT_BUF_RX_ID);
840 		return QDF_STATUS_E_FAILURE;
841 	}
842 
843 	mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id]);
844 
845 	if (!mod_param) {
846 		direct_buf_rx_err("dir buf rx module param is null");
847 		wlan_objmgr_pdev_release_ref(pdev, WLAN_DIRECT_BUF_RX_ID);
848 		return QDF_STATUS_E_FAILURE;
849 	}
850 
851 	dbr_buf_pool = mod_param->dbr_buf_pool;
852 	dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry *
853 					sizeof(struct direct_buf_rx_entry));
854 
855 	if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) {
856 		direct_buf_rx_err("More than expected number of metadata");
857 		wlan_objmgr_pdev_release_ref(pdev,
858 					     WLAN_DIRECT_BUF_RX_ID);
859 		return QDF_STATUS_E_FAILURE;
860 	}
861 
862 	for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) {
863 		if (wmi_extract_dbr_buf_release_entry(
864 			GET_WMI_HDL_FROM_PSOC(psoc), data_buf, i,
865 			&dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) {
866 			direct_buf_rx_err("Unable to extract DBR buf entry %d",
867 					  i+1);
868 			qdf_mem_free(dbr_rsp.dbr_entries);
869 			wlan_objmgr_pdev_release_ref(pdev,
870 						     WLAN_DIRECT_BUF_RX_ID);
871 			return QDF_STATUS_E_FAILURE;
872 		}
873 		status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp,
874 						&dbr_data, i, &cookie);
875 
876 		if (QDF_IS_STATUS_ERROR(status)) {
877 			direct_buf_rx_err("DBR data get failed");
878 			qdf_mem_free(dbr_rsp.dbr_entries);
879 			wlan_objmgr_pdev_release_ref(pdev,
880 						     WLAN_DIRECT_BUF_RX_ID);
881 			return QDF_STATUS_E_FAILURE;
882 		}
883 
884 		dbr_data.meta_data_valid = false;
885 		if (i < dbr_rsp.num_meta_data_entry) {
886 			if (wmi_extract_dbr_buf_metadata(
887 				GET_WMI_HDL_FROM_PSOC(psoc), data_buf, i,
888 				&dbr_data.meta_data) == QDF_STATUS_SUCCESS)
889 				dbr_data.meta_data_valid = true;
890 		}
891 		ret = mod_param->dbr_rsp_handler(pdev, &dbr_data);
892 		status = target_if_dbr_replenish_ring(pdev, mod_param,
893 						      dbr_data.vaddr, cookie);
894 		if (QDF_IS_STATUS_ERROR(status)) {
895 			direct_buf_rx_err("dir buf rx ring replenish failed");
896 			qdf_mem_free(dbr_rsp.dbr_entries);
897 			wlan_objmgr_pdev_release_ref(pdev,
898 						     WLAN_DIRECT_BUF_RX_ID);
899 			return QDF_STATUS_E_FAILURE;
900 		}
901 	}
902 
903 	qdf_mem_free(dbr_rsp.dbr_entries);
904 	wlan_objmgr_pdev_release_ref(pdev, WLAN_DIRECT_BUF_RX_ID);
905 
906 	return ret;
907 }
908 
909 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev,
910 			struct direct_buf_rx_psoc_obj *dbr_psoc_obj,
911 			struct direct_buf_rx_module_param *mod_param)
912 {
913 	uint32_t idx;
914 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
915 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
916 	struct direct_buf_rx_buf_info *dbr_buf_pool;
917 
918 	direct_buf_rx_enter();
919 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
920 	dbr_ring_cap = mod_param->dbr_ring_cap;
921 	dbr_buf_pool = mod_param->dbr_buf_pool;
922 
923 	direct_buf_rx_info("dbr_ring_cfg %pK, dbr_ring_cap %pK dbr_buf_pool %pK",
924 			   dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool);
925 
926 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
927 		direct_buf_rx_info("dbr buf pool unmap and free for ptr %d",
928 				   idx);
929 		qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev,
930 			(qdf_dma_addr_t)dbr_buf_pool[idx].paddr,
931 			QDF_DMA_FROM_DEVICE,
932 			dbr_ring_cap->min_buf_size);
933 		qdf_mem_free(dbr_buf_pool[idx].vaddr);
934 	}
935 
936 	return QDF_STATUS_SUCCESS;
937 }
938 
939 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev,
940 			struct direct_buf_rx_module_param *mod_param)
941 {
942 	struct wlan_objmgr_psoc *psoc;
943 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
944 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
945 
946 	direct_buf_rx_enter();
947 	psoc = wlan_pdev_get_psoc(pdev);
948 	if (!psoc) {
949 		direct_buf_rx_err("psoc is null");
950 		return QDF_STATUS_E_FAILURE;
951 	}
952 
953 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
954 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
955 
956 	if (dbr_psoc_obj == NULL) {
957 		direct_buf_rx_err("dir buf rx psoc object is null");
958 		return QDF_STATUS_E_FAILURE;
959 	}
960 	direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj);
961 
962 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
963 	if (dbr_ring_cfg) {
964 		target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param);
965 		hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng);
966 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
967 					dbr_psoc_obj->osdev->dev,
968 					dbr_ring_cfg->ring_alloc_size,
969 					dbr_ring_cfg->base_vaddr_unaligned,
970 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
971 	}
972 
973 	return QDF_STATUS_SUCCESS;
974 }
975 
976 static QDF_STATUS target_if_dbr_deinit_srng(
977 			struct wlan_objmgr_pdev *pdev,
978 			struct direct_buf_rx_module_param *mod_param)
979 {
980 	struct direct_buf_rx_buf_info *dbr_buf_pool;
981 
982 	direct_buf_rx_enter();
983 	dbr_buf_pool = mod_param->dbr_buf_pool;
984 	direct_buf_rx_info("dbr buf pool %pK", dbr_buf_pool);
985 	target_if_dbr_deinit_ring(pdev, mod_param);
986 	qdf_mem_free(dbr_buf_pool);
987 	mod_param->dbr_buf_pool = NULL;
988 
989 	return QDF_STATUS_SUCCESS;
990 }
991 
992 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev,
993 			struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
994 			enum DBR_MODULE mod_id)
995 {
996 	struct direct_buf_rx_module_param *mod_param;
997 
998 	direct_buf_rx_enter();
999 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id]);
1000 
1001 	if (!mod_param) {
1002 		direct_buf_rx_err("dir buf rx module param is null");
1003 		return QDF_STATUS_E_FAILURE;
1004 	}
1005 	direct_buf_rx_info("mod_param %pK", mod_param);
1006 	direct_buf_rx_info("dbr_ring_cap %pK", mod_param->dbr_ring_cap);
1007 	target_if_dbr_deinit_srng(pdev, mod_param);
1008 	qdf_mem_free(mod_param->dbr_ring_cap);
1009 	mod_param->dbr_ring_cap = NULL;
1010 	qdf_mem_free(mod_param->dbr_ring_cfg);
1011 	mod_param->dbr_ring_cfg = NULL;
1012 
1013 	return QDF_STATUS_SUCCESS;
1014 }
1015 
1016 QDF_STATUS target_if_direct_buf_rx_register_events(
1017 				struct wlan_objmgr_psoc *psoc)
1018 {
1019 	int ret;
1020 
1021 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
1022 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
1023 		return QDF_STATUS_E_INVAL;
1024 	}
1025 
1026 	ret = wmi_unified_register_event_handler(
1027 			get_wmi_unified_hdl_from_psoc(psoc),
1028 			wmi_dma_buf_release_event_id,
1029 			target_if_direct_buf_rx_rsp_event_handler,
1030 			WMI_RX_UMAC_CTX);
1031 
1032 	if (ret)
1033 		direct_buf_rx_info("event handler not supported", ret);
1034 
1035 	return QDF_STATUS_SUCCESS;
1036 }
1037 
1038 QDF_STATUS target_if_direct_buf_rx_unregister_events(
1039 				struct wlan_objmgr_psoc *psoc)
1040 {
1041 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
1042 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
1043 		return QDF_STATUS_E_INVAL;
1044 	}
1045 
1046 	wmi_unified_unregister_event_handler(
1047 			get_wmi_unified_hdl_from_psoc(psoc),
1048 			wmi_dma_buf_release_event_id);
1049 
1050 	return QDF_STATUS_SUCCESS;
1051 }
1052 
1053 QDF_STATUS target_if_direct_buf_rx_print_ring_stat(
1054 				struct wlan_objmgr_pdev *pdev)
1055 {
1056 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1057 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1058 	struct wlan_objmgr_psoc *psoc;
1059 	void *srng, *hal_soc;
1060 	uint32_t hp = 0, tp = 0;
1061 	struct direct_buf_rx_module_param *mod_param;
1062 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1063 	uint8_t num_modules, mod_idx;
1064 
1065 	if (!pdev) {
1066 		direct_buf_rx_err("pdev is null");
1067 		return QDF_STATUS_E_INVAL;
1068 	}
1069 
1070 	psoc = wlan_pdev_get_psoc(pdev);
1071 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1072 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1073 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1074 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1075 	hal_soc = dbr_psoc_obj->hal_soc;
1076 	num_modules = dbr_pdev_obj->num_modules;
1077 	direct_buf_rx_err("--------------------------------------------------");
1078 	direct_buf_rx_err("| Module ID |    Module    | Head Idx | Tail Idx |");
1079 	direct_buf_rx_err("--------------------------------------------------");
1080 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
1081 		mod_param = &dbr_pdev_obj->dbr_mod_param[mod_idx];
1082 		dbr_ring_cfg = mod_param->dbr_ring_cfg;
1083 		srng = dbr_ring_cfg->srng;
1084 		hal_api_get_tphp(hal_soc, srng, &tp, &hp);
1085 		direct_buf_rx_err("|%11d|%14s|%10x|%10x|",
1086 				  mod_idx,
1087 				  g_dbr_module_name[mod_idx].module_name_str,
1088 				  hp, tp);
1089 	}
1090 	direct_buf_rx_err("--------------------------------------------------");
1091 
1092 	return QDF_STATUS_SUCCESS;
1093 }
1094