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 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 */ 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 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 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 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