1 /* QLogic qed NIC Driver 2 * Copyright (c) 2015-2017 QLogic Corporation 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and /or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33 #ifndef _QED_INT_H 34 #define _QED_INT_H 35 36 #include <linux/types.h> 37 #include <linux/slab.h> 38 #include "qed.h" 39 40 /* Fields of IGU PF CONFIGRATION REGISTER */ 41 #define IGU_PF_CONF_FUNC_EN (0x1 << 0) /* function enable */ 42 #define IGU_PF_CONF_MSI_MSIX_EN (0x1 << 1) /* MSI/MSIX enable */ 43 #define IGU_PF_CONF_INT_LINE_EN (0x1 << 2) /* INT enable */ 44 #define IGU_PF_CONF_ATTN_BIT_EN (0x1 << 3) /* attention enable */ 45 #define IGU_PF_CONF_SINGLE_ISR_EN (0x1 << 4) /* single ISR mode enable */ 46 #define IGU_PF_CONF_SIMD_MODE (0x1 << 5) /* simd all ones mode */ 47 /* Fields of IGU VF CONFIGRATION REGISTER */ 48 #define IGU_VF_CONF_FUNC_EN (0x1 << 0) /* function enable */ 49 #define IGU_VF_CONF_MSI_MSIX_EN (0x1 << 1) /* MSI/MSIX enable */ 50 #define IGU_VF_CONF_SINGLE_ISR_EN (0x1 << 4) /* single ISR mode enable */ 51 #define IGU_VF_CONF_PARENT_MASK (0xF) /* Parent PF */ 52 #define IGU_VF_CONF_PARENT_SHIFT 5 /* Parent PF */ 53 54 /* Igu control commands 55 */ 56 enum igu_ctrl_cmd { 57 IGU_CTRL_CMD_TYPE_RD, 58 IGU_CTRL_CMD_TYPE_WR, 59 MAX_IGU_CTRL_CMD 60 }; 61 62 /* Control register for the IGU command register 63 */ 64 struct igu_ctrl_reg { 65 u32 ctrl_data; 66 #define IGU_CTRL_REG_FID_MASK 0xFFFF /* Opaque_FID */ 67 #define IGU_CTRL_REG_FID_SHIFT 0 68 #define IGU_CTRL_REG_PXP_ADDR_MASK 0xFFF /* Command address */ 69 #define IGU_CTRL_REG_PXP_ADDR_SHIFT 16 70 #define IGU_CTRL_REG_RESERVED_MASK 0x1 71 #define IGU_CTRL_REG_RESERVED_SHIFT 28 72 #define IGU_CTRL_REG_TYPE_MASK 0x1 /* use enum igu_ctrl_cmd */ 73 #define IGU_CTRL_REG_TYPE_SHIFT 31 74 }; 75 76 enum qed_coalescing_fsm { 77 QED_COAL_RX_STATE_MACHINE, 78 QED_COAL_TX_STATE_MACHINE 79 }; 80 81 /** 82 * @brief qed_int_igu_enable_int - enable device interrupts 83 * 84 * @param p_hwfn 85 * @param p_ptt 86 * @param int_mode - interrupt mode to use 87 */ 88 void qed_int_igu_enable_int(struct qed_hwfn *p_hwfn, 89 struct qed_ptt *p_ptt, 90 enum qed_int_mode int_mode); 91 92 /** 93 * @brief qed_int_igu_disable_int - disable device interrupts 94 * 95 * @param p_hwfn 96 * @param p_ptt 97 */ 98 void qed_int_igu_disable_int(struct qed_hwfn *p_hwfn, 99 struct qed_ptt *p_ptt); 100 101 /** 102 * @brief qed_int_igu_read_sisr_reg - Reads the single isr multiple dpc 103 * register from igu. 104 * 105 * @param p_hwfn 106 * 107 * @return u64 108 */ 109 u64 qed_int_igu_read_sisr_reg(struct qed_hwfn *p_hwfn); 110 111 #define QED_SP_SB_ID 0xffff 112 /** 113 * @brief qed_int_sb_init - Initializes the sb_info structure. 114 * 115 * once the structure is initialized it can be passed to sb related functions. 116 * 117 * @param p_hwfn 118 * @param p_ptt 119 * @param sb_info points to an uninitialized (but 120 * allocated) sb_info structure 121 * @param sb_virt_addr 122 * @param sb_phy_addr 123 * @param sb_id the sb_id to be used (zero based in driver) 124 * should use QED_SP_SB_ID for SP Status block 125 * 126 * @return int 127 */ 128 int qed_int_sb_init(struct qed_hwfn *p_hwfn, 129 struct qed_ptt *p_ptt, 130 struct qed_sb_info *sb_info, 131 void *sb_virt_addr, 132 dma_addr_t sb_phy_addr, 133 u16 sb_id); 134 /** 135 * @brief qed_int_sb_setup - Setup the sb. 136 * 137 * @param p_hwfn 138 * @param p_ptt 139 * @param sb_info initialized sb_info structure 140 */ 141 void qed_int_sb_setup(struct qed_hwfn *p_hwfn, 142 struct qed_ptt *p_ptt, 143 struct qed_sb_info *sb_info); 144 145 /** 146 * @brief qed_int_sb_release - releases the sb_info structure. 147 * 148 * once the structure is released, it's memory can be freed 149 * 150 * @param p_hwfn 151 * @param sb_info points to an allocated sb_info structure 152 * @param sb_id the sb_id to be used (zero based in driver) 153 * should never be equal to QED_SP_SB_ID 154 * (SP Status block) 155 * 156 * @return int 157 */ 158 int qed_int_sb_release(struct qed_hwfn *p_hwfn, 159 struct qed_sb_info *sb_info, 160 u16 sb_id); 161 162 /** 163 * @brief qed_int_sp_dpc - To be called when an interrupt is received on the 164 * default status block. 165 * 166 * @param p_hwfn - pointer to hwfn 167 * 168 */ 169 void qed_int_sp_dpc(unsigned long hwfn_cookie); 170 171 /** 172 * @brief qed_int_get_num_sbs - get the number of status 173 * blocks configured for this funciton in the igu. 174 * 175 * @param p_hwfn 176 * @param p_sb_cnt_info 177 * 178 * @return int - number of status blocks configured 179 */ 180 void qed_int_get_num_sbs(struct qed_hwfn *p_hwfn, 181 struct qed_sb_cnt_info *p_sb_cnt_info); 182 183 /** 184 * @brief qed_int_disable_post_isr_release - performs the cleanup post ISR 185 * release. The API need to be called after releasing all slowpath IRQs 186 * of the device. 187 * 188 * @param cdev 189 * 190 */ 191 void qed_int_disable_post_isr_release(struct qed_dev *cdev); 192 193 /** 194 * @brief - Doorbell Recovery handler. 195 * Run doorbell recovery in case of PF overflow (and flush DORQ if 196 * needed). 197 * 198 * @param p_hwfn 199 * @param p_ptt 200 */ 201 int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); 202 203 #define QED_CAU_DEF_RX_TIMER_RES 0 204 #define QED_CAU_DEF_TX_TIMER_RES 0 205 206 #define QED_SB_ATT_IDX 0x0001 207 #define QED_SB_EVENT_MASK 0x0003 208 209 #define SB_ALIGNED_SIZE(p_hwfn) \ 210 ALIGNED_TYPE_SIZE(struct status_block_e4, p_hwfn) 211 212 #define QED_SB_INVALID_IDX 0xffff 213 214 struct qed_igu_block { 215 u8 status; 216 #define QED_IGU_STATUS_FREE 0x01 217 #define QED_IGU_STATUS_VALID 0x02 218 #define QED_IGU_STATUS_PF 0x04 219 #define QED_IGU_STATUS_DSB 0x08 220 221 u8 vector_number; 222 u8 function_id; 223 u8 is_pf; 224 225 /* Index inside IGU [meant for back reference] */ 226 u16 igu_sb_id; 227 228 struct qed_sb_info *sb_info; 229 }; 230 231 struct qed_igu_info { 232 struct qed_igu_block entry[MAX_TOT_SB_PER_PATH]; 233 u16 igu_dsb_id; 234 235 struct qed_sb_cnt_info usage; 236 237 bool b_allow_pf_vf_change; 238 }; 239 240 /** 241 * @brief - Make sure the IGU CAM reflects the resources provided by MFW 242 * 243 * @param p_hwfn 244 * @param p_ptt 245 */ 246 int qed_int_igu_reset_cam(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); 247 248 /** 249 * @brief Translate the weakly-defined client sb-id into an IGU sb-id 250 * 251 * @param p_hwfn 252 * @param sb_id - user provided sb_id 253 * 254 * @return an index inside IGU CAM where the SB resides 255 */ 256 u16 qed_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id); 257 258 /** 259 * @brief return a pointer to an unused valid SB 260 * 261 * @param p_hwfn 262 * @param b_is_pf - true iff we want a SB belonging to a PF 263 * 264 * @return point to an igu_block, NULL if none is available 265 */ 266 struct qed_igu_block *qed_get_igu_free_sb(struct qed_hwfn *p_hwfn, 267 bool b_is_pf); 268 269 void qed_int_igu_init_pure_rt(struct qed_hwfn *p_hwfn, 270 struct qed_ptt *p_ptt, 271 bool b_set, 272 bool b_slowpath); 273 274 void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn); 275 276 /** 277 * @brief qed_int_igu_read_cam - Reads the IGU CAM. 278 * This function needs to be called during hardware 279 * prepare. It reads the info from igu cam to know which 280 * status block is the default / base status block etc. 281 * 282 * @param p_hwfn 283 * @param p_ptt 284 * 285 * @return int 286 */ 287 int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn, 288 struct qed_ptt *p_ptt); 289 290 typedef int (*qed_int_comp_cb_t)(struct qed_hwfn *p_hwfn, 291 void *cookie); 292 /** 293 * @brief qed_int_register_cb - Register callback func for 294 * slowhwfn statusblock. 295 * 296 * Every protocol that uses the slowhwfn status block 297 * should register a callback function that will be called 298 * once there is an update of the sp status block. 299 * 300 * @param p_hwfn 301 * @param comp_cb - function to be called when there is an 302 * interrupt on the sp sb 303 * 304 * @param cookie - passed to the callback function 305 * @param sb_idx - OUT parameter which gives the chosen index 306 * for this protocol. 307 * @param p_fw_cons - pointer to the actual address of the 308 * consumer for this protocol. 309 * 310 * @return int 311 */ 312 int qed_int_register_cb(struct qed_hwfn *p_hwfn, 313 qed_int_comp_cb_t comp_cb, 314 void *cookie, 315 u8 *sb_idx, 316 __le16 **p_fw_cons); 317 318 /** 319 * @brief qed_int_unregister_cb - Unregisters callback 320 * function from sp sb. 321 * Partner of qed_int_register_cb -> should be called 322 * when no longer required. 323 * 324 * @param p_hwfn 325 * @param pi 326 * 327 * @return int 328 */ 329 int qed_int_unregister_cb(struct qed_hwfn *p_hwfn, 330 u8 pi); 331 332 /** 333 * @brief qed_int_get_sp_sb_id - Get the slowhwfn sb id. 334 * 335 * @param p_hwfn 336 * 337 * @return u16 338 */ 339 u16 qed_int_get_sp_sb_id(struct qed_hwfn *p_hwfn); 340 341 /** 342 * @brief Status block cleanup. Should be called for each status 343 * block that will be used -> both PF / VF 344 * 345 * @param p_hwfn 346 * @param p_ptt 347 * @param igu_sb_id - igu status block id 348 * @param opaque - opaque fid of the sb owner. 349 * @param b_set - set(1) / clear(0) 350 */ 351 void qed_int_igu_init_pure_rt_single(struct qed_hwfn *p_hwfn, 352 struct qed_ptt *p_ptt, 353 u16 igu_sb_id, 354 u16 opaque, 355 bool b_set); 356 357 /** 358 * @brief qed_int_cau_conf - configure cau for a given status 359 * block 360 * 361 * @param p_hwfn 362 * @param ptt 363 * @param sb_phys 364 * @param igu_sb_id 365 * @param vf_number 366 * @param vf_valid 367 */ 368 void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn, 369 struct qed_ptt *p_ptt, 370 dma_addr_t sb_phys, 371 u16 igu_sb_id, 372 u16 vf_number, 373 u8 vf_valid); 374 375 /** 376 * @brief qed_int_alloc 377 * 378 * @param p_hwfn 379 * @param p_ptt 380 * 381 * @return int 382 */ 383 int qed_int_alloc(struct qed_hwfn *p_hwfn, 384 struct qed_ptt *p_ptt); 385 386 /** 387 * @brief qed_int_free 388 * 389 * @param p_hwfn 390 */ 391 void qed_int_free(struct qed_hwfn *p_hwfn); 392 393 /** 394 * @brief qed_int_setup 395 * 396 * @param p_hwfn 397 * @param p_ptt 398 */ 399 void qed_int_setup(struct qed_hwfn *p_hwfn, 400 struct qed_ptt *p_ptt); 401 402 /** 403 * @brief - Enable Interrupt & Attention for hw function 404 * 405 * @param p_hwfn 406 * @param p_ptt 407 * @param int_mode 408 * 409 * @return int 410 */ 411 int qed_int_igu_enable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 412 enum qed_int_mode int_mode); 413 414 /** 415 * @brief - Initialize CAU status block entry 416 * 417 * @param p_hwfn 418 * @param p_sb_entry 419 * @param pf_id 420 * @param vf_number 421 * @param vf_valid 422 */ 423 void qed_init_cau_sb_entry(struct qed_hwfn *p_hwfn, 424 struct cau_sb_entry *p_sb_entry, 425 u8 pf_id, 426 u16 vf_number, 427 u8 vf_valid); 428 429 int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 430 u8 timer_res, u16 sb_id, bool tx); 431 432 #define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev)) 433 434 int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, 435 struct qed_ptt *p_ptt); 436 437 #endif