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