1 /* 2 * Copyright (c) 2014-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 /** 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_FUNC_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 * @func: Function 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 *func, uint32_t line, 107 void *caller, uint32_t flag); 108 109 #define qdf_mem_malloc(size) \ 110 qdf_mem_malloc_debug(size, __func__, __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, __func__, __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, __func__, __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 * @func: Function 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 *func, 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 __func__, __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 * @func: Function 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 *func, 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 __func__, __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 /** 263 * qdf_aligned_malloc() - allocates aligned QDF memory. 264 * @size: Number of bytes of memory to allocate. 265 * @ring_base_align: Base address alignment. 266 * @vaddr_unaligned: Unaligned virtual address. 267 * @func: Function name of the call site. 268 * @line: Line number of the call site. 269 * 270 * This function will dynamically allocate the specified number of bytes of 271 * memory. Checks if the allocated base address is aligned with base_align. 272 * If not, it frees the allocated memory, adds base_align to alloc size and 273 * re-allocates the memory. 274 * 275 * Return: 276 * Upon successful allocate, returns an aligned base address of the allocated 277 * memory. If this function is unable to allocate the amount of memory 278 * specified (for any reason) it returns NULL. 279 */ 280 #define qdf_aligned_malloc(size, ring_base_align, vaddr_unaligned) \ 281 qdf_aligned_malloc_fl(size, ring_base_align, vaddr_unaligned, \ 282 __func__, __LINE__) 283 284 void *qdf_aligned_malloc_fl(qdf_size_t size, uint32_t ring_base_align, 285 void **vaddr_unaligned, 286 const char *func, uint32_t line); 287 288 /** 289 * qdf_aligned_mem_alloc_consistent() - allocates consistent qdf memory 290 * @osdev: OS device handle 291 * @dev: Pointer to device handle 292 * @size: Size to be allocated 293 * @vaddr_unaligned: Unaligned virtual address. 294 * @paddr_unaligned: Unaligned physical address. 295 * @paddr_aligned: Aligned physical address. 296 * @ring_base_align: Base address alignment. 297 * @func: Function name of the call site. 298 * @line: Line number of the call site. 299 * 300 * Return: pointer of allocated memory or null if memory alloc fails. 301 */ 302 #define qdf_aligned_mem_alloc_consistent(osdev, dev, size, vaddr_unaligned, \ 303 paddr_unaligned, paddr_aligned, ring_base_align) \ 304 qdf_aligned_mem_alloc_consistent_fl(osdev, dev, size, vaddr_unaligned, \ 305 paddr_unaligned, paddr_aligned, \ 306 ring_base_align, __func__, __LINE__) 307 308 void *qdf_aligned_mem_alloc_consistent_fl( 309 qdf_device_t osdev, void *dev, qdf_size_t size, 310 void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned, 311 qdf_dma_addr_t *paddr_aligned, uint32_t ring_base_align, 312 const char *func, uint32_t line); 313 314 void qdf_mem_set_io(void *ptr, uint32_t num_bytes, uint32_t value); 315 316 void qdf_mem_copy_toio(void *dst_addr, const void *src_addr, 317 uint32_t num_bytes); 318 319 /** 320 * qdf_mem_set() - set (fill) memory with a specified byte value. 321 * @ptr: Pointer to memory that will be set 322 * @num_bytes: Number of bytes to be set 323 * @value: Byte set in memory 324 * 325 * WARNING: parameter @num_bytes and @value are swapped comparing with 326 * standard C function "memset", please ensure correct usage of this function! 327 * 328 * Return: None 329 */ 330 void qdf_mem_set(void *ptr, uint32_t num_bytes, uint32_t value); 331 332 /** 333 * qdf_mem_zero() - zero out memory 334 * @ptr: pointer to memory that will be set to zero 335 * @num_bytes: number of bytes zero 336 * 337 * This function sets the memory location to all zeros, essentially clearing 338 * the memory. 339 * 340 * Return: None 341 */ 342 static inline void qdf_mem_zero(void *ptr, uint32_t num_bytes) 343 { 344 qdf_mem_set(ptr, num_bytes, 0); 345 } 346 347 /** 348 * qdf_mem_copy() - copy memory 349 * @dst_addr: Pointer to destination memory location (to copy to) 350 * @src_addr: Pointer to source memory location (to copy from) 351 * @num_bytes: Number of bytes to copy. 352 * 353 * Copy host memory from one location to another, similar to memcpy in 354 * standard C. Note this function does not specifically handle overlapping 355 * source and destination memory locations. Calling this function with 356 * overlapping source and destination memory locations will result in 357 * unpredictable results. Use qdf_mem_move() if the memory locations 358 * for the source and destination are overlapping (or could be overlapping!) 359 * 360 * Return: none 361 */ 362 void qdf_mem_copy(void *dst_addr, const void *src_addr, uint32_t num_bytes); 363 364 /** 365 * qdf_mem_move() - move memory 366 * @dst_addr: pointer to destination memory location (to move to) 367 * @src_addr: pointer to source memory location (to move from) 368 * @num_bytes: number of bytes to move. 369 * 370 * Move host memory from one location to another, similar to memmove in 371 * standard C. Note this function *does* handle overlapping 372 * source and destination memory locations. 373 374 * Return: None 375 */ 376 void qdf_mem_move(void *dst_addr, const void *src_addr, uint32_t num_bytes); 377 378 /** 379 * qdf_mem_cmp() - memory compare 380 * @left: pointer to one location in memory to compare 381 * @right: pointer to second location in memory to compare 382 * @size: the number of bytes to compare 383 * 384 * Function to compare two pieces of memory, similar to memcmp function 385 * in standard C. 386 * 387 * Return: 388 * 0 -- equal 389 * < 0 -- *memory1 is less than *memory2 390 * > 0 -- *memory1 is bigger than *memory2 391 */ 392 int qdf_mem_cmp(const void *left, const void *right, size_t size); 393 394 void qdf_ether_addr_copy(void *dst_addr, const void *src_addr); 395 396 /** 397 * qdf_mem_map_nbytes_single - Map memory for DMA 398 * @osdev: pomter OS device context 399 * @buf: pointer to memory to be dma mapped 400 * @dir: DMA map direction 401 * @nbytes: number of bytes to be mapped. 402 * @phy_addr: ponter to recive physical address. 403 * 404 * Return: success/failure 405 */ 406 static inline uint32_t qdf_mem_map_nbytes_single(qdf_device_t osdev, void *buf, 407 qdf_dma_dir_t dir, int nbytes, 408 qdf_dma_addr_t *phy_addr) 409 { 410 #if defined(HIF_PCI) 411 return __qdf_mem_map_nbytes_single(osdev, buf, dir, nbytes, phy_addr); 412 #else 413 return 0; 414 #endif 415 } 416 417 /** 418 * qdf_mem_unmap_nbytes_single() - un_map memory for DMA 419 * @osdev: pomter OS device context 420 * @phy_addr: physical address of memory to be dma unmapped 421 * @dir: DMA unmap direction 422 * @nbytes: number of bytes to be unmapped. 423 * 424 * Return: none 425 */ 426 static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev, 427 qdf_dma_addr_t phy_addr, 428 qdf_dma_dir_t dir, 429 int nbytes) 430 { 431 #if defined(HIF_PCI) 432 __qdf_mem_unmap_nbytes_single(osdev, phy_addr, dir, nbytes); 433 #endif 434 } 435 436 /** 437 * qdf_mempool_init - Create and initialize memory pool 438 * @osdev: platform device object 439 * @pool_addr: address of the pool created 440 * @elem_cnt: no. of elements in pool 441 * @elem_size: size of each pool element in bytes 442 * @flags: flags 443 * Return: Handle to memory pool or NULL if allocation failed 444 */ 445 static inline int qdf_mempool_init(qdf_device_t osdev, 446 qdf_mempool_t *pool_addr, int elem_cnt, 447 size_t elem_size, uint32_t flags) 448 { 449 return __qdf_mempool_init(osdev, pool_addr, elem_cnt, elem_size, 450 flags); 451 } 452 453 /** 454 * qdf_mempool_destroy - Destroy memory pool 455 * @osdev: platform device object 456 * @Handle: to memory pool 457 * Return: none 458 */ 459 static inline void qdf_mempool_destroy(qdf_device_t osdev, qdf_mempool_t pool) 460 { 461 __qdf_mempool_destroy(osdev, pool); 462 } 463 464 /** 465 * qdf_mempool_alloc - Allocate an element memory pool 466 * @osdev: platform device object 467 * @Handle: to memory pool 468 * Return: Pointer to the allocated element or NULL if the pool is empty 469 */ 470 static inline void *qdf_mempool_alloc(qdf_device_t osdev, qdf_mempool_t pool) 471 { 472 return (void *)__qdf_mempool_alloc(osdev, pool); 473 } 474 475 /** 476 * qdf_mempool_free - Free a memory pool element 477 * @osdev: Platform device object 478 * @pool: Handle to memory pool 479 * @buf: Element to be freed 480 * Return: none 481 */ 482 static inline void qdf_mempool_free(qdf_device_t osdev, qdf_mempool_t pool, 483 void *buf) 484 { 485 __qdf_mempool_free(osdev, pool, buf); 486 } 487 488 void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, 489 qdf_dma_addr_t bus_addr, 490 qdf_size_t size, 491 __dma_data_direction direction); 492 493 void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, 494 qdf_dma_addr_t bus_addr, 495 qdf_size_t size, 496 __dma_data_direction direction); 497 498 void qdf_mem_multi_pages_alloc(qdf_device_t osdev, 499 struct qdf_mem_multi_page_t *pages, 500 size_t element_size, uint16_t element_num, 501 qdf_dma_context_t memctxt, bool cacheable); 502 void qdf_mem_multi_pages_free(qdf_device_t osdev, 503 struct qdf_mem_multi_page_t *pages, 504 qdf_dma_context_t memctxt, bool cacheable); 505 int qdf_mem_multi_page_link(qdf_device_t osdev, 506 struct qdf_mem_multi_page_t *pages, 507 uint32_t elem_size, uint32_t elem_count, uint8_t cacheable); 508 509 #ifdef WLAN_DEBUGFS 510 511 /** 512 * qdf_mem_kmalloc_inc() - increment kmalloc allocated bytes count 513 * @size: number of bytes to increment by 514 * 515 * Return: None 516 */ 517 void qdf_mem_kmalloc_inc(qdf_size_t size); 518 519 /** 520 * qdf_mem_kmalloc_dec() - decrement kmalloc allocated bytes count 521 * @size: number of bytes to decrement by 522 * 523 * Return: None 524 */ 525 void qdf_mem_kmalloc_dec(qdf_size_t size); 526 527 #else 528 529 static inline void qdf_mem_kmalloc_inc(qdf_size_t size) { } 530 static inline void qdf_mem_kmalloc_dec(qdf_size_t size) { } 531 532 #endif /* WLAN_DEBUGFS */ 533 534 /** 535 * qdf_mem_skb_inc() - increment total skb allocation size 536 * @size: size to be added 537 * 538 * Return: none 539 */ 540 void qdf_mem_skb_inc(qdf_size_t size); 541 542 /** 543 * qdf_mem_skb_dec() - decrement total skb allocation size 544 * @size: size to be decremented 545 * 546 * Return: none 547 */ 548 void qdf_mem_skb_dec(qdf_size_t size); 549 550 /** 551 * qdf_mem_map_table_alloc() - Allocate shared memory info structure 552 * @num: number of required storage 553 * 554 * Allocate mapping table for DMA memory allocation. This is needed for 555 * IPA-WLAN buffer sharing when SMMU Stage1 Translation is enabled. 556 * 557 * Return: shared memory info storage table pointer 558 */ 559 static inline qdf_mem_info_t *qdf_mem_map_table_alloc(uint32_t num) 560 { 561 qdf_mem_info_t *mem_info_arr; 562 563 mem_info_arr = qdf_mem_malloc(num * sizeof(mem_info_arr[0])); 564 return mem_info_arr; 565 } 566 567 /** 568 * qdf_update_mem_map_table() - Update DMA memory map info 569 * @osdev: Parent device instance 570 * @mem_info: Pointer to shared memory information 571 * @dma_addr: dma address 572 * @mem_size: memory size allocated 573 * 574 * Store DMA shared memory information 575 * 576 * Return: none 577 */ 578 static inline void qdf_update_mem_map_table(qdf_device_t osdev, 579 qdf_mem_info_t *mem_info, 580 qdf_dma_addr_t dma_addr, 581 uint32_t mem_size) 582 { 583 if (!mem_info) { 584 __qdf_print("%s: NULL mem_info\n", __func__); 585 return; 586 } 587 588 __qdf_update_mem_map_table(osdev, mem_info, dma_addr, mem_size); 589 } 590 591 /** 592 * qdf_mem_smmu_s1_enabled() - Return SMMU stage 1 translation enable status 593 * @osdev parent device instance 594 * 595 * Return: true if smmu s1 enabled, false if smmu s1 is bypassed 596 */ 597 static inline bool qdf_mem_smmu_s1_enabled(qdf_device_t osdev) 598 { 599 return __qdf_mem_smmu_s1_enabled(osdev); 600 } 601 602 /** 603 * qdf_mem_paddr_from_dmaaddr() - get actual physical address from dma address 604 * @osdev: Parent device instance 605 * @dma_addr: DMA/IOVA address 606 * 607 * Get actual physical address from dma_addr based on SMMU enablement status. 608 * IF SMMU Stage 1 tranlation is enabled, DMA APIs return IO virtual address 609 * (IOVA) otherwise returns physical address. So get SMMU physical address 610 * mapping from IOVA. 611 * 612 * Return: dmaable physical address 613 */ 614 static inline qdf_dma_addr_t qdf_mem_paddr_from_dmaaddr(qdf_device_t osdev, 615 qdf_dma_addr_t dma_addr) 616 { 617 return __qdf_mem_paddr_from_dmaaddr(osdev, dma_addr); 618 } 619 620 /** 621 * qdf_mem_dma_get_sgtable() - Returns DMA memory scatter gather table 622 * @dev: device instace 623 * @sgt: scatter gather table pointer 624 * @cpu_addr: HLOS virtual address 625 * @dma_addr: dma address 626 * @size: allocated memory size 627 * 628 * Return: physical address 629 */ 630 static inline int 631 qdf_mem_dma_get_sgtable(struct device *dev, void *sgt, void *cpu_addr, 632 qdf_dma_addr_t dma_addr, size_t size) 633 { 634 return __qdf_os_mem_dma_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); 635 } 636 637 /** 638 * qdf_mem_free_sgtable() - Free a previously allocated sg table 639 * @sgt: the mapped sg table header 640 * 641 * Return: None 642 */ 643 static inline void 644 qdf_mem_free_sgtable(struct sg_table *sgt) 645 { 646 __qdf_os_mem_free_sgtable(sgt); 647 } 648 649 /** 650 * qdf_dma_get_sgtable_dma_addr() - Assigns DMA address to scatterlist elements 651 * @sgt: scatter gather table pointer 652 * 653 * Return: None 654 */ 655 static inline void 656 qdf_dma_get_sgtable_dma_addr(struct sg_table *sgt) 657 { 658 __qdf_dma_get_sgtable_dma_addr(sgt); 659 } 660 661 /** 662 * qdf_mem_get_dma_addr() - Return dma address based on SMMU translation status. 663 * @osdev: Parent device instance 664 * @mem_info: Pointer to allocated memory information 665 * 666 * Get dma address based on SMMU enablement status. If SMMU Stage 1 667 * tranlation is enabled, DMA APIs return IO virtual address otherwise 668 * returns physical address. 669 * 670 * Return: dma address 671 */ 672 static inline qdf_dma_addr_t qdf_mem_get_dma_addr(qdf_device_t osdev, 673 qdf_mem_info_t *mem_info) 674 { 675 return __qdf_mem_get_dma_addr(osdev, mem_info); 676 } 677 678 /** 679 * qdf_mem_get_dma_addr_ptr() - Return DMA address pointer from mem info struct 680 * @osdev: Parent device instance 681 * @mem_info: Pointer to allocated memory information 682 * 683 * Based on smmu stage 1 translation enablement, return corresponding dma 684 * address storage pointer. 685 * 686 * Return: dma address storage pointer 687 */ 688 static inline qdf_dma_addr_t *qdf_mem_get_dma_addr_ptr(qdf_device_t osdev, 689 qdf_mem_info_t *mem_info) 690 { 691 return __qdf_mem_get_dma_addr_ptr(osdev, mem_info); 692 } 693 694 695 /** 696 * qdf_mem_get_dma_size() - Return DMA memory size 697 * @osdev: parent device instance 698 * @mem_info: Pointer to allocated memory information 699 * 700 * Return: DMA memory size 701 */ 702 static inline uint32_t 703 qdf_mem_get_dma_size(qdf_device_t osdev, 704 qdf_mem_info_t *mem_info) 705 { 706 return __qdf_mem_get_dma_size(osdev, mem_info); 707 } 708 709 /** 710 * qdf_mem_set_dma_size() - Set DMA memory size 711 * @osdev: parent device instance 712 * @mem_info: Pointer to allocated memory information 713 * @mem_size: memory size allocated 714 * 715 * Return: none 716 */ 717 static inline void 718 qdf_mem_set_dma_size(qdf_device_t osdev, 719 qdf_mem_info_t *mem_info, 720 uint32_t mem_size) 721 { 722 __qdf_mem_set_dma_size(osdev, mem_info, mem_size); 723 } 724 725 /** 726 * qdf_mem_get_dma_size() - Return DMA physical address 727 * @osdev: parent device instance 728 * @mem_info: Pointer to allocated memory information 729 * 730 * Return: DMA physical address 731 */ 732 static inline qdf_dma_addr_t 733 qdf_mem_get_dma_pa(qdf_device_t osdev, 734 qdf_mem_info_t *mem_info) 735 { 736 return __qdf_mem_get_dma_pa(osdev, mem_info); 737 } 738 739 /** 740 * qdf_mem_set_dma_size() - Set DMA physical address 741 * @osdev: parent device instance 742 * @mem_info: Pointer to allocated memory information 743 * @dma_pa: DMA phsical address 744 * 745 * Return: none 746 */ 747 static inline void 748 qdf_mem_set_dma_pa(qdf_device_t osdev, 749 qdf_mem_info_t *mem_info, 750 qdf_dma_addr_t dma_pa) 751 { 752 __qdf_mem_set_dma_pa(osdev, mem_info, dma_pa); 753 } 754 755 /** 756 * qdf_mem_shared_mem_alloc() - Allocate DMA memory for shared resource 757 * @osdev: parent device instance 758 * @mem_info: Pointer to allocated memory information 759 * @size: size to be allocated 760 * 761 * Allocate DMA memory which will be shared with external kernel module. This 762 * information is needed for SMMU mapping. 763 * 764 * Return: 0 success 765 */ 766 qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev, uint32_t size); 767 768 /** 769 * qdf_mem_shared_mem_free() - Free shared memory 770 * @osdev: parent device instance 771 * @shared_mem: shared memory information storage 772 * 773 * Free DMA shared memory resource 774 * 775 * Return: None 776 */ 777 static inline void qdf_mem_shared_mem_free(qdf_device_t osdev, 778 qdf_shared_mem_t *shared_mem) 779 { 780 if (!shared_mem) { 781 __qdf_print("%s: NULL shared mem struct passed\n", 782 __func__); 783 return; 784 } 785 786 if (shared_mem->vaddr) { 787 qdf_mem_free_consistent(osdev, osdev->dev, 788 qdf_mem_get_dma_size(osdev, 789 &shared_mem->mem_info), 790 shared_mem->vaddr, 791 qdf_mem_get_dma_addr(osdev, 792 &shared_mem->mem_info), 793 qdf_get_dma_mem_context(shared_mem, 794 memctx)); 795 } 796 qdf_mem_free_sgtable(&shared_mem->sgtable); 797 qdf_mem_free(shared_mem); 798 } 799 800 #endif /* __QDF_MEMORY_H */ 801