xref: /illumos-gate/usr/src/uts/common/io/qede/579xx/drivers/ecore/ecore_int_api.h (revision 14b24e2b79293068c8e016a69ef1d872fb5e2fd5)
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, v.1,  (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 
22 /*
23 * Copyright 2014-2017 Cavium, Inc.
24 * The contents of this file are subject to the terms of the Common Development
25 * and Distribution License, v.1,  (the "License").
26 
27 * You may not use this file except in compliance with the License.
28 
29 * You can obtain a copy of the License at available
30 * at http://opensource.org/licenses/CDDL-1.0
31 
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35 
36 #ifndef __ECORE_INT_API_H__
37 #define __ECORE_INT_API_H__
38 
39 #ifndef __EXTRACT__LINUX__
40 #define ECORE_SB_IDX		0x0002
41 
42 #define RX_PI		0
43 #define TX_PI(tc)	(RX_PI + 1 + tc)
44 
45 #ifndef ECORE_INT_MODE
46 #define ECORE_INT_MODE
47 enum ecore_int_mode {
48 	ECORE_INT_MODE_INTA,
49 	ECORE_INT_MODE_MSIX,
50 	ECORE_INT_MODE_MSI,
51 	ECORE_INT_MODE_POLL,
52 };
53 #endif
54 
55 struct ecore_sb_info {
56 	struct status_block *sb_virt;
57 	dma_addr_t sb_phys;
58 	u32 sb_ack; /* Last given ack */
59 	u16 igu_sb_id;
60 	void OSAL_IOMEM *igu_addr;
61 	u8 flags;
62 #define ECORE_SB_INFO_INIT 	0x1
63 #define ECORE_SB_INFO_SETUP 	0x2
64 
65 #ifdef ECORE_CONFIG_DIRECT_HWFN
66 	struct ecore_hwfn *p_hwfn;
67 #endif
68 	struct ecore_dev *p_dev;
69 };
70 
71 struct ecore_sb_info_dbg {
72 	u32 igu_prod;
73 	u32 igu_cons;
74 	u16 pi[PIS_PER_SB];
75 };
76 
77 struct ecore_sb_cnt_info {
78 	/* Original, current, and free SBs for PF */
79 	int orig;
80 	int cnt;
81 	int free_cnt;
82 
83 	/* Original, current and free SBS for child VFs */
84 	int iov_orig;
85 	int iov_cnt;
86 	int free_cnt_iov;
87 };
88 
ecore_sb_update_sb_idx(struct ecore_sb_info * sb_info)89 static OSAL_INLINE u16 ecore_sb_update_sb_idx(struct ecore_sb_info *sb_info)
90 {
91 	u32 prod = 0;
92 	u16 rc   = 0;
93 
94 	// barrier(); /* status block is written to by the chip */
95 	// FIXME: need some sort of barrier.
96 	prod = OSAL_LE32_TO_CPU(sb_info->sb_virt->prod_index) &
97 	       STATUS_BLOCK_PROD_INDEX_MASK;
98 	if (sb_info->sb_ack != prod) {
99 		sb_info->sb_ack = prod;
100 		rc |= ECORE_SB_IDX;
101 	}
102 
103 	OSAL_MMIOWB(sb_info->p_dev);
104 	return rc;
105 }
106 
107 /**
108  * @brief This function creates an update command for interrupts that is
109  *        written to the IGU.
110  *
111  * @param sb_info 	- This is the structure allocated and
112  *      	   initialized per status block. Assumption is
113  *      	   that it was initialized using ecore_sb_init
114  * @param int_cmd 	- Enable/Disable/Nop
115  * @param upd_flg 	- whether igu consumer should be
116  *      	   updated.
117  *
118  * @return OSAL_INLINE void
119  */
ecore_sb_ack(struct ecore_sb_info * sb_info,enum igu_int_cmd int_cmd,u8 upd_flg)120 static OSAL_INLINE void ecore_sb_ack(struct ecore_sb_info *sb_info,
121 				     enum igu_int_cmd int_cmd, u8 upd_flg)
122 {
123 	struct igu_prod_cons_update igu_ack = { 0 };
124 
125 	igu_ack.sb_id_and_flags =
126 		((sb_info->sb_ack << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
127 		 (upd_flg << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
128 		 (int_cmd << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
129 		 (IGU_SEG_ACCESS_REG <<
130 		  IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
131 
132 #ifdef ECORE_CONFIG_DIRECT_HWFN
133 	DIRECT_REG_WR(sb_info->p_hwfn, sb_info->igu_addr,
134 		      igu_ack.sb_id_and_flags);
135 #else
136 	DIRECT_REG_WR(OSAL_NULL, sb_info->igu_addr, igu_ack.sb_id_and_flags);
137 #endif
138 	/* Both segments (interrupts & acks) are written to same place address;
139 	 * Need to guarantee all commands will be received (in-order) by HW.
140 	 */
141 	OSAL_MMIOWB(sb_info->p_dev);
142 	OSAL_BARRIER(sb_info->p_dev);
143 }
144 
145 #ifdef ECORE_CONFIG_DIRECT_HWFN
__internal_ram_wr(struct ecore_hwfn * p_hwfn,void OSAL_IOMEM * addr,int size,u32 * data)146 static OSAL_INLINE void __internal_ram_wr(struct ecore_hwfn *p_hwfn,
147 					  void OSAL_IOMEM *addr,
148 					  int size, u32 *data)
149 #else
150 static OSAL_INLINE void __internal_ram_wr(void *p_hwfn,
151 					  void OSAL_IOMEM *addr,
152 					  int size, u32 *data)
153 
154 #endif
155 {
156 	unsigned int i;
157 
158 	for (i = 0; i < size / sizeof(*data); i++)
159 		DIRECT_REG_WR(p_hwfn, &((u32 OSAL_IOMEM *)addr)[i], data[i]);
160 }
161 
162 #ifdef ECORE_CONFIG_DIRECT_HWFN
internal_ram_wr(struct ecore_hwfn * p_hwfn,void OSAL_IOMEM * addr,int size,u32 * data)163 static OSAL_INLINE void internal_ram_wr(struct ecore_hwfn *p_hwfn,
164 					void OSAL_IOMEM *addr,
165 					int size, u32 *data)
166 {
167 	__internal_ram_wr(p_hwfn, addr, size, data);
168 }
169 #else
internal_ram_wr(void OSAL_IOMEM * addr,int size,u32 * data)170 static OSAL_INLINE void internal_ram_wr(void OSAL_IOMEM *addr,
171 					int size, u32 *data)
172 {
173 	__internal_ram_wr(OSAL_NULL, addr, size, data);
174 }
175 #endif
176 #endif
177 
178 struct ecore_hwfn;
179 struct ecore_ptt;
180 
181 enum ecore_coalescing_fsm {
182 	ECORE_COAL_RX_STATE_MACHINE,
183 	ECORE_COAL_TX_STATE_MACHINE
184 };
185 
186 /**
187  * @brief ecore_int_cau_conf_pi - configure cau for a given
188  *        status block
189  *
190  * @param p_hwfn
191  * @param p_ptt
192  * @param p_sb
193  * @param pi_index
194  * @param state
195  * @param timeset
196  */
197 void ecore_int_cau_conf_pi(struct ecore_hwfn		*p_hwfn,
198 			   struct ecore_ptt		*p_ptt,
199 			   struct ecore_sb_info		*p_sb,
200 			   u32				pi_index,
201 			   enum ecore_coalescing_fsm	coalescing_fsm,
202 			   u8				timeset);
203 
204 /**
205  * @brief ecore_int_igu_enable_int - enable device interrupts
206  *
207  * @param p_hwfn
208  * @param p_ptt
209  * @param int_mode - interrupt mode to use
210  */
211 void ecore_int_igu_enable_int(struct ecore_hwfn *p_hwfn,
212 			      struct ecore_ptt *p_ptt,
213 			      enum ecore_int_mode int_mode);
214 
215 /**
216  * @brief ecore_int_igu_disable_int - disable device interrupts
217  *
218  * @param p_hwfn
219  * @param p_ptt
220  */
221 void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
222 			       struct ecore_ptt	*p_ptt);
223 
224 /**
225  * @brief ecore_int_igu_read_sisr_reg - Reads the single isr multiple dpc
226  *        register from igu.
227  *
228  * @param p_hwfn
229  *
230  * @return u64
231  */
232 u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn);
233 
234 #define ECORE_SP_SB_ID 0xffff
235 
236 /**
237  * @brief ecore_int_sb_init - Initializes the sb_info structure.
238  *
239  * once the structure is initialized it can be passed to sb related functions.
240  *
241  * @param p_hwfn
242  * @param p_ptt
243  * @param sb_info	points to an uninitialized (but
244  *			allocated) sb_info structure
245  * @param sb_virt_addr
246  * @param sb_phy_addr
247  * @param sb_id		the sb_id to be used (zero based in driver)
248  *			should use ECORE_SP_SB_ID for SP Status block
249  *
250  * @return enum _ecore_status_t
251  */
252 enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn	*p_hwfn,
253 				       struct ecore_ptt		*p_ptt,
254 				       struct ecore_sb_info	*sb_info,
255 				       void			*sb_virt_addr,
256 				       dma_addr_t		sb_phy_addr,
257 				       u16			sb_id);
258 /**
259  * @brief ecore_int_sb_setup - Setup the sb.
260  *
261  * @param p_hwfn
262  * @param p_ptt
263  * @param sb_info	initialized sb_info structure
264  */
265 void ecore_int_sb_setup(
266 		struct ecore_hwfn	*p_hwfn,
267 		struct ecore_ptt		*p_ptt,
268 		struct ecore_sb_info	*sb_info);
269 
270 /**
271  * @brief ecore_int_sb_release - releases the sb_info structure.
272  *
273  * once the structure is released, it's memory can be freed
274  *
275  * @param p_hwfn
276  * @param sb_info	points to an allocated sb_info structure
277  * @param sb_id		the sb_id to be used (zero based in driver)
278  *			should never be equal to ECORE_SP_SB_ID
279  *			(SP Status block)
280  *
281  * @return enum _ecore_status_t
282  */
283 enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn	*p_hwfn,
284 					  struct ecore_sb_info	*sb_info,
285 					  u16			sb_id);
286 
287 /**
288  * @brief ecore_int_sp_dpc - To be called when an interrupt is received on the
289  *        default status block.
290  *
291  * @param p_hwfn - pointer to hwfn
292  *
293  */
294 void ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie);
295 
296 /**
297  * @brief ecore_int_get_num_sbs - get the number of status
298  *        blocks configured for this funciton in the igu.
299  *
300  * @param p_hwfn
301  * @param p_sb_cnt_info
302  *
303  * @return
304  */
305 void ecore_int_get_num_sbs(struct ecore_hwfn	    *p_hwfn,
306 			   struct ecore_sb_cnt_info *p_sb_cnt_info);
307 
308 /**
309  * @brief ecore_int_disable_post_isr_release - performs the cleanup post ISR
310  *        release. The API need to be called after releasing all slowpath IRQs
311  *        of the device.
312  *
313  * @param p_dev
314  *
315  */
316 void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev);
317 
318 /**
319  * @brief ecore_int_attn_clr_enable - sets whether the general behavior is
320  *        preventing attentions from being reasserted, or following the
321  *        attributes of the specific attention.
322  *
323  * @param p_dev
324  * @param clr_enable
325  *
326  */
327 void ecore_int_attn_clr_enable(struct ecore_dev *p_dev, bool clr_enable);
328 
329 /**
330  * @brief Read debug information regarding a given SB.
331  *
332  * @param p_hwfn
333  * @param p_ptt
334  * @param p_sb - point to Status block for which we want to get info.
335  * @param p_info - pointer to struct to fill with information regarding SB.
336  *
337  * @return ECORE_SUCCESS if pointer is filled; failure otherwise.
338  */
339 enum _ecore_status_t ecore_int_get_sb_dbg(struct ecore_hwfn *p_hwfn,
340 					  struct ecore_ptt *p_ptt,
341 					  struct ecore_sb_info *p_sb,
342 					  struct ecore_sb_info_dbg *p_info);
343 
344 /**
345  * @brief - Move a free Status block between PF and child VF
346  *
347  * @param p_hwfn
348  * @param p_ptt
349  * @param sb_id - The PF fastpath vector to be moved [re-assigned if claiming
350  *                from VF, given-up if moving to VF]
351  * @param b_to_vf - PF->VF == true, VF->PF == false
352  *
353  * @return ECORE_SUCCESS if SB successfully moved.
354  */
355 enum _ecore_status_t
356 ecore_int_igu_relocate_sb(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
357 			  u16 sb_id, bool b_to_vf);
358 #endif
359