xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_mem.h (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
2  * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * DOC: qdf_mem
30  * QCA driver framework (QDF) memory management APIs
31  */
32 
33 #if !defined(__QDF_MEMORY_H)
34 #define __QDF_MEMORY_H
35 
36 /* Include Files */
37 #include <qdf_types.h>
38 #include <i_qdf_mem.h>
39 
40 #define QDF_CACHE_LINE_SZ __qdf_cache_line_sz
41 
42 /**
43  * qdf_align() - align to the given size.
44  * @a: input that needs to be aligned.
45  * @align_size: boundary on which 'a' has to be alinged.
46  *
47  * Return: aligned value.
48  */
49 #define qdf_align(a, align_size)   __qdf_align(a, align_size)
50 
51 /**
52  * struct qdf_mem_dma_page_t - Allocated dmaable page
53  * @page_v_addr_start: Page start virtual address
54  * @page_v_addr_end: Page end virtual address
55  * @page_p_addr: Page start physical address
56  */
57 struct qdf_mem_dma_page_t {
58 	char *page_v_addr_start;
59 	char *page_v_addr_end;
60 	qdf_dma_addr_t page_p_addr;
61 };
62 
63 /**
64  * struct qdf_mem_multi_page_t - multiple page allocation information storage
65  * @num_element_per_page: Number of element in single page
66  * @num_pages: Number of allocation needed pages
67  * @dma_pages: page information storage in case of coherent memory
68  * @cacheable_pages: page information storage in case of cacheable memory
69  */
70 struct qdf_mem_multi_page_t {
71 	uint16_t num_element_per_page;
72 	uint16_t num_pages;
73 	struct qdf_mem_dma_page_t *dma_pages;
74 	void **cacheable_pages;
75 };
76 
77 
78 /* Preprocessor definitions and constants */
79 
80 typedef __qdf_mempool_t qdf_mempool_t;
81 
82 /**
83  * qdf_mem_init() - Initialize QDF memory module
84  *
85  * Return: None
86  *
87  */
88 void qdf_mem_init(void);
89 
90 /**
91  * qdf_mem_exit() - Exit QDF memory module
92  *
93  * Return: None
94  *
95  */
96 void qdf_mem_exit(void);
97 
98 #ifdef MEMORY_DEBUG
99 /**
100  * qdf_mem_malloc_debug() - debug version of QDF memory allocation API
101  * @size: Number of bytes of memory to allocate.
102  * @file: File name of the call site
103  * @line: Line number of the call site
104  * @caller: Address of the caller function
105  *
106  * This function will dynamicallly allocate the specified number of bytes of
107  * memory and add it to the qdf tracking list to check for memory leaks and
108  * corruptions
109  *
110  * Return: A valid memory location on success, or NULL on failure
111  */
112 void *qdf_mem_malloc_debug(size_t size, const char *file, uint32_t line,
113 			   void *caller);
114 
115 #define qdf_mem_malloc(size) \
116 	qdf_mem_malloc_debug(size, __FILE__, __LINE__, QDF_RET_IP)
117 
118 /**
119  * qdf_mem_free_debug() - debug version of qdf_mem_free
120  * @ptr: Pointer to the starting address of the memory to be freed.
121  *
122  * This function will free the memory pointed to by 'ptr'. It also checks for
123  * memory corruption, underrun, overrun, double free, domain mismatch, etc.
124  *
125  * Return: none
126  */
127 void qdf_mem_free_debug(void *ptr, const char *file, uint32_t line);
128 
129 #define qdf_mem_free(ptr) \
130 	qdf_mem_free_debug(ptr, __FILE__, __LINE__)
131 
132 /**
133  * qdf_mem_check_for_leaks() - Assert that the current memory domain is empty
134  *
135  * Call this to ensure there are no active memory allocations being tracked
136  * against the current debug domain. For example, one should call this function
137  * immediately before a call to qdf_debug_domain_set() as a memory leak
138  * detection mechanism.
139  *
140  * e.g.
141  *	qdf_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
142  *
143  *	...
144  *
145  *	// memory is allocated and freed
146  *
147  *	...
148  *
149  *	// before transitioning back to inactive state,
150  *	// make sure all active memory has been freed
151  *	qdf_mem_check_for_leaks();
152  *	qdf_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
153  *
154  *	...
155  *
156  *	// also, before program exit, make sure init time memory is freed
157  *	qdf_mem_check_for_leaks();
158  *	exit();
159  *
160  * Return: None
161  */
162 void qdf_mem_check_for_leaks(void);
163 
164 /**
165  * qdf_mem_alloc_consistent_debug() - allocates consistent qdf memory
166  * @osdev: OS device handle
167  * @dev: Pointer to device handle
168  * @size: Size to be allocated
169  * @paddr: Physical address
170  * @file: file name of the call site
171  * @line: line numbe rof the call site
172  * @caller: Address of the caller function
173  *
174  * Return: pointer of allocated memory or null if memory alloc fails
175  */
176 void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev,
177 				     qdf_size_t size, qdf_dma_addr_t *paddr,
178 				     const char *file, uint32_t line,
179 				     void *caller);
180 
181 #define qdf_mem_alloc_consistent(osdev, dev, size, paddr) \
182 	qdf_mem_alloc_consistent_debug(osdev, dev, size, paddr, \
183 				       __FILE__, __LINE__, QDF_RET_IP)
184 
185 /**
186  * qdf_mem_free_consistent_debug() - free consistent qdf memory
187  * @osdev: OS device handle
188  * @size: Size to be allocated
189  * @vaddr: virtual address
190  * @paddr: Physical address
191  * @memctx: Pointer to DMA context
192  * @file: file name of the call site
193  * @line: line numbe rof the call site
194  *
195  * Return: none
196  */
197 void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev,
198 				   qdf_size_t size, void *vaddr,
199 				   qdf_dma_addr_t paddr,
200 				   qdf_dma_context_t memctx,
201 				   const char *file, uint32_t line);
202 
203 #define qdf_mem_free_consistent(osdev, dev, size, vaddr, paddr, memctx) \
204 	qdf_mem_free_consistent_debug(osdev, dev, size, vaddr, paddr, memctx, \
205 				  __FILE__, __LINE__)
206 #else
207 void *qdf_mem_malloc(qdf_size_t size);
208 
209 /**
210  * qdf_mem_free() - free QDF memory
211  * @ptr: Pointer to the starting address of the memory to be freed.
212  *
213  * Return: None
214  */
215 void qdf_mem_free(void *ptr);
216 
217 static inline void qdf_mem_check_for_leaks(void) { }
218 
219 void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev,
220 			       qdf_size_t size, qdf_dma_addr_t *paddr);
221 
222 void qdf_mem_free_consistent(qdf_device_t osdev, void *dev,
223 			     qdf_size_t size, void *vaddr,
224 			     qdf_dma_addr_t paddr, qdf_dma_context_t memctx);
225 
226 #endif /* MEMORY_DEBUG */
227 
228 void *qdf_mem_alloc_outline(qdf_device_t osdev, qdf_size_t size);
229 
230 void qdf_mem_set(void *ptr, uint32_t num_bytes, uint32_t value);
231 
232 void qdf_mem_zero(void *ptr, uint32_t num_bytes);
233 
234 void qdf_mem_copy(void *dst_addr, const void *src_addr, uint32_t num_bytes);
235 
236 void qdf_mem_move(void *dst_addr, const void *src_addr, uint32_t num_bytes);
237 
238 void qdf_mem_free_outline(void *buf);
239 
240 void qdf_mem_zero_outline(void *buf, qdf_size_t size);
241 
242 void qdf_ether_addr_copy(void *dst_addr, const void *src_addr);
243 
244 /**
245  * qdf_mem_cmp() - memory compare
246  * @memory1: pointer to one location in memory to compare.
247  * @memory2: pointer to second location in memory to compare.
248  * @num_bytes: the number of bytes to compare.
249  *
250  * Function to compare two pieces of memory, similar to memcmp function
251  * in standard C.
252  * Return:
253  * int32_t - returns an int value that tells if the memory
254  * locations are equal or not equal.
255  * 0 -- equal
256  * < 0 -- *memory1 is less than *memory2
257  * > 0 -- *memory1 is bigger than *memory2
258  */
259 static inline int32_t qdf_mem_cmp(const void *memory1, const void *memory2,
260 				  uint32_t num_bytes)
261 {
262 	return __qdf_mem_cmp(memory1, memory2, num_bytes);
263 }
264 
265 /**
266  * qdf_mem_map_nbytes_single - Map memory for DMA
267  * @osdev: pomter OS device context
268  * @buf: pointer to memory to be dma mapped
269  * @dir: DMA map direction
270  * @nbytes: number of bytes to be mapped.
271  * @phy_addr: ponter to recive physical address.
272  *
273  * Return: success/failure
274  */
275 static inline uint32_t qdf_mem_map_nbytes_single(qdf_device_t osdev, void *buf,
276 						 qdf_dma_dir_t dir, int nbytes,
277 						 qdf_dma_addr_t *phy_addr)
278 {
279 #if defined(HIF_PCI)
280 	return __qdf_mem_map_nbytes_single(osdev, buf, dir, nbytes, phy_addr);
281 #else
282 	return 0;
283 #endif
284 }
285 
286 /**
287  * qdf_mem_unmap_nbytes_single() - un_map memory for DMA
288  * @osdev: pomter OS device context
289  * @phy_addr: physical address of memory to be dma unmapped
290  * @dir: DMA unmap direction
291  * @nbytes: number of bytes to be unmapped.
292  *
293  * Return: none
294  */
295 static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev,
296 					       qdf_dma_addr_t phy_addr,
297 					       qdf_dma_dir_t dir,
298 					       int nbytes)
299 {
300 #if defined(HIF_PCI)
301 	__qdf_mem_unmap_nbytes_single(osdev, phy_addr, dir, nbytes);
302 #endif
303 }
304 
305 /**
306  * qdf_mempool_init - Create and initialize memory pool
307  * @osdev: platform device object
308  * @pool_addr: address of the pool created
309  * @elem_cnt: no. of elements in pool
310  * @elem_size: size of each pool element in bytes
311  * @flags: flags
312  * Return: Handle to memory pool or NULL if allocation failed
313  */
314 static inline int qdf_mempool_init(qdf_device_t osdev,
315 				   qdf_mempool_t *pool_addr, int elem_cnt,
316 				   size_t elem_size, uint32_t flags)
317 {
318 	return __qdf_mempool_init(osdev, pool_addr, elem_cnt, elem_size,
319 				  flags);
320 }
321 
322 /**
323  * qdf_mempool_destroy - Destroy memory pool
324  * @osdev: platform device object
325  * @Handle: to memory pool
326  * Return: none
327  */
328 static inline void qdf_mempool_destroy(qdf_device_t osdev, qdf_mempool_t pool)
329 {
330 	__qdf_mempool_destroy(osdev, pool);
331 }
332 
333 /**
334  * qdf_mempool_alloc - Allocate an element memory pool
335  * @osdev: platform device object
336  * @Handle: to memory pool
337  * Return: Pointer to the allocated element or NULL if the pool is empty
338  */
339 static inline void *qdf_mempool_alloc(qdf_device_t osdev, qdf_mempool_t pool)
340 {
341 	return (void *)__qdf_mempool_alloc(osdev, pool);
342 }
343 
344 /**
345  * qdf_mempool_free - Free a memory pool element
346  * @osdev: Platform device object
347  * @pool: Handle to memory pool
348  * @buf: Element to be freed
349  * Return: none
350  */
351 static inline void qdf_mempool_free(qdf_device_t osdev, qdf_mempool_t pool,
352 				    void *buf)
353 {
354 	__qdf_mempool_free(osdev, pool, buf);
355 }
356 
357 void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev,
358 					qdf_dma_addr_t bus_addr,
359 					qdf_size_t size,
360 					__dma_data_direction direction);
361 
362 void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev,
363 					qdf_dma_addr_t bus_addr,
364 					qdf_size_t size,
365 					__dma_data_direction direction);
366 
367 void qdf_mem_multi_pages_alloc(qdf_device_t osdev,
368 			       struct qdf_mem_multi_page_t *pages,
369 			       size_t element_size, uint16_t element_num,
370 			       qdf_dma_context_t memctxt, bool cacheable);
371 void qdf_mem_multi_pages_free(qdf_device_t osdev,
372 			      struct qdf_mem_multi_page_t *pages,
373 			      qdf_dma_context_t memctxt, bool cacheable);
374 int qdf_mem_multi_page_link(qdf_device_t osdev,
375 		struct qdf_mem_multi_page_t *pages,
376 		uint32_t elem_size, uint32_t elem_count, uint8_t cacheable);
377 /**
378  * qdf_mem_skb_inc() - increment total skb allocation size
379  * @size: size to be added
380  *
381  * Return: none
382  */
383 void qdf_mem_skb_inc(qdf_size_t size);
384 
385 /**
386  * qdf_mem_skb_dec() - decrement total skb allocation size
387  * @size: size to be decremented
388  *
389  * Return: none
390  */
391 void qdf_mem_skb_dec(qdf_size_t size);
392 
393 /**
394  * qdf_mem_map_table_alloc() - Allocate shared memory info structure
395  * @num: number of required storage
396  *
397  * Allocate mapping table for DMA memory allocation. This is needed for
398  * IPA-WLAN buffer sharing when SMMU Stage1 Translation is enabled.
399  *
400  * Return: shared memory info storage table pointer
401  */
402 static inline qdf_mem_info_t *qdf_mem_map_table_alloc(uint32_t num)
403 {
404 	qdf_mem_info_t *mem_info_arr;
405 
406 	mem_info_arr = qdf_mem_malloc(num * sizeof(mem_info_arr[0]));
407 	return mem_info_arr;
408 }
409 
410 /**
411  * qdf_update_mem_map_table() - Update DMA memory map info
412  * @osdev: Parent device instance
413  * @mem_info: Pointer to shared memory information
414  * @dma_addr: dma address
415  * @mem_size: memory size allocated
416  *
417  * Store DMA shared memory information
418  *
419  * Return: none
420  */
421 static inline void qdf_update_mem_map_table(qdf_device_t osdev,
422 					    qdf_mem_info_t *mem_info,
423 					    qdf_dma_addr_t dma_addr,
424 					    uint32_t mem_size)
425 {
426 	if (!mem_info) {
427 		__qdf_print("%s: NULL mem_info\n", __func__);
428 		return;
429 	}
430 
431 	__qdf_update_mem_map_table(osdev, mem_info, dma_addr, mem_size);
432 }
433 
434 /**
435  * qdf_mem_smmu_s1_enabled() - Return SMMU stage 1 translation enable status
436  * @osdev parent device instance
437  *
438  * Return: true if smmu s1 enabled, false if smmu s1 is bypassed
439  */
440 static inline bool qdf_mem_smmu_s1_enabled(qdf_device_t osdev)
441 {
442 	return __qdf_mem_smmu_s1_enabled(osdev);
443 }
444 
445 /**
446  * qdf_mem_paddr_from_dmaaddr() - get actual physical address from dma address
447  * @osdev: Parent device instance
448  * @dma_addr: DMA/IOVA address
449  *
450  * Get actual physical address from dma_addr based on SMMU enablement status.
451  * IF SMMU Stage 1 tranlation is enabled, DMA APIs return IO virtual address
452  * (IOVA) otherwise returns physical address. So get SMMU physical address
453  * mapping from IOVA.
454  *
455  * Return: dmaable physical address
456  */
457 static inline qdf_dma_addr_t qdf_mem_paddr_from_dmaaddr(qdf_device_t osdev,
458 							qdf_dma_addr_t dma_addr)
459 {
460 	return __qdf_mem_paddr_from_dmaaddr(osdev, dma_addr);
461 }
462 
463 /**
464  * qdf_os_mem_dma_get_sgtable() - Returns DMA memory scatter gather table
465  * @dev: device instace
466  * @sgt: scatter gather table pointer
467  * @cpu_addr: HLOS virtual address
468  * @dma_addr: dma address
469  * @size: allocated memory size
470  *
471  * Return: physical address
472  */
473 static inline int
474 qdf_mem_dma_get_sgtable(struct device *dev, void *sgt, void *cpu_addr,
475 			qdf_dma_addr_t dma_addr, size_t size)
476 {
477 	return __qdf_os_mem_dma_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
478 }
479 
480 /**
481  * qdf_mem_get_dma_addr() - Return dma address based on SMMU translation status.
482  * @osdev: Parent device instance
483  * @mem_info: Pointer to allocated memory information
484  *
485  * Get dma address based on SMMU enablement status. If SMMU Stage 1
486  * tranlation is enabled, DMA APIs return IO virtual address otherwise
487  * returns physical address.
488  *
489  * Return: dma address
490  */
491 static inline qdf_dma_addr_t qdf_mem_get_dma_addr(qdf_device_t osdev,
492 						  qdf_mem_info_t *mem_info)
493 {
494 	return __qdf_mem_get_dma_addr(osdev, mem_info);
495 }
496 
497 /**
498  * qdf_mem_get_dma_addr_ptr() - Return DMA address pointer from mem info struct
499  * @osdev: Parent device instance
500  * @mem_info: Pointer to allocated memory information
501  *
502  * Based on smmu stage 1 translation enablement, return corresponding dma
503  * address storage pointer.
504  *
505  * Return: dma address storage pointer
506  */
507 static inline qdf_dma_addr_t *qdf_mem_get_dma_addr_ptr(qdf_device_t osdev,
508 						       qdf_mem_info_t *mem_info)
509 {
510 	return __qdf_mem_get_dma_addr_ptr(osdev, mem_info);
511 }
512 
513 
514 /**
515  * qdf_mem_get_dma_size() - Return DMA memory size
516  * @osdev: parent device instance
517  * @mem_info: Pointer to allocated memory information
518  *
519  * Return: DMA memory size
520  */
521 static inline uint32_t
522 qdf_mem_get_dma_size(qdf_device_t osdev,
523 		       qdf_mem_info_t *mem_info)
524 {
525 	return __qdf_mem_get_dma_size(osdev, mem_info);
526 }
527 
528 /**
529  * qdf_mem_set_dma_size() - Set DMA memory size
530  * @osdev: parent device instance
531  * @mem_info: Pointer to allocated memory information
532  * @mem_size: memory size allocated
533  *
534  * Return: none
535  */
536 static inline void
537 qdf_mem_set_dma_size(qdf_device_t osdev,
538 		       qdf_mem_info_t *mem_info,
539 		       uint32_t mem_size)
540 {
541 	__qdf_mem_set_dma_size(osdev, mem_info, mem_size);
542 }
543 
544 /**
545  * qdf_mem_get_dma_size() - Return DMA physical address
546  * @osdev: parent device instance
547  * @mem_info: Pointer to allocated memory information
548  *
549  * Return: DMA physical address
550  */
551 static inline qdf_dma_addr_t
552 qdf_mem_get_dma_pa(qdf_device_t osdev,
553 		     qdf_mem_info_t *mem_info)
554 {
555 	return __qdf_mem_get_dma_pa(osdev, mem_info);
556 }
557 
558 /**
559  * qdf_mem_set_dma_size() - Set DMA physical address
560  * @osdev: parent device instance
561  * @mem_info: Pointer to allocated memory information
562  * @dma_pa: DMA phsical address
563  *
564  * Return: none
565  */
566 static inline void
567 qdf_mem_set_dma_pa(qdf_device_t osdev,
568 		     qdf_mem_info_t *mem_info,
569 		     qdf_dma_addr_t dma_pa)
570 {
571 	__qdf_mem_set_dma_pa(osdev, mem_info, dma_pa);
572 }
573 
574 /**
575  * qdf_mem_shared_mem_alloc() - Allocate DMA memory for shared resource
576  * @osdev: parent device instance
577  * @mem_info: Pointer to allocated memory information
578  * @size: size to be allocated
579  *
580  * Allocate DMA memory which will be shared with external kernel module. This
581  * information is needed for SMMU mapping.
582  *
583  * Return: 0 suceess
584  */
585 static inline qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev,
586 							 uint32_t size)
587 {
588 	qdf_shared_mem_t *shared_mem;
589 
590 	shared_mem = qdf_mem_malloc(sizeof(*shared_mem));
591 	if (!shared_mem) {
592 		__qdf_print("%s: Unable to allocate memory for shared resource struct\n",
593 			    __func__);
594 		return NULL;
595 	}
596 
597 	shared_mem->vaddr = qdf_mem_alloc_consistent(osdev, osdev->dev,
598 				size, qdf_mem_get_dma_addr_ptr(osdev,
599 						&shared_mem->mem_info));
600 	if (!shared_mem->vaddr) {
601 		__qdf_print("%s; Unable to allocate DMA memory for shared resource\n",
602 			    __func__);
603 		qdf_mem_free(shared_mem);
604 		return NULL;
605 	}
606 
607 	qdf_mem_set_dma_size(osdev, &shared_mem->mem_info, size);
608 	qdf_mem_zero(shared_mem->vaddr,
609 		     qdf_mem_get_dma_size(osdev, &shared_mem->mem_info));
610 	qdf_mem_set_dma_pa(osdev, &shared_mem->mem_info,
611 			   qdf_mem_paddr_from_dmaaddr(osdev,
612 				qdf_mem_get_dma_addr(osdev,
613 						     &shared_mem->mem_info)));
614 	qdf_mem_dma_get_sgtable(osdev->dev,
615 				(void *)&shared_mem->sgtable,
616 				shared_mem->vaddr,
617 				qdf_mem_get_dma_addr(osdev,
618 						     &shared_mem->mem_info),
619 				qdf_mem_get_dma_size(osdev,
620 						     &shared_mem->mem_info));
621 
622 	shared_mem->sgtable.sgl->dma_address =
623 		qdf_mem_get_dma_pa(osdev, &shared_mem->mem_info);
624 
625 	return shared_mem;
626 }
627 
628 /**
629  * qdf_mem_shared_mem_free() - Free shared memory
630  * @osdev: parent device instance
631  * @shared_mem: shared memory information storage
632  *
633  * Free DMA shared memory resource
634  *
635  * Return: None
636  */
637 static inline void qdf_mem_shared_mem_free(qdf_device_t osdev,
638 					   qdf_shared_mem_t *shared_mem)
639 {
640 	if (!shared_mem) {
641 		__qdf_print("%s: NULL shared mem struct passed\n",
642 			    __func__);
643 		return;
644 	}
645 
646 	if (shared_mem->vaddr) {
647 		qdf_mem_free_consistent(osdev, osdev->dev,
648 					qdf_mem_get_dma_size(osdev,
649 						&shared_mem->mem_info),
650 					shared_mem->vaddr,
651 					qdf_mem_get_dma_addr(osdev,
652 						&shared_mem->mem_info),
653 					qdf_get_dma_mem_context(shared_mem,
654 								memctx));
655 	}
656 	qdf_mem_free(shared_mem);
657 }
658 
659 #endif /* __QDF_MEMORY_H */
660