xref: /wlan-dirver/qca-wifi-host-cmn/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c (revision 11f5a63a6cbdda84849a730de22f0a71e635d58c)
1 /*
2  * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "target_if.h"
20 #include "wlan_lmac_if_def.h"
21 #include "target_if_direct_buf_rx_main.h"
22 #include <target_if_direct_buf_rx_api.h>
23 #include "hal_api.h"
24 #include <service_ready_util.h>
25 #include <init_deinit_lmac.h>
26 
27 /**
28  * struct module_name : Module name information structure
29  * @module_name_str : Module name subscribing to DBR
30  */
31 struct module_name {
32 	unsigned char module_name_str[QDF_MAX_NAME_SIZE];
33 };
34 
35 static const struct module_name g_dbr_module_name[DBR_MODULE_MAX] = {
36 	[DBR_MODULE_SPECTRAL] = {"SPECTRAL"},
37 	[DBR_MODULE_CFR]      = {"CFR"},
38 };
39 
40 static uint8_t get_num_dbr_modules_per_pdev(struct wlan_objmgr_pdev *pdev)
41 {
42 	struct wlan_objmgr_psoc *psoc;
43 	struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap;
44 	uint8_t num_dbr_ring_caps, cap_idx, pdev_id, num_modules;
45 	struct target_psoc_info *tgt_psoc_info;
46 
47 	psoc = wlan_pdev_get_psoc(pdev);
48 
49 	if (!psoc) {
50 		direct_buf_rx_err("psoc is null");
51 		return 0;
52 	}
53 
54 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
55 	if (!tgt_psoc_info) {
56 		direct_buf_rx_err("target_psoc_info is null");
57 		return 0;
58 	}
59 	num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info);
60 	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
61 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
62 	num_modules = 0;
63 
64 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
65 		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id)
66 			num_modules++;
67 	}
68 
69 	return num_modules;
70 }
71 
72 static QDF_STATUS populate_dbr_cap_mod_param(struct wlan_objmgr_pdev *pdev,
73 			struct direct_buf_rx_module_param *mod_param)
74 {
75 	struct wlan_objmgr_psoc *psoc;
76 	struct wlan_psoc_host_dbr_ring_caps *dbr_ring_cap;
77 	uint8_t cap_idx;
78 	bool cap_found = false;
79 	enum DBR_MODULE mod_id = mod_param->mod_id;
80 	uint32_t num_dbr_ring_caps, pdev_id;
81 	struct target_psoc_info *tgt_psoc_info;
82 
83 	psoc = wlan_pdev_get_psoc(pdev);
84 
85 	if (!psoc) {
86 		direct_buf_rx_err("psoc is null");
87 		return QDF_STATUS_E_INVAL;
88 	}
89 
90 	tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
91 	if (!tgt_psoc_info) {
92 		direct_buf_rx_err("target_psoc_info is null");
93 		return QDF_STATUS_E_INVAL;
94 	}
95 
96 	num_dbr_ring_caps = target_psoc_get_num_dbr_ring_caps(tgt_psoc_info);
97 	dbr_ring_cap = target_psoc_get_dbr_ring_caps(tgt_psoc_info);
98 	pdev_id = mod_param->pdev_id;
99 
100 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
101 		if (dbr_ring_cap[cap_idx].pdev_id == pdev_id) {
102 			if (dbr_ring_cap[cap_idx].mod_id == mod_id) {
103 				mod_param->dbr_ring_cap->ring_elems_min =
104 					dbr_ring_cap[cap_idx].ring_elems_min;
105 				mod_param->dbr_ring_cap->min_buf_size =
106 					dbr_ring_cap[cap_idx].min_buf_size;
107 				mod_param->dbr_ring_cap->min_buf_align =
108 					dbr_ring_cap[cap_idx].min_buf_align;
109 				cap_found = true;
110 			}
111 		}
112 	}
113 
114 	if (!cap_found) {
115 		direct_buf_rx_err("No cap found for module %d in pdev %d",
116 				  mod_id, pdev_id);
117 		return QDF_STATUS_E_FAILURE;
118 	}
119 
120 	return QDF_STATUS_SUCCESS;
121 }
122 
123 QDF_STATUS target_if_direct_buf_rx_pdev_create_handler(
124 	struct wlan_objmgr_pdev *pdev, void *data)
125 {
126 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
127 	struct wlan_objmgr_psoc *psoc;
128 	uint8_t num_modules;
129 	QDF_STATUS status;
130 
131 	direct_buf_rx_enter();
132 
133 	if (!pdev) {
134 		direct_buf_rx_err("pdev context passed is null");
135 		return QDF_STATUS_E_INVAL;
136 	}
137 
138 	psoc = wlan_pdev_get_psoc(pdev);
139 
140 	if (!psoc) {
141 		direct_buf_rx_err("psoc is null");
142 		return QDF_STATUS_E_INVAL;
143 	}
144 
145 	dbr_pdev_obj = qdf_mem_malloc(sizeof(*dbr_pdev_obj));
146 
147 	if (!dbr_pdev_obj)
148 		return QDF_STATUS_E_NOMEM;
149 
150 	direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj);
151 
152 	status = wlan_objmgr_pdev_component_obj_attach(pdev,
153 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
154 					dbr_pdev_obj, QDF_STATUS_SUCCESS);
155 
156 	if (status != QDF_STATUS_SUCCESS) {
157 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
158 				  status);
159 		qdf_mem_free(dbr_pdev_obj);
160 		return status;
161 	}
162 
163 	num_modules = get_num_dbr_modules_per_pdev(pdev);
164 	direct_buf_rx_info("Number of modules = %d pdev %d", num_modules,
165 			   wlan_objmgr_pdev_get_pdev_id(pdev));
166 	dbr_pdev_obj->num_modules = num_modules;
167 
168 	if (!dbr_pdev_obj->num_modules) {
169 		direct_buf_rx_info("Number of modules = %d", num_modules);
170 		return QDF_STATUS_SUCCESS;
171 	}
172 
173 	direct_buf_rx_info("sring number = %d", DBR_SRNG_NUM);
174 	dbr_pdev_obj->dbr_mod_param = qdf_mem_malloc(num_modules *
175 				DBR_SRNG_NUM *
176 				sizeof(struct direct_buf_rx_module_param));
177 
178 	if (!dbr_pdev_obj->dbr_mod_param) {
179 		 direct_buf_rx_err("alloc dbr mod param fail");
180 		wlan_objmgr_pdev_component_obj_detach(pdev,
181 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
182 					dbr_pdev_obj);
183 		qdf_mem_free(dbr_pdev_obj);
184 		return QDF_STATUS_E_NOMEM;
185 	}
186 
187 	return QDF_STATUS_SUCCESS;
188 }
189 
190 QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler(
191 	struct wlan_objmgr_pdev *pdev, void *data)
192 {
193 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
194 	QDF_STATUS status;
195 	uint8_t num_modules, mod_idx, srng_id;
196 
197 	if (!pdev) {
198 		direct_buf_rx_err("pdev context passed is null");
199 		return QDF_STATUS_E_INVAL;
200 	}
201 
202 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
203 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
204 
205 	if (!dbr_pdev_obj) {
206 		direct_buf_rx_err("dir buf rx object is null");
207 		return QDF_STATUS_E_FAILURE;
208 	}
209 
210 	num_modules = dbr_pdev_obj->num_modules;
211 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
212 		for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++)
213 			target_if_deinit_dbr_ring(pdev, dbr_pdev_obj,
214 						  mod_idx, srng_id);
215 	}
216 
217 	qdf_mem_free(dbr_pdev_obj->dbr_mod_param);
218 	dbr_pdev_obj->dbr_mod_param = NULL;
219 
220 	status = wlan_objmgr_pdev_component_obj_detach(pdev,
221 					WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
222 					dbr_pdev_obj);
223 
224 	if (status != QDF_STATUS_SUCCESS) {
225 		direct_buf_rx_err("failed to detach dir buf rx component %d",
226 				  status);
227 	}
228 
229 	qdf_mem_free(dbr_pdev_obj);
230 
231 	return status;
232 }
233 
234 QDF_STATUS target_if_direct_buf_rx_psoc_create_handler(
235 	struct wlan_objmgr_psoc *psoc, void *data)
236 {
237 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
238 	QDF_STATUS status;
239 
240 	direct_buf_rx_enter();
241 
242 	if (!psoc) {
243 		direct_buf_rx_err("psoc context passed is null");
244 		return QDF_STATUS_E_INVAL;
245 	}
246 
247 	dbr_psoc_obj = qdf_mem_malloc(sizeof(*dbr_psoc_obj));
248 
249 	if (!dbr_psoc_obj)
250 		return QDF_STATUS_E_NOMEM;
251 
252 	direct_buf_rx_info("Dbr psoc obj %pK", dbr_psoc_obj);
253 
254 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
255 			WLAN_TARGET_IF_COMP_DIRECT_BUF_RX, dbr_psoc_obj,
256 			QDF_STATUS_SUCCESS);
257 
258 	if (status != QDF_STATUS_SUCCESS) {
259 		direct_buf_rx_err("Failed to attach dir buf rx component %d",
260 				  status);
261 		goto attach_error;
262 	}
263 
264 	return status;
265 
266 attach_error:
267 	qdf_mem_free(dbr_psoc_obj);
268 
269 	return status;
270 }
271 
272 QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler(
273 	struct wlan_objmgr_psoc *psoc, void *data)
274 {
275 	QDF_STATUS status;
276 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
277 
278 	direct_buf_rx_enter();
279 
280 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
281 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
282 
283 	if (!dbr_psoc_obj) {
284 		direct_buf_rx_err("dir buf rx psoc obj is null");
285 		return QDF_STATUS_E_FAILURE;
286 	}
287 
288 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
289 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX,
290 				dbr_psoc_obj);
291 
292 	if (status != QDF_STATUS_SUCCESS) {
293 		direct_buf_rx_err("failed to detach dir buf rx component %d",
294 				  status);
295 	}
296 
297 	qdf_mem_free(dbr_psoc_obj);
298 
299 	return status;
300 }
301 
302 static QDF_STATUS target_if_dbr_replenish_ring(struct wlan_objmgr_pdev *pdev,
303 			struct direct_buf_rx_module_param *mod_param,
304 			void *aligned_vaddr, uint32_t cookie)
305 {
306 	uint64_t *ring_entry;
307 	uint32_t dw_lo, dw_hi = 0, map_status;
308 	void *hal_soc, *srng;
309 	qdf_dma_addr_t paddr;
310 	struct wlan_objmgr_psoc *psoc;
311 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
312 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
313 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
314 	struct direct_buf_rx_buf_info *dbr_buf_pool;
315 
316 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
317 	dbr_ring_cap = mod_param->dbr_ring_cap;
318 	dbr_buf_pool = mod_param->dbr_buf_pool;
319 
320 	psoc = wlan_pdev_get_psoc(pdev);
321 
322 	if (!psoc) {
323 		direct_buf_rx_err("psoc is null");
324 		return QDF_STATUS_E_FAILURE;
325 	}
326 
327 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
328 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
329 
330 	if (!dbr_psoc_obj) {
331 		direct_buf_rx_err("dir buf rx psoc object is null");
332 		return QDF_STATUS_E_FAILURE;
333 	}
334 
335 	hal_soc = dbr_psoc_obj->hal_soc;
336 	srng = dbr_ring_cfg->srng;
337 	if (!aligned_vaddr) {
338 		direct_buf_rx_err("aligned vaddr is null");
339 		return QDF_STATUS_SUCCESS;
340 	}
341 
342 	map_status = qdf_mem_map_nbytes_single(dbr_psoc_obj->osdev,
343 					       aligned_vaddr,
344 					       QDF_DMA_FROM_DEVICE,
345 					       dbr_ring_cap->min_buf_size,
346 					       &paddr);
347 	if (map_status) {
348 		direct_buf_rx_err("mem map failed status = %d", map_status);
349 		return QDF_STATUS_E_FAILURE;
350 	}
351 
352 	QDF_ASSERT(!((uint64_t)paddr % dbr_ring_cap->min_buf_align));
353 	dbr_buf_pool[cookie].paddr = paddr;
354 
355 	hal_srng_access_start(hal_soc, srng);
356 	ring_entry = hal_srng_src_get_next(hal_soc, srng);
357 	QDF_ASSERT(ring_entry);
358 	dw_lo = (uint64_t)paddr & 0xFFFFFFFF;
359 	WMI_HOST_DBR_RING_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32);
360 	WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie);
361 	*ring_entry = (uint64_t)dw_hi << 32 | dw_lo;
362 	hal_srng_access_end(hal_soc, srng);
363 
364 	return QDF_STATUS_SUCCESS;
365 }
366 
367 static QDF_STATUS target_if_dbr_fill_ring(struct wlan_objmgr_pdev *pdev,
368 			  struct direct_buf_rx_module_param *mod_param)
369 {
370 	uint32_t idx;
371 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
372 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
373 	struct direct_buf_rx_buf_info *dbr_buf_pool;
374 	QDF_STATUS status;
375 
376 	direct_buf_rx_enter();
377 
378 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
379 	dbr_ring_cap = mod_param->dbr_ring_cap;
380 	dbr_buf_pool = mod_param->dbr_buf_pool;
381 
382 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
383 		void *buf_vaddr_unaligned = NULL, *buf_vaddr_aligned;
384 		dma_addr_t buf_paddr_aligned, buf_paddr_unaligned;
385 
386 		buf_vaddr_aligned = qdf_aligned_malloc(
387 			&dbr_ring_cap->min_buf_size, &buf_vaddr_unaligned,
388 			&buf_paddr_unaligned, &buf_paddr_aligned,
389 			dbr_ring_cap->min_buf_align);
390 
391 		if (!buf_vaddr_aligned) {
392 			direct_buf_rx_err("dir buf rx ring alloc failed");
393 			return QDF_STATUS_E_NOMEM;
394 		}
395 		dbr_buf_pool[idx].vaddr = buf_vaddr_unaligned;
396 		dbr_buf_pool[idx].offset = buf_vaddr_aligned -
397 		    buf_vaddr_unaligned;
398 		dbr_buf_pool[idx].cookie = idx;
399 		status = target_if_dbr_replenish_ring(pdev, mod_param,
400 						      buf_vaddr_aligned, idx);
401 		if (QDF_IS_STATUS_ERROR(status)) {
402 			direct_buf_rx_err("replenish failed with status : %d",
403 					  status);
404 			qdf_mem_free(buf_vaddr_unaligned);
405 			return QDF_STATUS_E_FAILURE;
406 		}
407 	}
408 
409 	return QDF_STATUS_SUCCESS;
410 }
411 
412 static QDF_STATUS target_if_dbr_init_ring(struct wlan_objmgr_pdev *pdev,
413 			struct direct_buf_rx_module_param *mod_param)
414 {
415 	void *srng;
416 	uint32_t num_entries, ring_alloc_size, max_entries, entry_size;
417 	qdf_dma_addr_t paddr;
418 	struct hal_srng_params ring_params = {0};
419 	struct wlan_objmgr_psoc *psoc;
420 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
421 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
422 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
423 	QDF_STATUS status;
424 
425 	direct_buf_rx_enter();
426 
427 	psoc = wlan_pdev_get_psoc(pdev);
428 
429 	if (!psoc) {
430 		direct_buf_rx_err("psoc is null");
431 		return QDF_STATUS_E_FAILURE;
432 	}
433 
434 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
435 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
436 
437 	if (!dbr_psoc_obj) {
438 		direct_buf_rx_err("dir buf rx psoc object is null");
439 		return QDF_STATUS_E_FAILURE;
440 	}
441 
442 	if (!dbr_psoc_obj->hal_soc ||
443 	    !dbr_psoc_obj->osdev) {
444 		direct_buf_rx_err("dir buf rx target attach failed");
445 		return QDF_STATUS_E_FAILURE;
446 	}
447 
448 	max_entries = hal_srng_max_entries(dbr_psoc_obj->hal_soc,
449 					   DIR_BUF_RX_DMA_SRC);
450 	entry_size = hal_srng_get_entrysize(dbr_psoc_obj->hal_soc,
451 					    DIR_BUF_RX_DMA_SRC);
452 	direct_buf_rx_info("Max Entries = %d", max_entries);
453 	direct_buf_rx_info("Entry Size = %d", entry_size);
454 
455 	status = populate_dbr_cap_mod_param(pdev, mod_param);
456 	if (QDF_IS_STATUS_ERROR(status)) {
457 		direct_buf_rx_err("Module cap population failed");
458 		return QDF_STATUS_E_FAILURE;
459 	}
460 
461 	dbr_ring_cap = mod_param->dbr_ring_cap;
462 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
463 	num_entries = dbr_ring_cap->ring_elems_min > max_entries ?
464 			max_entries : dbr_ring_cap->ring_elems_min;
465 	direct_buf_rx_info("Num entries = %d", num_entries);
466 	dbr_ring_cfg->num_ptr = num_entries;
467 	mod_param->dbr_buf_pool = qdf_mem_malloc(num_entries * sizeof(
468 				struct direct_buf_rx_buf_info));
469 	if (!mod_param->dbr_buf_pool)
470 		return QDF_STATUS_E_NOMEM;
471 
472 	ring_alloc_size = (num_entries * entry_size) + DBR_RING_BASE_ALIGN - 1;
473 	dbr_ring_cfg->ring_alloc_size = ring_alloc_size;
474 	direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj);
475 	dbr_ring_cfg->base_vaddr_unaligned = qdf_mem_alloc_consistent(
476 		dbr_psoc_obj->osdev, dbr_psoc_obj->osdev->dev, ring_alloc_size,
477 		&paddr);
478 	direct_buf_rx_info("vaddr aligned allocated");
479 	dbr_ring_cfg->base_paddr_unaligned = paddr;
480 	if (!dbr_ring_cfg->base_vaddr_unaligned) {
481 		direct_buf_rx_err("dir buf rx vaddr alloc failed");
482 		qdf_mem_free(mod_param->dbr_buf_pool);
483 		return QDF_STATUS_E_NOMEM;
484 	}
485 
486 	/* Alignment is defined to 8 for now. Will be advertised by FW */
487 	dbr_ring_cfg->base_vaddr_aligned = (void *)(uintptr_t)qdf_roundup(
488 		(uint64_t)(uintptr_t)dbr_ring_cfg->base_vaddr_unaligned,
489 		DBR_RING_BASE_ALIGN);
490 	ring_params.ring_base_vaddr = dbr_ring_cfg->base_vaddr_aligned;
491 	dbr_ring_cfg->base_paddr_aligned = qdf_roundup(
492 		(uint64_t)dbr_ring_cfg->base_paddr_unaligned,
493 		DBR_RING_BASE_ALIGN);
494 	ring_params.ring_base_paddr =
495 		(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_aligned;
496 	ring_params.num_entries = num_entries;
497 	srng = hal_srng_setup(dbr_psoc_obj->hal_soc, DIR_BUF_RX_DMA_SRC,
498 			      mod_param->mod_id,
499 			      mod_param->pdev_id, &ring_params);
500 
501 	if (!srng) {
502 		direct_buf_rx_err("srng setup failed");
503 		qdf_mem_free(mod_param->dbr_buf_pool);
504 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
505 					dbr_psoc_obj->osdev->dev,
506 					ring_alloc_size,
507 					dbr_ring_cfg->base_vaddr_unaligned,
508 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
509 		return QDF_STATUS_E_FAILURE;
510 	}
511 	dbr_ring_cfg->srng = srng;
512 	dbr_ring_cfg->tail_idx_addr =
513 		hal_srng_get_tp_addr(dbr_psoc_obj->hal_soc, srng);
514 	dbr_ring_cfg->head_idx_addr =
515 		hal_srng_get_hp_addr(dbr_psoc_obj->hal_soc, srng);
516 	dbr_ring_cfg->buf_size = dbr_ring_cap->min_buf_size;
517 
518 	return target_if_dbr_fill_ring(pdev, mod_param);
519 }
520 
521 static QDF_STATUS target_if_dbr_init_srng(struct wlan_objmgr_pdev *pdev,
522 			struct direct_buf_rx_module_param *mod_param)
523 {
524 	QDF_STATUS status;
525 
526 	direct_buf_rx_info("Init DBR srng");
527 
528 	if (!mod_param) {
529 		direct_buf_rx_err("dir buf rx module param is null");
530 		return QDF_STATUS_E_INVAL;
531 	}
532 
533 	mod_param->dbr_ring_cap = qdf_mem_malloc(sizeof(
534 					struct direct_buf_rx_ring_cap));
535 
536 	if (!mod_param->dbr_ring_cap)
537 		return QDF_STATUS_E_NOMEM;
538 
539 	/* Allocate memory for DBR Ring Config */
540 	mod_param->dbr_ring_cfg = qdf_mem_malloc(sizeof(
541 					struct direct_buf_rx_ring_cfg));
542 
543 	if (!mod_param->dbr_ring_cfg) {
544 		qdf_mem_free(mod_param->dbr_ring_cap);
545 		return QDF_STATUS_E_NOMEM;
546 	}
547 
548 	status = target_if_dbr_init_ring(pdev, mod_param);
549 
550 	if (QDF_IS_STATUS_ERROR(status)) {
551 		direct_buf_rx_err("DBR ring init failed");
552 		qdf_mem_free(mod_param->dbr_ring_cfg);
553 		qdf_mem_free(mod_param->dbr_ring_cap);
554 		return QDF_STATUS_E_FAILURE;
555 	}
556 
557 	return QDF_STATUS_SUCCESS;
558 }
559 
560 static QDF_STATUS target_if_dbr_cfg_tgt(struct wlan_objmgr_pdev *pdev,
561 			struct direct_buf_rx_module_param *mod_param)
562 {
563 	QDF_STATUS status;
564 	struct wlan_objmgr_psoc *psoc;
565 	wmi_unified_t wmi_hdl;
566 	struct direct_buf_rx_cfg_req dbr_cfg_req = {0};
567 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
568 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
569 	struct dbr_module_config *dbr_config;
570 
571 	direct_buf_rx_enter();
572 
573 	psoc = wlan_pdev_get_psoc(pdev);
574 	if (!psoc) {
575 		direct_buf_rx_err("psoc is null");
576 		return QDF_STATUS_E_FAILURE;
577 	}
578 
579 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
580 	dbr_ring_cap = mod_param->dbr_ring_cap;
581 	dbr_config = &mod_param->dbr_config;
582 	wmi_hdl = lmac_get_pdev_wmi_handle(pdev);
583 	if (!wmi_hdl) {
584 		direct_buf_rx_err("WMI handle null. Can't send WMI CMD");
585 		return QDF_STATUS_E_INVAL;
586 	}
587 
588 	direct_buf_rx_debug("Sending DBR Ring CFG to target");
589 	dbr_cfg_req.pdev_id = mod_param->pdev_id;
590 	/* Module ID numbering starts from 1 in FW. need to fix it */
591 	dbr_cfg_req.mod_id = mod_param->mod_id;
592 	dbr_cfg_req.base_paddr_lo = (uint64_t)dbr_ring_cfg->base_paddr_aligned
593 						& 0xFFFFFFFF;
594 	dbr_cfg_req.base_paddr_hi = (uint64_t)dbr_ring_cfg->base_paddr_aligned
595 						& 0xFFFFFFFF00000000;
596 	dbr_cfg_req.head_idx_paddr_lo = (uint64_t)dbr_ring_cfg->head_idx_addr
597 						& 0xFFFFFFFF;
598 	dbr_cfg_req.head_idx_paddr_hi = (uint64_t)dbr_ring_cfg->head_idx_addr
599 						& 0xFFFFFFFF00000000;
600 	dbr_cfg_req.tail_idx_paddr_lo = (uint64_t)dbr_ring_cfg->tail_idx_addr
601 						& 0xFFFFFFFF;
602 	dbr_cfg_req.tail_idx_paddr_hi = (uint64_t)dbr_ring_cfg->tail_idx_addr
603 						& 0xFFFFFFFF00000000;
604 	dbr_cfg_req.num_elems = dbr_ring_cap->ring_elems_min;
605 	dbr_cfg_req.buf_size = dbr_ring_cap->min_buf_size;
606 	dbr_cfg_req.num_resp_per_event = dbr_config->num_resp_per_event;
607 	dbr_cfg_req.event_timeout_ms = dbr_config->event_timeout_in_ms;
608 	direct_buf_rx_info("pdev id %d mod id %d base addr lo %x\n"
609 			   "base addr hi %x head idx addr lo %x\n"
610 			   "head idx addr hi %x tail idx addr lo %x\n"
611 			   "tail idx addr hi %x num ptr %d\n"
612 			   "num resp %d event timeout %d\n",
613 			   dbr_cfg_req.pdev_id, dbr_cfg_req.mod_id,
614 			   dbr_cfg_req.base_paddr_lo, dbr_cfg_req.base_paddr_hi,
615 			   dbr_cfg_req.head_idx_paddr_lo,
616 			   dbr_cfg_req.head_idx_paddr_hi,
617 			   dbr_cfg_req.tail_idx_paddr_lo,
618 			   dbr_cfg_req.tail_idx_paddr_hi,
619 			   dbr_cfg_req.num_elems,
620 			   dbr_cfg_req.num_resp_per_event,
621 			   dbr_cfg_req.event_timeout_ms);
622 	status = wmi_unified_dbr_ring_cfg(wmi_hdl, &dbr_cfg_req);
623 
624 	return status;
625 }
626 
627 static QDF_STATUS target_if_init_dbr_ring(struct wlan_objmgr_pdev *pdev,
628 				struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
629 				enum DBR_MODULE mod_id, uint8_t srng_id)
630 {
631 	QDF_STATUS status = QDF_STATUS_SUCCESS;
632 	struct direct_buf_rx_module_param *mod_param;
633 
634 	direct_buf_rx_info("Init DBR ring for module %d, srng %d",
635 			   mod_id, srng_id);
636 
637 	if (!dbr_pdev_obj) {
638 		direct_buf_rx_err("dir buf rx object is null");
639 		return QDF_STATUS_E_INVAL;
640 	}
641 
642 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
643 
644 	if (!mod_param) {
645 		direct_buf_rx_err("dir buf rx module param is null");
646 		return QDF_STATUS_E_FAILURE;
647 	}
648 
649 	direct_buf_rx_info("mod_param %pK", mod_param);
650 
651 	mod_param->mod_id = mod_id;
652 	mod_param->pdev_id = dbr_get_pdev_id(
653 				srng_id, wlan_objmgr_pdev_get_pdev_id(pdev));
654 
655 	/* Initialize DMA ring now */
656 	status = target_if_dbr_init_srng(pdev, mod_param);
657 	if (QDF_IS_STATUS_ERROR(status)) {
658 		direct_buf_rx_err("DBR ring init failed %d", status);
659 		return status;
660 	}
661 
662 	/* Send CFG request command to firmware */
663 	status = target_if_dbr_cfg_tgt(pdev, mod_param);
664 	if (QDF_IS_STATUS_ERROR(status)) {
665 		direct_buf_rx_err("DBR config to target failed %d", status);
666 		goto dbr_srng_init_failed;
667 	}
668 
669 	return QDF_STATUS_SUCCESS;
670 
671 dbr_srng_init_failed:
672 	target_if_deinit_dbr_ring(pdev, dbr_pdev_obj, mod_id, srng_id);
673 	return status;
674 }
675 
676 QDF_STATUS target_if_direct_buf_rx_module_register(
677 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id,
678 			struct dbr_module_config *dbr_config,
679 			bool (*dbr_rsp_handler)
680 			     (struct wlan_objmgr_pdev *pdev,
681 			      struct direct_buf_rx_data *dbr_data))
682 {
683 	QDF_STATUS status;
684 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
685 	struct dbr_module_config *config = NULL;
686 	struct direct_buf_rx_module_param *mod_param;
687 	uint8_t srng_id;
688 
689 	if (!pdev) {
690 		direct_buf_rx_err("pdev context passed is null");
691 		return QDF_STATUS_E_INVAL;
692 	}
693 
694 	if (!dbr_rsp_handler) {
695 		direct_buf_rx_err("Response handler is null");
696 		return QDF_STATUS_E_INVAL;
697 	}
698 
699 	if (mod_id >= DBR_MODULE_MAX) {
700 		direct_buf_rx_err("Invalid module id");
701 		return QDF_STATUS_E_INVAL;
702 	}
703 
704 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
705 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
706 
707 	if (!dbr_pdev_obj) {
708 		direct_buf_rx_err("dir buf rx object is null");
709 		return QDF_STATUS_E_FAILURE;
710 	}
711 
712 	direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj);
713 
714 	if (!dbr_pdev_obj->dbr_mod_param) {
715 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
716 		return QDF_STATUS_E_FAILURE;
717 	}
718 
719 	if (mod_id >= dbr_pdev_obj->num_modules) {
720 		direct_buf_rx_err("Module %d not supported in target", mod_id);
721 		return QDF_STATUS_E_FAILURE;
722 	}
723 
724 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
725 		mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
726 		config = &mod_param->dbr_config;
727 		mod_param->dbr_rsp_handler = dbr_rsp_handler;
728 		*config = *dbr_config;
729 
730 		status = target_if_init_dbr_ring(pdev, dbr_pdev_obj,
731 						 (enum DBR_MODULE)mod_id,
732 						 srng_id);
733 		if (QDF_IS_STATUS_ERROR(status))
734 			direct_buf_rx_err("init dbr ring fail, srng_id %d, status %d",
735 					  srng_id, status);
736 	}
737 
738 	return status;
739 }
740 
741 QDF_STATUS target_if_direct_buf_rx_module_unregister(
742 			struct wlan_objmgr_pdev *pdev, uint8_t mod_id)
743 {
744 	QDF_STATUS status;
745 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
746 	uint8_t srng_id;
747 
748 	if (!pdev) {
749 		direct_buf_rx_err("pdev context passed is null");
750 		return QDF_STATUS_E_INVAL;
751 	}
752 
753 	if (mod_id >= DBR_MODULE_MAX) {
754 		direct_buf_rx_err("Invalid module id");
755 		return QDF_STATUS_E_INVAL;
756 	}
757 
758 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
759 			(pdev,
760 			 WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
761 
762 	if (!dbr_pdev_obj) {
763 		direct_buf_rx_err("dir buf rx object is null");
764 		return QDF_STATUS_E_FAILURE;
765 	}
766 
767 	direct_buf_rx_info("Dbr pdev obj %pK", dbr_pdev_obj);
768 
769 	if (!dbr_pdev_obj->dbr_mod_param) {
770 		direct_buf_rx_err("dbr_pdev_obj->dbr_mod_param is NULL");
771 		return QDF_STATUS_E_FAILURE;
772 	}
773 
774 	if (mod_id >= dbr_pdev_obj->num_modules) {
775 		direct_buf_rx_err("Module %d not supported in target", mod_id);
776 		return QDF_STATUS_E_FAILURE;
777 	}
778 
779 	for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
780 		status = target_if_deinit_dbr_ring(pdev, dbr_pdev_obj,
781 						   mod_id, srng_id);
782 		direct_buf_rx_info("status %d", status);
783 	}
784 
785 	return status;
786 }
787 
788 static void *target_if_dbr_vaddr_lookup(
789 			struct direct_buf_rx_module_param *mod_param,
790 			qdf_dma_addr_t paddr, uint32_t cookie)
791 {
792 	struct direct_buf_rx_buf_info *dbr_buf_pool;
793 
794 	dbr_buf_pool = mod_param->dbr_buf_pool;
795 
796 	if (dbr_buf_pool[cookie].paddr == paddr) {
797 		return dbr_buf_pool[cookie].vaddr +
798 				dbr_buf_pool[cookie].offset;
799 	}
800 
801 	direct_buf_rx_err("Incorrect paddr found on cookie slot");
802 	return NULL;
803 }
804 
805 QDF_STATUS target_if_dbr_cookie_lookup(struct wlan_objmgr_pdev *pdev,
806 				       uint8_t mod_id, qdf_dma_addr_t paddr,
807 				       uint32_t *cookie, uint8_t srng_id)
808 {
809 	struct direct_buf_rx_buf_info *dbr_buf_pool;
810 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
811 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
812 	struct direct_buf_rx_module_param *mod_param;
813 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
814 	uint32_t idx;
815 
816 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
817 	if (!dbr_pdev_obj) {
818 		direct_buf_rx_err("dir buf rx object is null");
819 		return QDF_STATUS_E_FAILURE;
820 	}
821 
822 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
823 	if (!mod_param) {
824 		direct_buf_rx_err("dir buf rx module param is null");
825 		return QDF_STATUS_E_FAILURE;
826 	}
827 
828 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
829 	dbr_buf_pool = mod_param->dbr_buf_pool;
830 
831 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
832 		if (dbr_buf_pool[idx].paddr &&
833 		    dbr_buf_pool[idx].paddr == paddr) {
834 			*cookie = idx;
835 			return QDF_STATUS_SUCCESS;
836 		}
837 	}
838 
839 	return QDF_STATUS_E_FAILURE;
840 }
841 
842 QDF_STATUS target_if_dbr_buf_release(struct wlan_objmgr_pdev *pdev,
843 				     uint8_t mod_id, qdf_dma_addr_t paddr,
844 				     uint32_t cookie, uint8_t srng_id)
845 {
846 	struct direct_buf_rx_module_param *mod_param;
847 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
848 	enum wlan_umac_comp_id dbr_comp_id = WLAN_TARGET_IF_COMP_DIRECT_BUF_RX;
849 	void *vaddr;
850 	QDF_STATUS status;
851 
852 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, dbr_comp_id);
853 	if (!dbr_pdev_obj) {
854 		direct_buf_rx_err("dir buf rx object is null");
855 		return QDF_STATUS_E_FAILURE;
856 	}
857 
858 	mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
859 	if (!mod_param) {
860 		direct_buf_rx_err("dir buf rx module param is null");
861 		return QDF_STATUS_E_FAILURE;
862 	}
863 
864 	vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, cookie);
865 	if (!vaddr)
866 		return QDF_STATUS_E_FAILURE;
867 
868 	status = target_if_dbr_replenish_ring(pdev, mod_param,
869 					      vaddr, cookie);
870 	if (QDF_IS_STATUS_ERROR(status)) {
871 		direct_buf_rx_err("Ring replenish failed");
872 		return QDF_STATUS_E_FAILURE;
873 	}
874 
875 	return QDF_STATUS_SUCCESS;
876 }
877 
878 static QDF_STATUS target_if_get_dbr_data(struct wlan_objmgr_pdev *pdev,
879 			struct direct_buf_rx_module_param *mod_param,
880 			struct direct_buf_rx_rsp *dbr_rsp,
881 			struct direct_buf_rx_data *dbr_data,
882 			uint8_t idx, uint32_t *cookie)
883 {
884 	qdf_dma_addr_t paddr = 0;
885 	uint32_t addr_hi;
886 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
887 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
888 	struct wlan_objmgr_psoc *psoc;
889 
890 	psoc = wlan_pdev_get_psoc(pdev);
891 	if (!psoc) {
892 		direct_buf_rx_err("psoc is null");
893 		return QDF_STATUS_E_FAILURE;
894 	}
895 
896 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
897 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
898 
899 	if (!dbr_psoc_obj) {
900 		direct_buf_rx_err("dir buf rx psoc object is null");
901 		return QDF_STATUS_E_FAILURE;
902 	}
903 
904 	dbr_ring_cap = mod_param->dbr_ring_cap;
905 	addr_hi = (uint64_t)WMI_HOST_DBR_DATA_ADDR_HI_GET(
906 				dbr_rsp->dbr_entries[idx].paddr_hi);
907 	paddr = (qdf_dma_addr_t)((uint64_t)addr_hi << 32 |
908 				  dbr_rsp->dbr_entries[idx].paddr_lo);
909 	*cookie = WMI_HOST_DBR_DATA_ADDR_HI_HOST_DATA_GET(
910 				dbr_rsp->dbr_entries[idx].paddr_hi);
911 	dbr_data->vaddr = target_if_dbr_vaddr_lookup(mod_param, paddr, *cookie);
912 	dbr_data->cookie = *cookie;
913 	dbr_data->paddr = paddr;
914 	direct_buf_rx_debug("Cookie = %d Vaddr look up = %pK",
915 			    dbr_data->cookie, dbr_data->vaddr);
916 	dbr_data->dbr_len = dbr_rsp->dbr_entries[idx].len;
917 	qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev, (qdf_dma_addr_t)paddr,
918 				    QDF_DMA_FROM_DEVICE,
919 				    dbr_ring_cap->min_buf_size);
920 
921 	return QDF_STATUS_SUCCESS;
922 }
923 
924 #ifdef DBR_MULTI_SRNG_ENABLE
925 /**
926  * dbr_get_pdev_and_srng_id() - get pdev object and srng id
927  *
928  * @psoc: pointer to psoc object
929  * @pdev_id: pdev id from wmi_pdev_dma_ring_buf_release eventid
930  * @srng_id:  pointer to return srng id
931  *
932  * Return : pointer to pdev
933  */
934 static struct wlan_objmgr_pdev *
935 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
936 			 uint8_t *srng_id)
937 {
938 	struct wlan_objmgr_pdev *pdev;
939 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
940 
941 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
942 	if (!pdev) {
943 		pdev = wlan_objmgr_get_pdev_by_id(psoc, TGT_WMI_PDEV_ID_SOC,
944 						  dbr_mod_id);
945 		if (pdev) {
946 			direct_buf_rx_info("update srng id from %d to %d",
947 					   *srng_id, pdev_id);
948 			*srng_id = pdev_id;
949 		}
950 	}
951 
952 	return pdev;
953 }
954 #else
955 static struct wlan_objmgr_pdev *
956 dbr_get_pdev_and_srng_id(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
957 			 uint8_t *srng_id)
958 {
959 	struct wlan_objmgr_pdev *pdev;
960 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
961 
962 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbr_mod_id);
963 
964 	return pdev;
965 }
966 #endif
967 
968 static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn,
969 						uint8_t *data_buf,
970 						uint32_t data_len)
971 {
972 	int ret = 0;
973 	uint8_t i = 0;
974 	QDF_STATUS status;
975 	uint32_t cookie = 0;
976 	struct direct_buf_rx_rsp dbr_rsp = {0};
977 	struct direct_buf_rx_data dbr_data = {0};
978 	struct wlan_objmgr_psoc *psoc;
979 	struct wlan_objmgr_pdev *pdev;
980 	struct direct_buf_rx_buf_info *dbr_buf_pool;
981 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
982 	struct direct_buf_rx_module_param *mod_param;
983 	struct wmi_unified *wmi_handle;
984 	wlan_objmgr_ref_dbgid dbr_mod_id = WLAN_DIRECT_BUF_RX_ID;
985 	uint8_t srng_id = 0;
986 
987 	direct_buf_rx_enter();
988 
989 	psoc = target_if_get_psoc_from_scn_hdl(scn);
990 	if (!psoc) {
991 		direct_buf_rx_err("psoc is null");
992 		return QDF_STATUS_E_FAILURE;
993 	}
994 
995 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
996 	if (!wmi_handle) {
997 		direct_buf_rx_err("WMI handle is null");
998 		return QDF_STATUS_E_FAILURE;
999 	}
1000 
1001 	if (wmi_extract_dbr_buf_release_fixed(
1002 		wmi_handle, data_buf, &dbr_rsp) != QDF_STATUS_SUCCESS) {
1003 		direct_buf_rx_err("unable to extract DBR rsp fixed param");
1004 		return QDF_STATUS_E_FAILURE;
1005 	}
1006 
1007 	direct_buf_rx_debug("Num buf release entry = %d",
1008 			    dbr_rsp.num_buf_release_entry);
1009 
1010 	pdev = dbr_get_pdev_and_srng_id(psoc, (uint8_t)dbr_rsp.pdev_id,
1011 					&srng_id);
1012 	if (!pdev || (srng_id >= DBR_SRNG_NUM)) {
1013 		direct_buf_rx_err("invalid pdev or srng, pdev %pK, srng %d",
1014 				  pdev, srng_id);
1015 		return QDF_STATUS_E_INVAL;
1016 	}
1017 
1018 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1019 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1020 
1021 	if (!dbr_pdev_obj) {
1022 		direct_buf_rx_err("dir buf rx object is null");
1023 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1024 		return QDF_STATUS_E_FAILURE;
1025 	}
1026 
1027 	if (dbr_rsp.mod_id >= dbr_pdev_obj->num_modules) {
1028 		direct_buf_rx_err("Invalid module id:%d", dbr_rsp.mod_id);
1029 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1030 		return QDF_STATUS_E_FAILURE;
1031 	}
1032 	mod_param = &(dbr_pdev_obj->dbr_mod_param[dbr_rsp.mod_id][srng_id]);
1033 
1034 	if (!mod_param) {
1035 		direct_buf_rx_err("dir buf rx module param is null");
1036 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1037 		return QDF_STATUS_E_FAILURE;
1038 	}
1039 
1040 	dbr_buf_pool = mod_param->dbr_buf_pool;
1041 	dbr_rsp.dbr_entries = qdf_mem_malloc(dbr_rsp.num_buf_release_entry *
1042 					sizeof(struct direct_buf_rx_entry));
1043 
1044 	if (dbr_rsp.num_meta_data_entry > dbr_rsp.num_buf_release_entry) {
1045 		direct_buf_rx_err("More than expected number of metadata");
1046 		wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1047 		return QDF_STATUS_E_FAILURE;
1048 	}
1049 
1050 	for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) {
1051 		if (wmi_extract_dbr_buf_release_entry(
1052 			wmi_handle, data_buf, i,
1053 			&dbr_rsp.dbr_entries[i]) != QDF_STATUS_SUCCESS) {
1054 			direct_buf_rx_err("Unable to extract DBR buf entry %d",
1055 					  i+1);
1056 			qdf_mem_free(dbr_rsp.dbr_entries);
1057 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1058 			return QDF_STATUS_E_FAILURE;
1059 		}
1060 		status = target_if_get_dbr_data(pdev, mod_param, &dbr_rsp,
1061 						&dbr_data, i, &cookie);
1062 
1063 		if (QDF_IS_STATUS_ERROR(status)) {
1064 			direct_buf_rx_err("DBR data get failed");
1065 			qdf_mem_free(dbr_rsp.dbr_entries);
1066 			wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1067 			return QDF_STATUS_E_FAILURE;
1068 		}
1069 
1070 		dbr_data.meta_data_valid = false;
1071 		if (i < dbr_rsp.num_meta_data_entry) {
1072 			if (wmi_extract_dbr_buf_metadata(
1073 				wmi_handle, data_buf, i,
1074 				&dbr_data.meta_data) == QDF_STATUS_SUCCESS)
1075 				dbr_data.meta_data_valid = true;
1076 		}
1077 		if (mod_param->dbr_rsp_handler(pdev, &dbr_data)) {
1078 			status = target_if_dbr_replenish_ring(pdev, mod_param,
1079 							      dbr_data.vaddr,
1080 							      cookie);
1081 			if (QDF_IS_STATUS_ERROR(status)) {
1082 				direct_buf_rx_err("Ring replenish failed");
1083 				qdf_mem_free(dbr_rsp.dbr_entries);
1084 				wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1085 				return QDF_STATUS_E_FAILURE;
1086 			}
1087 		}
1088 	}
1089 
1090 	qdf_mem_free(dbr_rsp.dbr_entries);
1091 	wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id);
1092 
1093 	return ret;
1094 }
1095 
1096 static QDF_STATUS target_if_dbr_empty_ring(struct wlan_objmgr_pdev *pdev,
1097 			struct direct_buf_rx_psoc_obj *dbr_psoc_obj,
1098 			struct direct_buf_rx_module_param *mod_param)
1099 {
1100 	uint32_t idx;
1101 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1102 	struct direct_buf_rx_ring_cap *dbr_ring_cap;
1103 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1104 
1105 	direct_buf_rx_enter();
1106 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1107 	dbr_ring_cap = mod_param->dbr_ring_cap;
1108 	dbr_buf_pool = mod_param->dbr_buf_pool;
1109 
1110 	direct_buf_rx_debug("dbr_ring_cfg %pK, ring_cap %pK buf_pool %pK",
1111 			   dbr_ring_cfg, dbr_ring_cap, dbr_buf_pool);
1112 
1113 	for (idx = 0; idx < dbr_ring_cfg->num_ptr - 1; idx++) {
1114 		qdf_mem_unmap_nbytes_single(dbr_psoc_obj->osdev,
1115 			(qdf_dma_addr_t)dbr_buf_pool[idx].paddr,
1116 			QDF_DMA_FROM_DEVICE,
1117 			dbr_ring_cap->min_buf_size);
1118 		qdf_mem_free(dbr_buf_pool[idx].vaddr);
1119 	}
1120 
1121 	return QDF_STATUS_SUCCESS;
1122 }
1123 
1124 static QDF_STATUS target_if_dbr_deinit_ring(struct wlan_objmgr_pdev *pdev,
1125 			struct direct_buf_rx_module_param *mod_param)
1126 {
1127 	struct wlan_objmgr_psoc *psoc;
1128 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1129 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1130 
1131 	direct_buf_rx_enter();
1132 	psoc = wlan_pdev_get_psoc(pdev);
1133 	if (!psoc) {
1134 		direct_buf_rx_err("psoc is null");
1135 		return QDF_STATUS_E_FAILURE;
1136 	}
1137 
1138 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1139 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1140 
1141 	if (!dbr_psoc_obj) {
1142 		direct_buf_rx_err("dir buf rx psoc object is null");
1143 		return QDF_STATUS_E_FAILURE;
1144 	}
1145 	direct_buf_rx_info("dbr_psoc_obj %pK", dbr_psoc_obj);
1146 
1147 	dbr_ring_cfg = mod_param->dbr_ring_cfg;
1148 	if (dbr_ring_cfg) {
1149 		target_if_dbr_empty_ring(pdev, dbr_psoc_obj, mod_param);
1150 		hal_srng_cleanup(dbr_psoc_obj->hal_soc, dbr_ring_cfg->srng);
1151 		qdf_mem_free_consistent(dbr_psoc_obj->osdev,
1152 					dbr_psoc_obj->osdev->dev,
1153 					dbr_ring_cfg->ring_alloc_size,
1154 					dbr_ring_cfg->base_vaddr_unaligned,
1155 			(qdf_dma_addr_t)dbr_ring_cfg->base_paddr_unaligned, 0);
1156 	}
1157 
1158 	return QDF_STATUS_SUCCESS;
1159 }
1160 
1161 static QDF_STATUS target_if_dbr_deinit_srng(
1162 			struct wlan_objmgr_pdev *pdev,
1163 			struct direct_buf_rx_module_param *mod_param)
1164 {
1165 	struct direct_buf_rx_buf_info *dbr_buf_pool;
1166 
1167 	direct_buf_rx_enter();
1168 	dbr_buf_pool = mod_param->dbr_buf_pool;
1169 	direct_buf_rx_info("dbr buf pool %pK", dbr_buf_pool);
1170 	target_if_dbr_deinit_ring(pdev, mod_param);
1171 	if (mod_param->dbr_buf_pool)
1172 		qdf_mem_free(dbr_buf_pool);
1173 	mod_param->dbr_buf_pool = NULL;
1174 
1175 	return QDF_STATUS_SUCCESS;
1176 }
1177 
1178 QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev,
1179 			struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
1180 			enum DBR_MODULE mod_id, uint8_t srng_id)
1181 {
1182 	struct direct_buf_rx_module_param *mod_param;
1183 
1184 	direct_buf_rx_enter();
1185 	mod_param = &(dbr_pdev_obj->dbr_mod_param[mod_id][srng_id]);
1186 
1187 	if (!mod_param) {
1188 		direct_buf_rx_err("dir buf rx module param is null");
1189 		return QDF_STATUS_E_FAILURE;
1190 	}
1191 	direct_buf_rx_debug("mod_param %pK, dbr_ring_cap %pK",
1192 			    mod_param, mod_param->dbr_ring_cap);
1193 	target_if_dbr_deinit_srng(pdev, mod_param);
1194 	if (mod_param->dbr_ring_cap)
1195 		qdf_mem_free(mod_param->dbr_ring_cap);
1196 	mod_param->dbr_ring_cap = NULL;
1197 	if (mod_param->dbr_ring_cfg)
1198 		qdf_mem_free(mod_param->dbr_ring_cfg);
1199 	mod_param->dbr_ring_cfg = NULL;
1200 
1201 	return QDF_STATUS_SUCCESS;
1202 }
1203 
1204 QDF_STATUS target_if_direct_buf_rx_register_events(
1205 				struct wlan_objmgr_psoc *psoc)
1206 {
1207 	int ret;
1208 
1209 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
1210 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
1211 		return QDF_STATUS_E_INVAL;
1212 	}
1213 
1214 	ret = wmi_unified_register_event_handler(
1215 			get_wmi_unified_hdl_from_psoc(psoc),
1216 			wmi_dma_buf_release_event_id,
1217 			target_if_direct_buf_rx_rsp_event_handler,
1218 			WMI_RX_UMAC_CTX);
1219 
1220 	if (ret)
1221 		direct_buf_rx_info("event handler not supported, ret=%d", ret);
1222 
1223 	return QDF_STATUS_SUCCESS;
1224 }
1225 
1226 QDF_STATUS target_if_direct_buf_rx_unregister_events(
1227 				struct wlan_objmgr_psoc *psoc)
1228 {
1229 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
1230 		direct_buf_rx_err("psoc or psoc->tgt_if_handle is null");
1231 		return QDF_STATUS_E_INVAL;
1232 	}
1233 
1234 	wmi_unified_unregister_event_handler(
1235 			get_wmi_unified_hdl_from_psoc(psoc),
1236 			wmi_dma_buf_release_event_id);
1237 
1238 	return QDF_STATUS_SUCCESS;
1239 }
1240 
1241 QDF_STATUS target_if_direct_buf_rx_print_ring_stat(
1242 				struct wlan_objmgr_pdev *pdev)
1243 {
1244 	struct direct_buf_rx_psoc_obj *dbr_psoc_obj;
1245 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1246 	struct wlan_objmgr_psoc *psoc;
1247 	void *srng, *hal_soc;
1248 	uint32_t hp = 0, tp = 0;
1249 	struct direct_buf_rx_module_param *mod_param;
1250 	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
1251 	uint8_t num_modules, mod_idx;
1252 	uint8_t srng_id;
1253 
1254 	if (!pdev) {
1255 		direct_buf_rx_err("pdev is null");
1256 		return QDF_STATUS_E_INVAL;
1257 	}
1258 
1259 	psoc = wlan_pdev_get_psoc(pdev);
1260 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1261 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1262 	dbr_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
1263 				WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1264 	hal_soc = dbr_psoc_obj->hal_soc;
1265 	num_modules = dbr_pdev_obj->num_modules;
1266 	direct_buf_rx_err("--------------------------------------------------");
1267 	direct_buf_rx_err("| Module ID |    Module    | Head Idx | Tail Idx |");
1268 	direct_buf_rx_err("--------------------------------------------------");
1269 	for (mod_idx = 0; mod_idx < num_modules; mod_idx++) {
1270 		for (srng_id = 0; srng_id < DBR_SRNG_NUM; srng_id++) {
1271 			mod_param =
1272 				&dbr_pdev_obj->dbr_mod_param[mod_idx][srng_id];
1273 			dbr_ring_cfg = mod_param->dbr_ring_cfg;
1274 			srng = dbr_ring_cfg->srng;
1275 			hal_get_sw_hptp(hal_soc, srng, &tp, &hp);
1276 			direct_buf_rx_err("|%11d|%14s|%10x|%10x|",
1277 					  mod_idx, g_dbr_module_name[mod_idx].
1278 					  module_name_str,
1279 					  hp, tp);
1280 		}
1281 	}
1282 	direct_buf_rx_err("--------------------------------------------------");
1283 
1284 	return QDF_STATUS_SUCCESS;
1285 }
1286 
1287 QDF_STATUS
1288 target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev,
1289 					struct module_ring_params *param,
1290 					uint8_t mod_id, uint8_t srng_id)
1291 {
1292 	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
1293 	struct direct_buf_rx_module_param *dbr_mod_param;
1294 
1295 	if (!pdev) {
1296 		direct_buf_rx_err("pdev context passed is null");
1297 		return QDF_STATUS_E_INVAL;
1298 	}
1299 
1300 	dbr_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj
1301 			(pdev, WLAN_TARGET_IF_COMP_DIRECT_BUF_RX);
1302 
1303 	if (!dbr_pdev_obj) {
1304 		direct_buf_rx_err("dir buf rx object is null");
1305 		return QDF_STATUS_E_FAILURE;
1306 	}
1307 
1308 	if ((mod_id >= DBR_MODULE_MAX) || (srng_id >= DBR_SRNG_NUM)) {
1309 		direct_buf_rx_err("invalid params, mod id %d, srng id %d",
1310 				  mod_id, srng_id);
1311 		return QDF_STATUS_E_INVAL;
1312 	}
1313 
1314 	dbr_mod_param = &dbr_pdev_obj->dbr_mod_param[mod_id][srng_id];
1315 	param->num_bufs = dbr_mod_param->dbr_ring_cfg->num_ptr;
1316 	param->buf_size = dbr_mod_param->dbr_ring_cfg->buf_size;
1317 
1318 	return QDF_STATUS_SUCCESS;
1319 }
1320