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