1 /* 2 * Copyright (c) 2017-2018 Cavium, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 * 29 */ 30 31 #ifndef __ECORE_INT_API_H__ 32 #define __ECORE_INT_API_H__ 33 34 #include "common_hsi.h" 35 36 #ifndef __EXTRACT__LINUX__ 37 #define ECORE_SB_IDX 0x0002 38 39 #define RX_PI 0 40 #define TX_PI(tc) (RX_PI + 1 + tc) 41 42 #ifndef ECORE_INT_MODE 43 #define ECORE_INT_MODE 44 enum ecore_int_mode { 45 ECORE_INT_MODE_INTA, 46 ECORE_INT_MODE_MSIX, 47 ECORE_INT_MODE_MSI, 48 ECORE_INT_MODE_POLL, 49 }; 50 #endif 51 52 struct ecore_sb_info { 53 struct status_block_e4 *sb_virt; 54 dma_addr_t sb_phys; 55 u32 sb_ack; /* Last given ack */ 56 u16 igu_sb_id; 57 void OSAL_IOMEM *igu_addr; 58 u8 flags; 59 #define ECORE_SB_INFO_INIT 0x1 60 #define ECORE_SB_INFO_SETUP 0x2 61 62 #ifdef ECORE_CONFIG_DIRECT_HWFN 63 struct ecore_hwfn *p_hwfn; 64 #endif 65 struct ecore_dev *p_dev; 66 }; 67 68 struct ecore_sb_info_dbg { 69 u32 igu_prod; 70 u32 igu_cons; 71 u16 pi[PIS_PER_SB_E4]; 72 }; 73 74 struct ecore_sb_cnt_info { 75 /* Original, current, and free SBs for PF */ 76 int orig; 77 int cnt; 78 int free_cnt; 79 80 /* Original, current and free SBS for child VFs */ 81 int iov_orig; 82 int iov_cnt; 83 int free_cnt_iov; 84 }; 85 86 static OSAL_INLINE u16 ecore_sb_update_sb_idx(struct ecore_sb_info *sb_info) 87 { 88 u32 prod = 0; 89 u16 rc = 0; 90 91 // barrier(); /* status block is written to by the chip */ 92 // FIXME: need some sort of barrier. 93 prod = OSAL_LE32_TO_CPU(sb_info->sb_virt->prod_index) & 94 STATUS_BLOCK_E4_PROD_INDEX_MASK; 95 if (sb_info->sb_ack != prod) { 96 sb_info->sb_ack = prod; 97 rc |= ECORE_SB_IDX; 98 } 99 100 OSAL_MMIOWB(sb_info->p_dev); 101 return rc; 102 } 103 104 /** 105 * @brief This function creates an update command for interrupts that is 106 * written to the IGU. 107 * 108 * @param sb_info - This is the structure allocated and 109 * initialized per status block. Assumption is 110 * that it was initialized using ecore_sb_init 111 * @param int_cmd - Enable/Disable/Nop 112 * @param upd_flg - whether igu consumer should be 113 * updated. 114 * 115 * @return OSAL_INLINE void 116 */ 117 static OSAL_INLINE void ecore_sb_ack(struct ecore_sb_info *sb_info, 118 enum igu_int_cmd int_cmd, u8 upd_flg) 119 { 120 struct igu_prod_cons_update igu_ack = { 0 }; 121 122 igu_ack.sb_id_and_flags = 123 ((sb_info->sb_ack << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) | 124 (upd_flg << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) | 125 (int_cmd << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) | 126 (IGU_SEG_ACCESS_REG << 127 IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT)); 128 129 #ifdef ECORE_CONFIG_DIRECT_HWFN 130 DIRECT_REG_WR(sb_info->p_hwfn, sb_info->igu_addr, 131 igu_ack.sb_id_and_flags); 132 #else 133 DIRECT_REG_WR(OSAL_NULL, sb_info->igu_addr, igu_ack.sb_id_and_flags); 134 #endif 135 /* Both segments (interrupts & acks) are written to same place address; 136 * Need to guarantee all commands will be received (in-order) by HW. 137 */ 138 OSAL_MMIOWB(sb_info->p_dev); 139 OSAL_BARRIER(sb_info->p_dev); 140 } 141 142 #ifdef ECORE_CONFIG_DIRECT_HWFN 143 static OSAL_INLINE void __internal_ram_wr(struct ecore_hwfn *p_hwfn, 144 void OSAL_IOMEM *addr, 145 int size, u32 *data) 146 #else 147 static OSAL_INLINE void __internal_ram_wr(void *p_hwfn, 148 void OSAL_IOMEM *addr, 149 int size, u32 *data) 150 151 #endif 152 { 153 unsigned int i; 154 155 for (i = 0; i < size / sizeof(*data); i++) 156 DIRECT_REG_WR(p_hwfn, &((u32 OSAL_IOMEM *)addr)[i], data[i]); 157 } 158 159 #ifdef ECORE_CONFIG_DIRECT_HWFN 160 static OSAL_INLINE void internal_ram_wr(struct ecore_hwfn *p_hwfn, 161 void OSAL_IOMEM *addr, 162 int size, u32 *data) 163 { 164 __internal_ram_wr(p_hwfn, addr, size, data); 165 } 166 #else 167 static OSAL_INLINE void internal_ram_wr(void OSAL_IOMEM *addr, 168 int size, u32 *data) 169 { 170 __internal_ram_wr(OSAL_NULL, addr, size, data); 171 } 172 #endif 173 #endif 174 175 struct ecore_hwfn; 176 struct ecore_ptt; 177 178 enum ecore_coalescing_fsm { 179 ECORE_COAL_RX_STATE_MACHINE, 180 ECORE_COAL_TX_STATE_MACHINE 181 }; 182 183 /** 184 * @brief ecore_int_cau_conf_pi - configure cau for a given 185 * status block 186 * 187 * @param p_hwfn 188 * @param p_ptt 189 * @param p_sb 190 * @param pi_index 191 * @param state 192 * @param timeset 193 */ 194 void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn, 195 struct ecore_ptt *p_ptt, 196 struct ecore_sb_info *p_sb, 197 u32 pi_index, 198 enum ecore_coalescing_fsm coalescing_fsm, 199 u8 timeset); 200 201 /** 202 * @brief ecore_int_igu_enable_int - enable device interrupts 203 * 204 * @param p_hwfn 205 * @param p_ptt 206 * @param int_mode - interrupt mode to use 207 */ 208 void ecore_int_igu_enable_int(struct ecore_hwfn *p_hwfn, 209 struct ecore_ptt *p_ptt, 210 enum ecore_int_mode int_mode); 211 212 /** 213 * @brief ecore_int_igu_disable_int - disable device interrupts 214 * 215 * @param p_hwfn 216 * @param p_ptt 217 */ 218 void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn, 219 struct ecore_ptt *p_ptt); 220 221 /** 222 * @brief ecore_int_igu_read_sisr_reg - Reads the single isr multiple dpc 223 * register from igu. 224 * 225 * @param p_hwfn 226 * 227 * @return u64 228 */ 229 u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn); 230 231 #define ECORE_SP_SB_ID 0xffff 232 233 /** 234 * @brief ecore_int_sb_init - Initializes the sb_info structure. 235 * 236 * once the structure is initialized it can be passed to sb related functions. 237 * 238 * @param p_hwfn 239 * @param p_ptt 240 * @param sb_info points to an uninitialized (but 241 * allocated) sb_info structure 242 * @param sb_virt_addr 243 * @param sb_phy_addr 244 * @param sb_id the sb_id to be used (zero based in driver) 245 * should use ECORE_SP_SB_ID for SP Status block 246 * 247 * @return enum _ecore_status_t 248 */ 249 enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn *p_hwfn, 250 struct ecore_ptt *p_ptt, 251 struct ecore_sb_info *sb_info, 252 void *sb_virt_addr, 253 dma_addr_t sb_phy_addr, 254 u16 sb_id); 255 /** 256 * @brief ecore_int_sb_setup - Setup the sb. 257 * 258 * @param p_hwfn 259 * @param p_ptt 260 * @param sb_info initialized sb_info structure 261 */ 262 void ecore_int_sb_setup( 263 struct ecore_hwfn *p_hwfn, 264 struct ecore_ptt *p_ptt, 265 struct ecore_sb_info *sb_info); 266 267 /** 268 * @brief ecore_int_sb_release - releases the sb_info structure. 269 * 270 * once the structure is released, it's memory can be freed 271 * 272 * @param p_hwfn 273 * @param sb_info points to an allocated sb_info structure 274 * @param sb_id the sb_id to be used (zero based in driver) 275 * should never be equal to ECORE_SP_SB_ID 276 * (SP Status block) 277 * 278 * @return enum _ecore_status_t 279 */ 280 enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn *p_hwfn, 281 struct ecore_sb_info *sb_info, 282 u16 sb_id); 283 284 /** 285 * @brief ecore_int_sp_dpc - To be called when an interrupt is received on the 286 * default status block. 287 * 288 * @param p_hwfn - pointer to hwfn 289 * 290 */ 291 void ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie); 292 293 /** 294 * @brief ecore_int_get_num_sbs - get the number of status 295 * blocks configured for this funciton in the igu. 296 * 297 * @param p_hwfn 298 * @param p_sb_cnt_info 299 * 300 * @return 301 */ 302 void ecore_int_get_num_sbs(struct ecore_hwfn *p_hwfn, 303 struct ecore_sb_cnt_info *p_sb_cnt_info); 304 305 /** 306 * @brief ecore_int_disable_post_isr_release - performs the cleanup post ISR 307 * release. The API need to be called after releasing all slowpath IRQs 308 * of the device. 309 * 310 * @param p_dev 311 * 312 */ 313 void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev); 314 315 /** 316 * @brief ecore_int_attn_clr_enable - sets whether the general behavior is 317 * preventing attentions from being reasserted, or following the 318 * attributes of the specific attention. 319 * 320 * @param p_dev 321 * @param clr_enable 322 * 323 */ 324 void ecore_int_attn_clr_enable(struct ecore_dev *p_dev, bool clr_enable); 325 326 /** 327 * @brief Read debug information regarding a given SB. 328 * 329 * @param p_hwfn 330 * @param p_ptt 331 * @param p_sb - point to Status block for which we want to get info. 332 * @param p_info - pointer to struct to fill with information regarding SB. 333 * 334 * @return ECORE_SUCCESS if pointer is filled; failure otherwise. 335 */ 336 enum _ecore_status_t ecore_int_get_sb_dbg(struct ecore_hwfn *p_hwfn, 337 struct ecore_ptt *p_ptt, 338 struct ecore_sb_info *p_sb, 339 struct ecore_sb_info_dbg *p_info); 340 341 /** 342 * @brief - Move a free Status block between PF and child VF 343 * 344 * @param p_hwfn 345 * @param p_ptt 346 * @param sb_id - The PF fastpath vector to be moved [re-assigned if claiming 347 * from VF, given-up if moving to VF] 348 * @param b_to_vf - PF->VF == true, VF->PF == false 349 * 350 * @return ECORE_SUCCESS if SB successfully moved. 351 */ 352 enum _ecore_status_t 353 ecore_int_igu_relocate_sb(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, 354 u16 sb_id, bool b_to_vf); 355 #endif 356