1 /* 2 * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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 #ifndef __HIF_NAPI_H__ 21 #define __HIF_NAPI_H__ 22 23 /** 24 * DOC: hif_napi.h 25 * 26 * Interface to HIF implemented functions of NAPI. 27 * These are used by hdd_napi. 28 */ 29 30 31 /* CLD headers */ 32 #include <hif.h> /* struct hif_opaque_softc; */ 33 34 /** 35 * common stuff 36 * The declarations until #ifdef FEATURE_NAPI below 37 * are valid whether or not FEATURE_NAPI has been 38 * defined. 39 */ 40 41 /** 42 * NAPI manages the following states: 43 * NAPI state: per NAPI instance, ENABLED/DISABLED 44 * CPU state: per CPU, DOWN/UP 45 * TPUT state: global, LOW/HI 46 * 47 * "Dynamic" changes to state of various NAPI structures are 48 * managed by NAPI events. The events may be produced by 49 * various detection points. With each event, some data is 50 * sent. The main event handler in hif_napi handles and makes 51 * the state changes. 52 * 53 * event : data : generated 54 * ---------------:------------------:------------------ 55 * EVT_INI_FILE : cfg->napi_enable : after ini file processed 56 * EVT_CMD_STATE : cmd arg : by the vendor cmd 57 * EVT_INT_STATE : 0 : internal - shut off/disable 58 * EVT_CPU_STATE : (cpu << 16)|state: CPU hotplug events 59 * EVT_TPUT_STATE : (high/low) : tput trigger 60 * EVT_USR_SERIAL : num-serial_calls : WMA/ROAMING-START/IND 61 * EVT_USR_NORMAL : N/A : WMA/ROAMING-END 62 */ 63 enum qca_napi_event { 64 NAPI_EVT_INVALID, 65 NAPI_EVT_INI_FILE, 66 NAPI_EVT_CMD_STATE, 67 NAPI_EVT_INT_STATE, 68 NAPI_EVT_CPU_STATE, 69 NAPI_EVT_TPUT_STATE, 70 NAPI_EVT_USR_SERIAL, 71 NAPI_EVT_USR_NORMAL 72 }; 73 /** 74 * Following are some of NAPI related features controlled using feature flag 75 * These flags need to be enabled in the qca_napi_data->flags variable for the 76 * feature to kick in. 77 .* QCA_NAPI_FEATURE_CPU_CORRECTION - controls CPU correction logic 78 .* QCA_NAPI_FEATURE_IRQ_BLACKLISTING - controls call to irq_denylist_on API 79 .* QCA_NAPI_FEATURE_CORE_CTL_BOOST - controls call to core_ctl_set_boost API 80 */ 81 #define QCA_NAPI_FEATURE_CPU_CORRECTION BIT(1) 82 #define QCA_NAPI_FEATURE_IRQ_BLACKLISTING BIT(2) 83 #define QCA_NAPI_FEATURE_CORE_CTL_BOOST BIT(3) 84 85 /** 86 * Macros to map ids -returned by ...create()- to pipes and vice versa 87 */ 88 #define NAPI_ID2PIPE(i) ((i)-1) 89 #define NAPI_PIPE2ID(p) ((p)+1) 90 91 #ifdef RECEIVE_OFFLOAD 92 /** 93 * hif_napi_rx_offld_flush_cb_register() - Register flush callback for Rx offld 94 * @hif_hdl: pointer to hif context 95 * @offld_flush_handler: register offld flush callback 96 * 97 * Return: None 98 */ 99 void hif_napi_rx_offld_flush_cb_register(struct hif_opaque_softc *hif_hdl, 100 void (rx_ol_flush_handler)(void *arg)); 101 102 /** 103 * hif_napi_rx_offld_flush_cb_deregister() - Degregister offld flush_cb 104 * @hif_hdl: pointer to hif context 105 * 106 * Return: NONE 107 */ 108 void hif_napi_rx_offld_flush_cb_deregister(struct hif_opaque_softc *hif_hdl); 109 #endif /* RECEIVE_OFFLOAD */ 110 111 /** 112 * hif_napi_get_lro_info() - returns the address LRO data for napi_id 113 * @hif: pointer to hif context 114 * @napi_id: napi instance 115 * 116 * Description: 117 * Returns the address of the LRO structure 118 * 119 * Return: 120 * <addr>: address of the LRO structure 121 */ 122 void *hif_napi_get_lro_info(struct hif_opaque_softc *hif_hdl, int napi_id); 123 124 enum qca_denylist_op { 125 DENYLIST_QUERY, 126 DENYLIST_OFF, 127 DENYLIST_ON 128 }; 129 130 #ifdef FEATURE_NAPI 131 132 /** 133 * NAPI HIF API 134 * 135 * the declarations below only apply to the case 136 * where FEATURE_NAPI is defined 137 */ 138 139 int hif_napi_create(struct hif_opaque_softc *hif, 140 int (*poll)(struct napi_struct *, int), 141 int budget, 142 int scale, 143 uint8_t flags); 144 int hif_napi_destroy(struct hif_opaque_softc *hif, 145 uint8_t id, 146 int force); 147 148 struct qca_napi_data *hif_napi_get_all(struct hif_opaque_softc *hif); 149 150 /** 151 * hif_get_napi() - get NAPI corresponding to napi_id 152 * @napi_id: NAPI instance 153 * @napid: Handle NAPI 154 * 155 * Return: napi corresponding napi_id 156 */ 157 struct qca_napi_info *hif_get_napi(int napi_id, struct qca_napi_data *napid); 158 159 int hif_napi_event(struct hif_opaque_softc *hif, 160 enum qca_napi_event event, 161 void *data); 162 163 /* called from the ISR within hif, so, ce is known */ 164 int hif_napi_enabled(struct hif_opaque_softc *hif, int ce); 165 166 bool hif_napi_created(struct hif_opaque_softc *hif, int ce); 167 168 /* called from hdd (napi_poll), using napi id as a selector */ 169 void hif_napi_enable_irq(struct hif_opaque_softc *hif, int id); 170 171 /* called by ce_tasklet.c::ce_dispatch_interrupt*/ 172 bool hif_napi_schedule(struct hif_opaque_softc *scn, int ce_id); 173 174 /* called by hdd_napi, which is called by kernel */ 175 int hif_napi_poll(struct hif_opaque_softc *hif_ctx, 176 struct napi_struct *napi, int budget); 177 178 #ifdef FEATURE_NAPI_DEBUG 179 #define NAPI_DEBUG(fmt, ...) \ 180 qdf_debug("wlan: NAPI: %s:%d "fmt, __func__, __LINE__, ##__VA_ARGS__) 181 #else 182 #define NAPI_DEBUG(fmt, ...) /* NO-OP */ 183 #endif /* FEATURE NAPI_DEBUG */ 184 185 #define HNC_ANY_CPU (-1) 186 #define HNC_ACT_RELOCATE (0) 187 #define HNC_ACT_COLLAPSE (1) 188 #define HNC_ACT_DISPERSE (-1) 189 190 /** 191 * hif_update_napi_max_poll_time() - updates NAPI max poll time 192 * @ce_state: ce state 193 * @ce_id: Copy engine ID 194 * @cpu_id: cpu id 195 * 196 * This API updates NAPI max poll time per CE per SPU. 197 * 198 * Return: void 199 */ 200 void hif_update_napi_max_poll_time(struct CE_state *ce_state, 201 int ce_id, 202 int cpu_id); 203 /** 204 * Local interface to HIF implemented functions of NAPI CPU affinity management. 205 * Note: 206 * 1- The symbols in this file are NOT supposed to be used by any 207 * entity other than hif_napi.c 208 * 2- The symbols are valid only if HELIUMPLUS is defined. They are otherwise 209 * mere wrappers. 210 * 211 */ 212 213 #else /* ! defined(FEATURE_NAPI) */ 214 215 /** 216 * Stub API 217 * 218 * The declarations in this section are valid only 219 * when FEATURE_NAPI has *not* been defined. 220 */ 221 222 #define NAPI_DEBUG(fmt, ...) /* NO-OP */ 223 224 static inline int hif_napi_create(struct hif_opaque_softc *hif, 225 uint8_t pipe_id, 226 int (*poll)(struct napi_struct *, int), 227 int budget, 228 int scale, 229 uint8_t flags) 230 { return -EPERM; } 231 232 static inline int hif_napi_destroy(struct hif_opaque_softc *hif, 233 uint8_t id, 234 int force) 235 { return -EPERM; } 236 237 static inline struct qca_napi_data *hif_napi_get_all( 238 struct hif_opaque_softc *hif) 239 { return NULL; } 240 241 static inline struct qca_napi_info *hif_get_napi(int napi_id, 242 struct qca_napi_data *napid) 243 { return NULL; } 244 245 static inline int hif_napi_event(struct hif_opaque_softc *hif, 246 enum qca_napi_event event, 247 void *data) 248 { return -EPERM; } 249 250 /* called from the ISR within hif, so, ce is known */ 251 static inline int hif_napi_enabled(struct hif_opaque_softc *hif, int ce) 252 { return 0; } 253 254 static inline bool hif_napi_created(struct hif_opaque_softc *hif, int ce) 255 { return false; } 256 257 /* called from hdd (napi_poll), using napi id as a selector */ 258 static inline void hif_napi_enable_irq(struct hif_opaque_softc *hif, int id) 259 { return; } 260 261 static inline bool hif_napi_schedule(struct hif_opaque_softc *hif, int ce_id) 262 { return false; } 263 264 static inline int hif_napi_poll(struct napi_struct *napi, int budget) 265 { return -EPERM; } 266 267 /** 268 * hif_update_napi_max_poll_time() - updates NAPI max poll time 269 * @ce_state: ce state 270 * @ce_id: Copy engine ID 271 * @cpu_id: cpu id 272 * 273 * This API updates NAPI max poll time per CE per SPU. 274 * 275 * Return: void 276 */ 277 static inline void hif_update_napi_max_poll_time(struct CE_state *ce_state, 278 int ce_id, 279 int cpu_id) 280 { return; } 281 #endif /* FEATURE_NAPI */ 282 283 #if defined(HIF_IRQ_AFFINITY) && defined(FEATURE_NAPI) 284 /* 285 * prototype signatures 286 */ 287 int hif_napi_cpu_init(struct hif_opaque_softc *hif); 288 int hif_napi_cpu_deinit(struct hif_opaque_softc *hif); 289 290 int hif_napi_cpu_migrate(struct qca_napi_data *napid, int cpu, int action); 291 int hif_napi_serialize(struct hif_opaque_softc *hif, int is_on); 292 293 int hif_napi_cpu_denylist(struct qca_napi_data *napid, 294 enum qca_denylist_op op); 295 296 /* not directly related to irq affinity, but oh well */ 297 void hif_napi_stats(struct qca_napi_data *napid); 298 void hif_napi_update_yield_stats(struct CE_state *ce_state, 299 bool time_limit_reached, 300 bool rxpkt_thresh_reached); 301 #else 302 struct qca_napi_data; 303 static inline int hif_napi_cpu_init(struct hif_opaque_softc *hif) 304 { return 0; } 305 306 static inline int hif_napi_cpu_deinit(struct hif_opaque_softc *hif) 307 { return 0; } 308 309 static inline int hif_napi_cpu_migrate(struct qca_napi_data *napid, int cpu, 310 int action) 311 { return 0; } 312 313 static inline int hif_napi_serialize(struct hif_opaque_softc *hif, int is_on) 314 { return -EPERM; } 315 316 static inline void hif_napi_stats(struct qca_napi_data *napid) { } 317 static inline void hif_napi_update_yield_stats(struct CE_state *ce_state, 318 bool time_limit_reached, 319 bool rxpkt_thresh_reached) { } 320 321 static inline int hif_napi_cpu_denylist(struct qca_napi_data *napid, 322 enum qca_denylist_op op) 323 { return 0; } 324 #endif /* HIF_IRQ_AFFINITY */ 325 326 #endif /* __HIF_NAPI_H__ */ 327