1 /* 2 * Copyright (c) 2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: i_qdf_nbuf_frag.h 22 * This file provides OS dependent nbuf frag API's. 23 */ 24 25 #ifndef _I_QDF_NBUF_FRAG_H 26 #define _I_QDF_NBUF_FRAG_H 27 28 #include <qdf_net_types.h> 29 #include <qdf_mem.h> 30 31 #define QDF_NBUF_FRAG_DEBUG_COUNT_ZERO 0 32 #define QDF_NBUF_FRAG_DEBUG_COUNT_ONE 1 33 34 /** 35 * typedef __qdf_frag_cache_t - Abstraction for void * for frag address 36 */ 37 typedef struct page_frag_cache __qdf_frag_cache_t; 38 39 /* 40 * typedef __qdf_frag_t - Abstraction for void * for frag address 41 */ 42 typedef void *__qdf_frag_t; 43 44 #ifdef QDF_NBUF_FRAG_GLOBAL_COUNT 45 46 /** 47 * __qdf_frag_count_get() - Get global frag count 48 * 49 * Return: Global frag gauge 50 */ 51 uint32_t __qdf_frag_count_get(void); 52 53 /** 54 * __qdf_frag_count_inc() - Increment frag global count 55 * @value: Increment value 56 * 57 * Return: none 58 */ 59 void __qdf_frag_count_inc(uint32_t value); 60 61 /** 62 * __qdf_frag_count_dec() - Decrement frag global count 63 * @value: Decrement value 64 * 65 * Return: none 66 */ 67 void __qdf_frag_count_dec(uint32_t value); 68 69 /* 70 * __qdf_frag_mod_init() - Initialization routine for qdf_frag 71 * 72 * Return: none 73 */ 74 void __qdf_frag_mod_init(void); 75 76 /** 77 * __qdf_frag_mod_exit() - Uninitialization routine for qdf_frag 78 * 79 * Return: none 80 */ 81 void __qdf_frag_mod_exit(void); 82 83 #else __qdf_frag_count_get(void)84 static inline uint32_t __qdf_frag_count_get(void) 85 { 86 return 0; 87 } 88 __qdf_frag_count_inc(uint32_t value)89 static inline void __qdf_frag_count_inc(uint32_t value) 90 { 91 } 92 __qdf_frag_count_dec(uint32_t value)93 static inline void __qdf_frag_count_dec(uint32_t value) 94 { 95 } 96 __qdf_frag_mod_init(void)97 static inline void __qdf_frag_mod_init(void) 98 { 99 } 100 __qdf_frag_mod_exit(void)101 static inline void __qdf_frag_mod_exit(void) 102 { 103 } 104 #endif /* QDF_NBUF_FRAG_GLOBAL_COUNT */ 105 106 /* 107 * Maximum number of frags an SKB can hold 108 */ 109 #define __QDF_NBUF_MAX_FRAGS MAX_SKB_FRAGS 110 111 /** 112 * __qdf_mem_unmap_page() - Unmap frag memory 113 * @osdev: qdf_device_t 114 * @paddr: Address to be unmapped 115 * @nbytes: Number of bytes to be unmapped 116 * @dir: qdf_dma_dir_t 117 */ 118 void __qdf_mem_unmap_page(qdf_device_t osdev, qdf_dma_addr_t paddr, 119 size_t nbytes, qdf_dma_dir_t dir); 120 121 /** 122 * __qdf_mem_map_page() - Map frag memory 123 * @osdev: qdf_device_t 124 * @buf: Vaddr to be mapped 125 * @dir: qdf_dma_dir_t 126 * @nbytes: Number of bytes to be mapped 127 * @phy_addr: Mapped physical address 128 * 129 * Return: QDF_STATUS 130 */ 131 QDF_STATUS __qdf_mem_map_page(qdf_device_t osdev, __qdf_frag_t buf, 132 qdf_dma_dir_t dir, size_t nbytes, 133 qdf_dma_addr_t *phy_addr); 134 135 /** 136 * __qdf_frag_cache_drain() - Drain page frag cache 137 * @pf_cache: page frag cache 138 * 139 * Return: void 140 */ 141 void __qdf_frag_cache_drain(__qdf_frag_cache_t *pf_cache); 142 143 /** 144 * __qdf_frag_free() - Free allocated frag memory 145 * @vaddr: Frag address to be freed 146 * 147 * Return: none 148 */ __qdf_frag_free(__qdf_frag_t vaddr)149 static inline void __qdf_frag_free(__qdf_frag_t vaddr) 150 { 151 if (qdf_likely(vaddr)) { 152 skb_free_frag(vaddr); 153 __qdf_frag_count_dec(QDF_NBUF_FRAG_DEBUG_COUNT_ONE); 154 } 155 } 156 157 /** 158 * __qdf_frag_alloc() - Allocate frag Memory 159 * @pf_cache: page frag cache 160 * @fragsz: Size of frag memory to be allocated 161 * 162 * Return: Allocated frag addr. 163 */ 164 #if defined(QDF_FRAG_CACHE_SUPPORT) __qdf_frag_alloc(__qdf_frag_cache_t * pf_cache,unsigned int fragsz)165 static inline __qdf_frag_t __qdf_frag_alloc(__qdf_frag_cache_t *pf_cache, 166 unsigned int fragsz) 167 { 168 __qdf_frag_t p_frag; 169 170 if (pf_cache) { 171 unsigned int sz = SKB_DATA_ALIGN(fragsz); 172 173 p_frag = page_frag_alloc(pf_cache, sz, GFP_ATOMIC); 174 } else { 175 p_frag = netdev_alloc_frag(fragsz); 176 } 177 if (p_frag) 178 __qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE); 179 return p_frag; 180 } 181 #else __qdf_frag_alloc(__qdf_frag_cache_t * pf_cache,unsigned int fragsz)182 static inline __qdf_frag_t __qdf_frag_alloc(__qdf_frag_cache_t *pf_cache, 183 unsigned int fragsz) 184 { 185 __qdf_frag_t p_frag = netdev_alloc_frag(fragsz); 186 187 if (p_frag) 188 __qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE); 189 190 return p_frag; 191 } 192 #endif 193 194 #endif /* _I_QDF_NBUF_FRAG_H */ 195