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