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