1 /* 2 * Copyright (c) 2014-2017 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 /** 41 * qdf_align() - align to the given size. 42 * @a: input that needs to be aligned. 43 * @align_size: boundary on which 'a' has to be alinged. 44 * 45 * Return: aligned value. 46 */ 47 #define qdf_align(a, align_size) __qdf_align(a, align_size) 48 49 /** 50 * struct qdf_mem_dma_page_t - Allocated dmaable page 51 * @page_v_addr_start: Page start virtual address 52 * @page_v_addr_end: Page end virtual address 53 * @page_p_addr: Page start physical address 54 */ 55 struct qdf_mem_dma_page_t { 56 char *page_v_addr_start; 57 char *page_v_addr_end; 58 qdf_dma_addr_t page_p_addr; 59 }; 60 61 /** 62 * struct qdf_mem_multi_page_t - multiple page allocation information storage 63 * @num_element_per_page: Number of element in single page 64 * @num_pages: Number of allocation needed pages 65 * @dma_pages: page information storage in case of coherent memory 66 * @cacheable_pages: page information storage in case of cacheable memory 67 */ 68 struct qdf_mem_multi_page_t { 69 uint16_t num_element_per_page; 70 uint16_t num_pages; 71 struct qdf_mem_dma_page_t *dma_pages; 72 void **cacheable_pages; 73 }; 74 75 76 /* Preprocessor definitions and constants */ 77 78 typedef __qdf_mempool_t qdf_mempool_t; 79 #ifdef MEMORY_DEBUG 80 void qdf_mem_clean(void); 81 82 void qdf_mem_init(void); 83 84 void qdf_mem_exit(void); 85 86 #else 87 /** 88 * qdf_mem_init() - initialize qdf memory debug functionality 89 * 90 * Return: none 91 */ 92 static inline void qdf_mem_init(void) 93 { 94 } 95 96 /** 97 * qdf_mem_exit() - exit qdf memory debug functionality 98 * 99 * Return: none 100 */ 101 static inline void qdf_mem_exit(void) 102 { 103 } 104 #endif 105 106 #ifdef MEMORY_DEBUG 107 #define qdf_mem_malloc(size) \ 108 qdf_mem_malloc_debug(size, __FILE__, __LINE__) 109 void *qdf_mem_malloc_debug(size_t size, char *file_name, uint32_t line_num); 110 #else 111 void * 112 qdf_mem_malloc(qdf_size_t size); 113 #endif 114 115 void *qdf_mem_alloc_outline(qdf_device_t osdev, qdf_size_t size); 116 117 /** 118 * qdf_mem_free() - free QDF memory 119 * @ptr: Pointer to the starting address of the memory to be free'd. 120 * This function will free the memory pointed to by 'ptr'. 121 * Return: 122 * None 123 */ 124 void qdf_mem_free(void *ptr); 125 126 void qdf_mem_set(void *ptr, uint32_t num_bytes, uint32_t value); 127 128 void qdf_mem_zero(void *ptr, uint32_t num_bytes); 129 130 void qdf_mem_copy(void *dst_addr, const void *src_addr, uint32_t num_bytes); 131 132 void qdf_mem_move(void *dst_addr, const void *src_addr, uint32_t num_bytes); 133 134 void qdf_mem_free_outline(void *buf); 135 136 void *qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, qdf_size_t size, 137 qdf_dma_addr_t *paddr); 138 139 void qdf_mem_free_consistent(qdf_device_t osdev, void *dev, qdf_size_t size, 140 void *vaddr, qdf_dma_addr_t paddr, 141 qdf_dma_context_t memctx); 142 143 void qdf_mem_zero_outline(void *buf, qdf_size_t size); 144 145 /** 146 * qdf_mem_cmp() - memory compare 147 * @memory1: pointer to one location in memory to compare. 148 * @memory2: pointer to second location in memory to compare. 149 * @num_bytes: the number of bytes to compare. 150 * 151 * Function to compare two pieces of memory, similar to memcmp function 152 * in standard C. 153 * Return: 154 * int32_t - returns an int value that tells if the memory 155 * locations are equal or not equal. 156 * 0 -- equal 157 * < 0 -- *memory1 is less than *memory2 158 * > 0 -- *memory1 is bigger than *memory2 159 */ 160 static inline int32_t qdf_mem_cmp(const void *memory1, const void *memory2, 161 uint32_t num_bytes) 162 { 163 return __qdf_mem_cmp(memory1, memory2, num_bytes); 164 } 165 166 /** 167 * qdf_str_cmp - Compare two strings 168 * @str1: First string 169 * @str2: Second string 170 * Return: =0 equal 171 * >0 not equal, if str1 sorts lexicographically after str2 172 * <0 not equal, if str1 sorts lexicographically before str2 173 */ 174 static inline int32_t qdf_str_cmp(const char *str1, const char *str2) 175 { 176 return __qdf_str_cmp(str1, str2); 177 } 178 179 /** 180 * qdf_str_lcopy - Copy from one string to another 181 * @dest: destination string 182 * @src: source string 183 * @bytes: limit of num bytes to copy 184 * Return: =0 returns the initial value of dest 185 */ 186 static inline uint32_t qdf_str_lcopy(char *dest, const char *src, uint32_t bytes) 187 { 188 return __qdf_str_lcopy(dest, src, bytes); 189 } 190 191 /** 192 * qdf_mem_map_nbytes_single - Map memory for DMA 193 * @osdev: pomter OS device context 194 * @buf: pointer to memory to be dma mapped 195 * @dir: DMA map direction 196 * @nbytes: number of bytes to be mapped. 197 * @phy_addr: ponter to recive physical address. 198 * 199 * Return: success/failure 200 */ 201 static inline uint32_t qdf_mem_map_nbytes_single(qdf_device_t osdev, void *buf, 202 qdf_dma_dir_t dir, int nbytes, 203 qdf_dma_addr_t *phy_addr) 204 { 205 #if defined(HIF_PCI) 206 return __qdf_mem_map_nbytes_single(osdev, buf, dir, nbytes, phy_addr); 207 #else 208 return 0; 209 #endif 210 } 211 212 /** 213 * qdf_mem_unmap_nbytes_single() - un_map memory for DMA 214 * @osdev: pomter OS device context 215 * @phy_addr: physical address of memory to be dma unmapped 216 * @dir: DMA unmap direction 217 * @nbytes: number of bytes to be unmapped. 218 * 219 * Return: none 220 */ 221 static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev, 222 qdf_dma_addr_t phy_addr, 223 qdf_dma_dir_t dir, 224 int nbytes) 225 { 226 #if defined(HIF_PCI) 227 __qdf_mem_unmap_nbytes_single(osdev, phy_addr, dir, nbytes); 228 #endif 229 } 230 231 /** 232 * qdf_mempool_init - Create and initialize memory pool 233 * @osdev: platform device object 234 * @pool_addr: address of the pool created 235 * @elem_cnt: no. of elements in pool 236 * @elem_size: size of each pool element in bytes 237 * @flags: flags 238 * Return: Handle to memory pool or NULL if allocation failed 239 */ 240 static inline int qdf_mempool_init(qdf_device_t osdev, 241 qdf_mempool_t *pool_addr, int elem_cnt, 242 size_t elem_size, uint32_t flags) 243 { 244 return __qdf_mempool_init(osdev, pool_addr, elem_cnt, elem_size, 245 flags); 246 } 247 248 /** 249 * qdf_mempool_destroy - Destroy memory pool 250 * @osdev: platform device object 251 * @Handle: to memory pool 252 * Return: none 253 */ 254 static inline void qdf_mempool_destroy(qdf_device_t osdev, qdf_mempool_t pool) 255 { 256 __qdf_mempool_destroy(osdev, pool); 257 } 258 259 /** 260 * qdf_mempool_alloc - Allocate an element memory pool 261 * @osdev: platform device object 262 * @Handle: to memory pool 263 * Return: Pointer to the allocated element or NULL if the pool is empty 264 */ 265 static inline void *qdf_mempool_alloc(qdf_device_t osdev, qdf_mempool_t pool) 266 { 267 return (void *)__qdf_mempool_alloc(osdev, pool); 268 } 269 270 /** 271 * qdf_mempool_free - Free a memory pool element 272 * @osdev: Platform device object 273 * @pool: Handle to memory pool 274 * @buf: Element to be freed 275 * Return: none 276 */ 277 static inline void qdf_mempool_free(qdf_device_t osdev, qdf_mempool_t pool, 278 void *buf) 279 { 280 __qdf_mempool_free(osdev, pool, buf); 281 } 282 283 void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, 284 qdf_dma_addr_t bus_addr, 285 qdf_size_t size, 286 __dma_data_direction direction); 287 288 void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, 289 qdf_dma_addr_t bus_addr, 290 qdf_size_t size, 291 __dma_data_direction direction); 292 /** 293 * qdf_str_len() - returns the length of a string 294 * @str: input string 295 * Return: 296 * length of string 297 */ 298 static inline int32_t qdf_str_len(const char *str) 299 { 300 return __qdf_str_len(str); 301 } 302 303 void qdf_mem_multi_pages_alloc(qdf_device_t osdev, 304 struct qdf_mem_multi_page_t *pages, 305 size_t element_size, uint16_t element_num, 306 qdf_dma_context_t memctxt, bool cacheable); 307 void qdf_mem_multi_pages_free(qdf_device_t osdev, 308 struct qdf_mem_multi_page_t *pages, 309 qdf_dma_context_t memctxt, bool cacheable); 310 int qdf_mem_multi_page_link(qdf_device_t osdev, 311 struct qdf_mem_multi_page_t *pages, 312 uint32_t elem_size, uint32_t elem_count, uint8_t cacheable); 313 314 #endif /* __QDF_MEMORY_H */ 315