Imported Upstream version 16.11
[deb_dpdk.git] / drivers / net / qede / base / ecore_int_api.h
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