net/qede: use I/O device memory read/write API
[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_relaxed(struct ecore_hwfn *p_hwfn,
124                                                   void OSAL_IOMEM * addr,
125                                                   int size, u32 *data)
126 #else
127 static OSAL_INLINE void __internal_ram_wr_relaxed(void *p_hwfn,
128                                                   void OSAL_IOMEM * addr,
129                                                   int size, u32 *data)
130 #endif
131 {
132         unsigned int i;
133
134         for (i = 0; i < size / sizeof(*data); i++)
135                 DIRECT_REG_WR_RELAXED(p_hwfn, &((u32 OSAL_IOMEM *)addr)[i],
136                                       data[i]);
137 }
138
139 #ifdef ECORE_CONFIG_DIRECT_HWFN
140 static OSAL_INLINE void internal_ram_wr(struct ecore_hwfn *p_hwfn,
141                                                 void OSAL_IOMEM * addr,
142                                                 int size, u32 *data)
143 {
144         __internal_ram_wr_relaxed(p_hwfn, addr, size, data);
145 }
146 #else
147 static OSAL_INLINE void internal_ram_wr(void OSAL_IOMEM *addr,
148                                                 int size, u32 *data)
149 {
150         __internal_ram_wr_relaxed(OSAL_NULL, addr, size, data);
151 }
152 #endif
153
154 #endif
155
156 struct ecore_hwfn;
157 struct ecore_ptt;
158
159 enum ecore_coalescing_fsm {
160         ECORE_COAL_RX_STATE_MACHINE,
161         ECORE_COAL_TX_STATE_MACHINE
162 };
163
164 /**
165  * @brief ecore_int_cau_conf_pi - configure cau for a given
166  *        status block
167  *
168  * @param p_hwfn
169  * @param p_ptt
170  * @param igu_sb_id
171  * @param pi_index
172  * @param state
173  * @param timeset
174  */
175 void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
176                            struct ecore_ptt *p_ptt,
177                            u16 igu_sb_id,
178                            u32 pi_index,
179                            enum ecore_coalescing_fsm coalescing_fsm,
180                            u8 timeset);
181
182 /**
183  *
184  * @brief ecore_int_igu_enable_int - enable device interrupts
185  *
186  * @param p_hwfn
187  * @param p_ptt
188  * @param int_mode - interrupt mode to use
189  */
190 void ecore_int_igu_enable_int(struct ecore_hwfn *p_hwfn,
191                               struct ecore_ptt *p_ptt,
192                               enum ecore_int_mode int_mode);
193
194 /**
195  *
196  * @brief ecore_int_igu_disable_int - disable device interrupts
197  *
198  * @param p_hwfn
199  * @param p_ptt
200  */
201 void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
202                                struct ecore_ptt *p_ptt);
203
204 /**
205  *
206  * @brief ecore_int_igu_read_sisr_reg - Reads the single isr multiple dpc
207  *        register from igu.
208  *
209  * @param p_hwfn
210  *
211  * @return u64
212  */
213 u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn);
214
215 #define ECORE_SP_SB_ID 0xffff
216 /**
217  * @brief ecore_int_sb_init - Initializes the sb_info structure.
218  *
219  * once the structure is initialized it can be passed to sb related functions.
220  *
221  * @param p_hwfn
222  * @param p_ptt
223  * @param sb_info       points to an uninitialized (but
224  *                      allocated) sb_info structure
225  * @param sb_virt_addr
226  * @param sb_phy_addr
227  * @param sb_id         the sb_id to be used (zero based in driver)
228  *                      should use ECORE_SP_SB_ID for SP Status block
229  *
230  * @return enum _ecore_status_t
231  */
232 enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn *p_hwfn,
233                                        struct ecore_ptt *p_ptt,
234                                        struct ecore_sb_info *sb_info,
235                                        void *sb_virt_addr,
236                                        dma_addr_t sb_phy_addr, u16 sb_id);
237 /**
238  * @brief ecore_int_sb_setup - Setup the sb.
239  *
240  * @param p_hwfn
241  * @param p_ptt
242  * @param sb_info       initialized sb_info structure
243  */
244 void ecore_int_sb_setup(struct ecore_hwfn *p_hwfn,
245                         struct ecore_ptt *p_ptt, struct ecore_sb_info *sb_info);
246
247 /**
248  * @brief ecore_int_sb_release - releases the sb_info structure.
249  *
250  * once the structure is released, it's memory can be freed
251  *
252  * @param p_hwfn
253  * @param sb_info       points to an allocated sb_info structure
254  * @param sb_id         the sb_id to be used (zero based in driver)
255  *                      should never be equal to ECORE_SP_SB_ID
256  *                      (SP Status block)
257  *
258  * @return enum _ecore_status_t
259  */
260 enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn *p_hwfn,
261                                           struct ecore_sb_info *sb_info,
262                                           u16 sb_id);
263
264 /**
265  * @brief ecore_int_sp_dpc - To be called when an interrupt is received on the
266  *        default status block.
267  *
268  * @param p_hwfn - pointer to hwfn
269  *
270  */
271 void ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie);
272
273 /**
274  * @brief ecore_int_get_num_sbs - get the number of status
275  *        blocks configured for this funciton in the igu.
276  *
277  * @param p_hwfn
278  * @param p_sb_cnt_info
279  *
280  * @return
281  */
282 void ecore_int_get_num_sbs(struct ecore_hwfn *p_hwfn,
283                            struct ecore_sb_cnt_info *p_sb_cnt_info);
284
285 /**
286  * @brief ecore_int_disable_post_isr_release - performs the cleanup post ISR
287  *        release. The API need to be called after releasing all slowpath IRQs
288  *        of the device.
289  *
290  * @param p_dev
291  *
292  */
293 void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev);
294
295 /**
296  * @brief ecore_int_attn_clr_enable - sets whether the general behavior is
297  *        preventing attentions from being reasserted, or following the
298  *        attributes of the specific attention.
299  *
300  * @param p_dev
301  * @param clr_enable
302  *
303  */
304 void ecore_int_attn_clr_enable(struct ecore_dev *p_dev, bool clr_enable);
305
306 #endif