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