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