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_SRIOV_H__ 37 #define __ECORE_SRIOV_H__ 38 39 #include "ecore_status.h" 40 #include "ecore_vfpf_if.h" 41 #include "ecore_iov_api.h" 42 #include "ecore_hsi_common.h" 43 #include "ecore_l2.h" 44 45 #define ECORE_ETH_MAX_VF_NUM_VLAN_FILTERS \ 46 (E4_MAX_NUM_VFS * ECORE_ETH_VF_NUM_VLAN_FILTERS) 47 48 /* Represents a full message. Both the request filled by VF 49 * and the response filled by the PF. The VF needs one copy 50 * of this message, it fills the request part and sends it to 51 * the PF. The PF will copy the response to the response part for 52 * the VF to later read it. The PF needs to hold a message like this 53 * per VF, the request that is copied to the PF is placed in the 54 * request size, and the response is filled by the PF before sending 55 * it to the VF. 56 */ 57 struct ecore_vf_mbx_msg { 58 union vfpf_tlvs req; 59 union pfvf_tlvs resp; 60 }; 61 62 /* This mailbox is maintained per VF in its PF 63 * contains all information required for sending / receiving 64 * a message 65 */ 66 struct ecore_iov_vf_mbx { 67 union vfpf_tlvs *req_virt; 68 dma_addr_t req_phys; 69 union pfvf_tlvs *reply_virt; 70 dma_addr_t reply_phys; 71 72 /* Address in VF where a pending message is located */ 73 dma_addr_t pending_req; 74 75 /* Message from VF awaits handling */ 76 bool b_pending_msg; 77 78 u8 *offset; 79 80 #ifdef CONFIG_ECORE_SW_CHANNEL 81 struct ecore_iov_sw_mbx sw_mbx; 82 #endif 83 84 /* VF GPA address */ 85 u32 vf_addr_lo; 86 u32 vf_addr_hi; 87 88 struct vfpf_first_tlv first_tlv; /* saved VF request header */ 89 90 u8 flags; 91 #define VF_MSG_INPROCESS 0x1 /* failsafe - the FW should prevent 92 * more then one pending msg 93 */ 94 }; 95 96 #define ECORE_IOV_LEGACY_QID_RX (0) 97 #define ECORE_IOV_LEGACY_QID_TX (1) 98 #define ECORE_IOV_QID_INVALID (0xFE) 99 100 struct ecore_vf_queue_cid { 101 bool b_is_tx; 102 struct ecore_queue_cid *p_cid; 103 }; 104 105 /* Describes a qzone associated with the VF */ 106 struct ecore_vf_queue { 107 /* Input from upper-layer, mapping relateive queue to queue-zone */ 108 u16 fw_rx_qid; 109 u16 fw_tx_qid; 110 111 struct ecore_vf_queue_cid cids[MAX_QUEUES_PER_QZONE]; 112 }; 113 114 enum vf_state { 115 VF_FREE = 0, /* VF ready to be acquired holds no resc */ 116 VF_ACQUIRED = 1, /* VF, aquired, but not initalized */ 117 VF_ENABLED = 2, /* VF, Enabled */ 118 VF_RESET = 3, /* VF, FLR'd, pending cleanup */ 119 VF_STOPPED = 4 /* VF, Stopped */ 120 }; 121 122 struct ecore_vf_vlan_shadow { 123 bool used; 124 u16 vid; 125 }; 126 127 struct ecore_vf_shadow_config { 128 /* Shadow copy of all guest vlans */ 129 struct ecore_vf_vlan_shadow vlans[ECORE_ETH_VF_NUM_VLAN_FILTERS + 1]; 130 131 /* Shadow copy of all configured MACs; Empty if forcing MACs */ 132 u8 macs[ECORE_ETH_VF_NUM_MAC_FILTERS][ETH_ALEN]; 133 u8 inner_vlan_removal; 134 }; 135 136 /* PFs maintain an array of this structure, per VF */ 137 struct ecore_vf_info { 138 struct ecore_iov_vf_mbx vf_mbx; 139 enum vf_state state; 140 bool b_init; 141 bool b_malicious; 142 u8 to_disable; 143 144 struct ecore_bulletin bulletin; 145 dma_addr_t vf_bulletin; 146 147 /* PF saves a copy of the last VF acquire message */ 148 struct vfpf_acquire_tlv acquire; 149 150 u32 concrete_fid; 151 u16 opaque_fid; 152 u16 mtu; 153 154 u8 vport_id; 155 u8 rss_eng_id; 156 u8 relative_vf_id; 157 u8 abs_vf_id; 158 #define ECORE_VF_ABS_ID(p_hwfn, p_vf) (ECORE_PATH_ID(p_hwfn) ? \ 159 (p_vf)->abs_vf_id + MAX_NUM_VFS_BB : \ 160 (p_vf)->abs_vf_id) 161 162 u8 vport_instance; /* Number of active vports */ 163 u8 num_rxqs; 164 u8 num_txqs; 165 166 u16 rx_coal; 167 u16 tx_coal; 168 169 u8 num_sbs; 170 171 u8 num_mac_filters; 172 u8 num_vlan_filters; 173 174 struct ecore_vf_queue vf_queues[ECORE_MAX_VF_CHAINS_PER_PF]; 175 u16 igu_sbs[ECORE_MAX_VF_CHAINS_PER_PF]; 176 177 /* TODO - Only windows is using it - should be removed */ 178 u8 was_malicious; 179 u8 num_active_rxqs; 180 void *ctx; 181 struct ecore_public_vf_info p_vf_info; 182 bool spoof_chk; /* Current configured on HW */ 183 bool req_spoofchk_val; /* Requested value */ 184 185 /* Stores the configuration requested by VF */ 186 struct ecore_vf_shadow_config shadow_config; 187 188 /* A bitfield using bulletin's valid-map bits, used to indicate 189 * which of the bulletin board features have been configured. 190 */ 191 u64 configured_features; 192 #define ECORE_IOV_CONFIGURED_FEATURES_MASK ((1 << MAC_ADDR_FORCED) | \ 193 (1 << VLAN_ADDR_FORCED)) 194 }; 195 196 /* This structure is part of ecore_hwfn and used only for PFs that have sriov 197 * capability enabled. 198 */ 199 struct ecore_pf_iov { 200 struct ecore_vf_info vfs_array[E4_MAX_NUM_VFS]; 201 u64 pending_flr[ECORE_VF_ARRAY_LENGTH]; 202 203 #ifndef REMOVE_DBG 204 /* This doesn't serve anything functionally, but it makes windows 205 * debugging of IOV related issues easier. 206 */ 207 u64 active_vfs[ECORE_VF_ARRAY_LENGTH]; 208 #endif 209 210 /* Allocate message address continuosuly and split to each VF */ 211 void *mbx_msg_virt_addr; 212 dma_addr_t mbx_msg_phys_addr; 213 u32 mbx_msg_size; 214 void *mbx_reply_virt_addr; 215 dma_addr_t mbx_reply_phys_addr; 216 u32 mbx_reply_size; 217 void *p_bulletins; 218 dma_addr_t bulletins_phys; 219 u32 bulletins_size; 220 }; 221 222 #ifdef CONFIG_ECORE_SRIOV 223 /** 224 * @brief Read sriov related information and allocated resources 225 * reads from configuraiton space, shmem, etc. 226 * 227 * @param p_hwfn 228 * 229 * @return enum _ecore_status_t 230 */ 231 enum _ecore_status_t ecore_iov_hw_info(struct ecore_hwfn *p_hwfn); 232 233 /** 234 * @brief ecore_add_tlv - place a given tlv on the tlv buffer at next offset 235 * 236 * @param p_hwfn 237 * @param p_iov 238 * @param type 239 * @param length 240 * 241 * @return pointer to the newly placed tlv 242 */ 243 void *ecore_add_tlv(struct ecore_hwfn *p_hwfn, 244 u8 **offset, 245 u16 type, 246 u16 length); 247 248 /** 249 * @brief list the types and lengths of the tlvs on the buffer 250 * 251 * @param p_hwfn 252 * @param tlvs_list 253 */ 254 void ecore_dp_tlv_list(struct ecore_hwfn *p_hwfn, 255 void *tlvs_list); 256 257 /** 258 * @brief ecore_iov_alloc - allocate sriov related resources 259 * 260 * @param p_hwfn 261 * 262 * @return enum _ecore_status_t 263 */ 264 enum _ecore_status_t ecore_iov_alloc(struct ecore_hwfn *p_hwfn); 265 266 /** 267 * @brief ecore_iov_setup - setup sriov related resources 268 * 269 * @param p_hwfn 270 * @param p_ptt 271 */ 272 void ecore_iov_setup(struct ecore_hwfn *p_hwfn, 273 struct ecore_ptt *p_ptt); 274 275 /** 276 * @brief ecore_iov_free - free sriov related resources 277 * 278 * @param p_hwfn 279 */ 280 void ecore_iov_free(struct ecore_hwfn *p_hwfn); 281 282 /** 283 * @brief free sriov related memory that was allocated during hw_prepare 284 * 285 * @param p_dev 286 */ 287 void ecore_iov_free_hw_info(struct ecore_dev *p_dev); 288 289 /** 290 * @brief ecore_sriov_eqe_event - handle async sriov event arrived on eqe. 291 * 292 * @param p_hwfn 293 * @param opcode 294 * @param echo 295 * @param data 296 */ 297 enum _ecore_status_t ecore_sriov_eqe_event(struct ecore_hwfn *p_hwfn, 298 u8 opcode, 299 __le16 echo, 300 union event_ring_data *data); 301 302 /** 303 * @brief Mark structs of vfs that have been FLR-ed. 304 * 305 * @param p_hwfn 306 * @param disabled_vfs - bitmask of all VFs on path that were FLRed 307 * 308 * @return 1 iff one of the PF's vfs got FLRed. 0 otherwise. 309 */ 310 bool ecore_iov_mark_vf_flr(struct ecore_hwfn *p_hwfn, 311 u32 *disabled_vfs); 312 313 /** 314 * @brief Search extended TLVs in request/reply buffer. 315 * 316 * @param p_hwfn 317 * @param p_tlvs_list - Pointer to tlvs list 318 * @param req_type - Type of TLV 319 * 320 * @return pointer to tlv type if found, otherwise returns NULL. 321 */ 322 void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn, 323 void *p_tlvs_list, u16 req_type); 324 325 /** 326 * @brief ecore_iov_get_vf_info - return the database of a 327 * specific VF 328 * 329 * @param p_hwfn 330 * @param relative_vf_id - relative id of the VF for which info 331 * is requested 332 * @param b_enabled_only - false iff want to access even if vf is disabled 333 * 334 * @return struct ecore_vf_info* 335 */ 336 struct ecore_vf_info *ecore_iov_get_vf_info(struct ecore_hwfn *p_hwfn, 337 u16 relative_vf_id, 338 bool b_enabled_only); 339 #else 340 static OSAL_INLINE enum _ecore_status_t ecore_iov_hw_info(struct ecore_hwfn *p_hwfn) {return ECORE_SUCCESS;} 341 static OSAL_INLINE void *ecore_add_tlv(struct ecore_hwfn *p_hwfn, u8 **offset, u16 type, u16 length) {return OSAL_NULL;} 342 static OSAL_INLINE void ecore_dp_tlv_list(struct ecore_hwfn *p_hwfn, void *tlvs_list) {} 343 static OSAL_INLINE enum _ecore_status_t ecore_iov_alloc(struct ecore_hwfn *p_hwfn) {return ECORE_SUCCESS;} 344 static OSAL_INLINE void ecore_iov_setup(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt) {} 345 static OSAL_INLINE void ecore_iov_free(struct ecore_hwfn *p_hwfn) {} 346 static OSAL_INLINE void ecore_iov_free_hw_info(struct ecore_dev *p_dev) {} 347 static OSAL_INLINE enum _ecore_status_t ecore_sriov_eqe_event(struct ecore_hwfn *p_hwfn, u8 opcode, __le16 echo, union event_ring_data *data) {return ECORE_INVAL;} 348 static OSAL_INLINE u32 ecore_crc32(u32 crc, u8 *ptr, u32 length) {return 0;} 349 static OSAL_INLINE bool ecore_iov_mark_vf_flr(struct ecore_hwfn *p_hwfn, u32 *disabled_vfs) {return 0;} 350 static OSAL_INLINE void *ecore_iov_search_list_tlvs(struct ecore_hwfn *p_hwfn, void *p_tlvs_list, u16 req_type) {return OSAL_NULL;} 351 static OSAL_INLINE struct ecore_vf_info *ecore_iov_get_vf_info(struct ecore_hwfn *p_hwfn, u16 relative_vf_id, bool b_enabled_only) {return OSAL_NULL;} 352 353 #endif 354 #endif /* __ECORE_SRIOV_H__ */ 355