xref: /dpdk/drivers/net/qede/base/ecore_int_api.h (revision aaffc740ec2cfdb304523c67020f09ad343cfacf)
1 /*
2  * Copyright (c) 2016 QLogic Corporation.
3  * All rights reserved.
4  * www.qlogic.com
5  *
6  * See LICENSE.qede_pmd for copyright and licensing details.
7  */
8 
9 #ifndef __ECORE_INT_API_H__
10 #define __ECORE_INT_API_H__
11 
12 #ifndef __EXTRACT__LINUX__
13 #define ECORE_SB_IDX		0x0002
14 
15 #define RX_PI		0
16 #define TX_PI(tc)	(RX_PI + 1 + tc)
17 
18 #ifndef ECORE_INT_MODE
19 #define ECORE_INT_MODE
20 enum ecore_int_mode {
21 	ECORE_INT_MODE_INTA,
22 	ECORE_INT_MODE_MSIX,
23 	ECORE_INT_MODE_MSI,
24 	ECORE_INT_MODE_POLL,
25 };
26 #endif
27 
28 struct ecore_sb_info {
29 	struct status_block *sb_virt;
30 	dma_addr_t sb_phys;
31 	u32 sb_ack;		/* Last given ack */
32 	u16 igu_sb_id;
33 	void OSAL_IOMEM *igu_addr;
34 	u8 flags;
35 #define ECORE_SB_INFO_INIT	0x1
36 #define ECORE_SB_INFO_SETUP	0x2
37 
38 #ifdef ECORE_CONFIG_DIRECT_HWFN
39 	struct ecore_hwfn *p_hwfn;
40 #endif
41 	struct ecore_dev *p_dev;
42 };
43 
44 struct ecore_sb_cnt_info {
45 	int sb_cnt;
46 	int sb_iov_cnt;
47 	int sb_free_blk;
48 };
49 
50 static OSAL_INLINE u16 ecore_sb_update_sb_idx(struct ecore_sb_info *sb_info)
51 {
52 	u32 prod = 0;
53 	u16 rc = 0;
54 
55 	/* barrier(); status block is written to by the chip */
56 	/* FIXME: need some sort of barrier. */
57 	prod = OSAL_LE32_TO_CPU(sb_info->sb_virt->prod_index) &
58 	    STATUS_BLOCK_PROD_INDEX_MASK;
59 	if (sb_info->sb_ack != prod) {
60 		sb_info->sb_ack = prod;
61 		rc |= ECORE_SB_IDX;
62 	}
63 
64 	OSAL_MMIOWB(sb_info->p_dev);
65 	return rc;
66 }
67 
68 /**
69  *
70  * @brief This function creates an update command for interrupts that is
71  *        written to the IGU.
72  *
73  * @param sb_info	- This is the structure allocated and
74  *	   initialized per status block. Assumption is
75  *	   that it was initialized using ecore_sb_init
76  * @param int_cmd	- Enable/Disable/Nop
77  * @param upd_flg	- whether igu consumer should be
78  *	   updated.
79  *
80  * @return OSAL_INLINE void
81  */
82 static OSAL_INLINE void ecore_sb_ack(struct ecore_sb_info *sb_info,
83 				     enum igu_int_cmd int_cmd, u8 upd_flg)
84 {
85 	struct igu_prod_cons_update igu_ack = { 0 };
86 
87 	igu_ack.sb_id_and_flags =
88 	    ((sb_info->sb_ack << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
89 	     (upd_flg << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
90 	     (int_cmd << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
91 	     (IGU_SEG_ACCESS_REG << IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
92 
93 #ifdef ECORE_CONFIG_DIRECT_HWFN
94 	DIRECT_REG_WR(sb_info->p_hwfn, sb_info->igu_addr,
95 		      igu_ack.sb_id_and_flags);
96 #else
97 	DIRECT_REG_WR(OSAL_NULL, sb_info->igu_addr, igu_ack.sb_id_and_flags);
98 #endif
99 	/* Both segments (interrupts & acks) are written to same place address;
100 	 * Need to guarantee all commands will be received (in-order) by HW.
101 	 */
102 	OSAL_MMIOWB(sb_info->p_dev);
103 	OSAL_BARRIER(sb_info->p_dev);
104 }
105 
106 #ifdef ECORE_CONFIG_DIRECT_HWFN
107 static OSAL_INLINE void __internal_ram_wr(struct ecore_hwfn *p_hwfn,
108 					  void OSAL_IOMEM *addr,
109 					  int size, u32 *data)
110 #else
111 static OSAL_INLINE void __internal_ram_wr(void *p_hwfn,
112 					  void OSAL_IOMEM *addr,
113 					  int size, u32 *data)
114 #endif
115 {
116 	unsigned int i;
117 
118 	for (i = 0; i < size / sizeof(*data); i++)
119 		DIRECT_REG_WR(p_hwfn, &((u32 OSAL_IOMEM *)addr)[i], data[i]);
120 }
121 
122 #ifdef ECORE_CONFIG_DIRECT_HWFN
123 static OSAL_INLINE void internal_ram_wr(struct ecore_hwfn *p_hwfn,
124 					void OSAL_IOMEM *addr,
125 					int size, u32 *data)
126 {
127 	__internal_ram_wr(p_hwfn, addr, size, data);
128 }
129 #else
130 static OSAL_INLINE void internal_ram_wr(void OSAL_IOMEM *addr,
131 					int size, u32 *data)
132 {
133 	__internal_ram_wr(OSAL_NULL, addr, size, data);
134 }
135 #endif
136 #endif
137 
138 struct ecore_hwfn;
139 struct ecore_ptt;
140 
141 enum ecore_coalescing_fsm {
142 	ECORE_COAL_RX_STATE_MACHINE,
143 	ECORE_COAL_TX_STATE_MACHINE
144 };
145 
146 /**
147  * @brief ecore_int_cau_conf_pi - configure cau for a given
148  *        status block
149  *
150  * @param p_hwfn
151  * @param p_ptt
152  * @param igu_sb_id
153  * @param pi_index
154  * @param state
155  * @param timeset
156  */
157 void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
158 			   struct ecore_ptt *p_ptt,
159 			   u16 igu_sb_id,
160 			   u32 pi_index,
161 			   enum ecore_coalescing_fsm coalescing_fsm,
162 			   u8 timeset);
163 
164 /**
165  *
166  * @brief ecore_int_igu_enable_int - enable device interrupts
167  *
168  * @param p_hwfn
169  * @param p_ptt
170  * @param int_mode - interrupt mode to use
171  */
172 void ecore_int_igu_enable_int(struct ecore_hwfn *p_hwfn,
173 			      struct ecore_ptt *p_ptt,
174 			      enum ecore_int_mode int_mode);
175 
176 /**
177  *
178  * @brief ecore_int_igu_disable_int - disable device interrupts
179  *
180  * @param p_hwfn
181  * @param p_ptt
182  */
183 void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
184 			       struct ecore_ptt *p_ptt);
185 
186 /**
187  *
188  * @brief ecore_int_igu_read_sisr_reg - Reads the single isr multiple dpc
189  *        register from igu.
190  *
191  * @param p_hwfn
192  *
193  * @return u64
194  */
195 u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn);
196 
197 #define ECORE_SP_SB_ID 0xffff
198 /**
199  * @brief ecore_int_sb_init - Initializes the sb_info structure.
200  *
201  * once the structure is initialized it can be passed to sb related functions.
202  *
203  * @param p_hwfn
204  * @param p_ptt
205  * @param sb_info	points to an uninitialized (but
206  *			allocated) sb_info structure
207  * @param sb_virt_addr
208  * @param sb_phy_addr
209  * @param sb_id		the sb_id to be used (zero based in driver)
210  *			should use ECORE_SP_SB_ID for SP Status block
211  *
212  * @return enum _ecore_status_t
213  */
214 enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn *p_hwfn,
215 				       struct ecore_ptt *p_ptt,
216 				       struct ecore_sb_info *sb_info,
217 				       void *sb_virt_addr,
218 				       dma_addr_t sb_phy_addr, u16 sb_id);
219 /**
220  * @brief ecore_int_sb_setup - Setup the sb.
221  *
222  * @param p_hwfn
223  * @param p_ptt
224  * @param sb_info	initialized sb_info structure
225  */
226 void ecore_int_sb_setup(struct ecore_hwfn *p_hwfn,
227 			struct ecore_ptt *p_ptt, struct ecore_sb_info *sb_info);
228 
229 /**
230  * @brief ecore_int_sb_release - releases the sb_info structure.
231  *
232  * once the structure is released, it's memory can be freed
233  *
234  * @param p_hwfn
235  * @param sb_info	points to an allocated sb_info structure
236  * @param sb_id		the sb_id to be used (zero based in driver)
237  *			should never be equal to ECORE_SP_SB_ID
238  *			(SP Status block)
239  *
240  * @return enum _ecore_status_t
241  */
242 enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn *p_hwfn,
243 					  struct ecore_sb_info *sb_info,
244 					  u16 sb_id);
245 
246 /**
247  * @brief ecore_int_sp_dpc - To be called when an interrupt is received on the
248  *        default status block.
249  *
250  * @param p_hwfn - pointer to hwfn
251  *
252  */
253 void ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie);
254 
255 /**
256  * @brief ecore_int_get_num_sbs - get the number of status
257  *        blocks configured for this funciton in the igu.
258  *
259  * @param p_hwfn
260  * @param p_sb_cnt_info
261  *
262  * @return
263  */
264 void ecore_int_get_num_sbs(struct ecore_hwfn *p_hwfn,
265 			   struct ecore_sb_cnt_info *p_sb_cnt_info);
266 
267 /**
268  * @brief ecore_int_disable_post_isr_release - performs the cleanup post ISR
269  *        release. The API need to be called after releasing all slowpath IRQs
270  *        of the device.
271  *
272  * @param p_dev
273  *
274  */
275 void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev);
276 
277 /**
278  * @brief ecore_int_attn_clr_enable - sets whether the general behavior is
279  *        preventing attentions from being reasserted, or following the
280  *        attributes of the specific attention.
281  *
282  * @param p_dev
283  * @param clr_enable
284  *
285  */
286 void ecore_int_attn_clr_enable(struct ecore_dev *p_dev, bool clr_enable);
287 
288 #endif
289