Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2023 Intel Corporation 3 : : */ 4 : : 5 : : #ifndef _CPFL_ETHDEV_H_ 6 : : #define _CPFL_ETHDEV_H_ 7 : : 8 : : #include <stdint.h> 9 : : #include <rte_malloc.h> 10 : : #include <rte_spinlock.h> 11 : : #include <rte_ethdev.h> 12 : : #include <rte_kvargs.h> 13 : : #include <rte_hash.h> 14 : : #include <ethdev_driver.h> 15 : : #include <ethdev_pci.h> 16 : : 17 : : #include <idpf_common_device.h> 18 : : #include <idpf_common_virtchnl.h> 19 : : #include <base/idpf_prototype.h> 20 : : #include <base/virtchnl2.h> 21 : : 22 : : #include "cpfl_logs.h" 23 : : #include "cpfl_cpchnl.h" 24 : : #include "cpfl_representor.h" 25 : : #include "cpfl_controlq.h" 26 : : 27 : : /* Currently, backend supports up to 8 vports */ 28 : : #define CPFL_MAX_VPORT_NUM 8 29 : : 30 : : #define CPFL_INVALID_VPORT_IDX 0xffff 31 : : 32 : : #define CPFL_DFLT_Q_VEC_NUM 1 33 : : 34 : : #define CPFL_MIN_BUF_SIZE 1024 35 : : #define CPFL_MAX_FRAME_SIZE 9728 36 : : #define CPFL_DEFAULT_MTU RTE_ETHER_MTU 37 : : 38 : : #define CPFL_VLAN_TAG_SIZE 4 39 : : #define CPFL_ETH_OVERHEAD \ 40 : : (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + CPFL_VLAN_TAG_SIZE * 2) 41 : : 42 : : #define CPFL_RSS_OFFLOAD_ALL ( \ 43 : : RTE_ETH_RSS_IPV4 | \ 44 : : RTE_ETH_RSS_FRAG_IPV4 | \ 45 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP | \ 46 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP | \ 47 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \ 48 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \ 49 : : RTE_ETH_RSS_IPV6 | \ 50 : : RTE_ETH_RSS_FRAG_IPV6 | \ 51 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP | \ 52 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ 53 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \ 54 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER | \ 55 : : RTE_ETH_RSS_L2_PAYLOAD) 56 : : 57 : : #define CPFL_ADAPTER_NAME_LEN (PCI_PRI_STR_SIZE + 1) 58 : : 59 : : #define CPFL_ALARM_INTERVAL 50000 /* us */ 60 : : 61 : : /* Device IDs */ 62 : : #define IDPF_DEV_ID_CPF 0x1453 63 : : #define VIRTCHNL2_QUEUE_GROUP_P2P 0x100 64 : : 65 : : #define CPFL_HOST_ID_NUM 2 66 : : #define CPFL_PF_TYPE_NUM 2 67 : : #define CPFL_HOST_ID_HOST 0 68 : : #define CPFL_HOST_ID_ACC 1 69 : : #define CPFL_INVALID_HOST_ID UINT8_MAX 70 : : #define CPFL_PF_TYPE_APF 0 71 : : #define CPFL_PF_TYPE_CPF 1 72 : : 73 : : /* Function IDs on IMC side */ 74 : : #define CPFL_HOST0_APF 0 75 : : #define CPFL_ACC_APF_ID 4 76 : : #define CPFL_HOST0_CPF_ID 8 77 : : #define CPFL_ACC_CPF_ID 12 78 : : 79 : : #define CPFL_VPORT_LAN_PF 0 80 : : #define CPFL_VPORT_LAN_VF 1 81 : : 82 : : #define CPFL_FLOW_FILE_LEN 100 83 : : #define CPFL_INVALID_HW_ID UINT16_MAX 84 : : #define CPFL_META_CHUNK_LENGTH 1024 85 : : #define CPFL_META_LENGTH 32 86 : : 87 : : #define CPFL_RX_CFGQ_NUM 4 88 : : #define CPFL_TX_CFGQ_NUM 4 89 : : #define CPFL_FPCP_CFGQ_TX 0 90 : : #define CPFL_FPCP_CFGQ_RX 1 91 : : #define CPFL_CFGQ_NUM 8 92 : : 93 : : /* bit[15:14] type 94 : : * bit[13] host/accelerator core 95 : : * bit[12] apf/cpf 96 : : * bit[11:0] vf 97 : : */ 98 : : #define CPFL_REPRESENTOR_ID(type, host_id, pf_id, vf_id) \ 99 : : ((((type) & 0x3) << 14) + (((host_id) & 0x1) << 13) + \ 100 : : (((pf_id) & 0x1) << 12) + ((vf_id) & 0xfff)) 101 : : 102 : : struct cpfl_vport_param { 103 : : struct cpfl_adapter_ext *adapter; 104 : : uint16_t devarg_id; /* arg id from user */ 105 : : uint16_t idx; /* index in adapter->vports[]*/ 106 : : }; 107 : : 108 : : #define CPFL_REPR_ARG_NUM_MAX 4 109 : : /* Struct used when parse driver specific devargs */ 110 : : struct cpfl_devargs { 111 : : uint16_t req_vports[CPFL_MAX_VPORT_NUM]; 112 : : uint16_t req_vport_nb; 113 : : uint8_t repr_args_num; 114 : : struct rte_eth_devargs repr_args[CPFL_REPR_ARG_NUM_MAX]; 115 : : char flow_parser[CPFL_FLOW_FILE_LEN]; 116 : : }; 117 : : 118 : : struct p2p_queue_chunks_info { 119 : : uint32_t tx_start_qid; 120 : : uint32_t rx_start_qid; 121 : : uint32_t tx_compl_start_qid; 122 : : uint32_t rx_buf_start_qid; 123 : : 124 : : uint64_t tx_qtail_start; 125 : : uint32_t tx_qtail_spacing; 126 : : uint64_t rx_qtail_start; 127 : : uint32_t rx_qtail_spacing; 128 : : uint64_t tx_compl_qtail_start; 129 : : uint32_t tx_compl_qtail_spacing; 130 : : uint64_t rx_buf_qtail_start; 131 : : uint32_t rx_buf_qtail_spacing; 132 : : }; 133 : : 134 : : struct cpfl_vport_id { 135 : : uint32_t vport_id; 136 : : uint8_t func_type; 137 : : uint8_t pf_id; 138 : : uint16_t vf_id; 139 : : }; 140 : : 141 : : struct cpfl_vport_info { 142 : : struct cpchnl2_event_vport_created vport; 143 : : bool enabled; 144 : : }; 145 : : 146 : : enum cpfl_itf_type { 147 : : CPFL_ITF_TYPE_VPORT, 148 : : CPFL_ITF_TYPE_REPRESENTOR, 149 : : }; 150 : : 151 : : TAILQ_HEAD(cpfl_flow_list, rte_flow); 152 : : 153 : : #define CPFL_FLOW_BATCH_SIZE 490 154 : : struct cpfl_itf { 155 : : enum cpfl_itf_type type; 156 : : struct cpfl_adapter_ext *adapter; 157 : : struct cpfl_flow_list flow_list; 158 : : struct idpf_dma_mem flow_dma; 159 : : struct idpf_dma_mem dma[CPFL_FLOW_BATCH_SIZE]; 160 : : struct idpf_ctlq_msg msg[CPFL_FLOW_BATCH_SIZE]; 161 : : void *data; 162 : : }; 163 : : 164 : : struct cpfl_vport { 165 : : struct cpfl_itf itf; 166 : : struct idpf_vport base; 167 : : struct p2p_queue_chunks_info *p2p_q_chunks_info; 168 : : 169 : : struct rte_mempool *p2p_mp; 170 : : 171 : : uint16_t nb_data_rxq; 172 : : uint16_t nb_data_txq; 173 : : uint16_t nb_p2p_rxq; 174 : : uint16_t nb_p2p_txq; 175 : : 176 : : struct idpf_rx_queue *p2p_rx_bufq; 177 : : struct idpf_tx_queue *p2p_tx_complq; 178 : : bool p2p_manual_bind; 179 : : }; 180 : : 181 : : struct cpfl_repr { 182 : : struct cpfl_itf itf; 183 : : struct cpfl_repr_id repr_id; 184 : : struct rte_ether_addr mac_addr; 185 : : struct cpfl_vport_info *vport_info; 186 : : bool func_up; /* If the represented function is up */ 187 : : }; 188 : : 189 : : struct cpfl_metadata_chunk { 190 : : int type; 191 : : uint8_t data[CPFL_META_CHUNK_LENGTH]; 192 : : }; 193 : : 194 : : /** 195 : : * It is driver's responsibility to simlulate a metadata buffer which 196 : : * can be used as data source to fill the key of a flow rule. 197 : : */ 198 : : struct cpfl_metadata { 199 : : int length; 200 : : struct cpfl_metadata_chunk chunks[CPFL_META_LENGTH]; 201 : : }; 202 : : 203 : : struct cpfl_adapter_ext { 204 : : TAILQ_ENTRY(cpfl_adapter_ext) next; 205 : : struct idpf_adapter base; 206 : : 207 : : char name[CPFL_ADAPTER_NAME_LEN]; 208 : : 209 : : struct cpfl_vport **vports; 210 : : uint16_t max_vport_nb; 211 : : 212 : : uint16_t cur_vports; /* bit mask of created vport */ 213 : : uint16_t cur_vport_nb; 214 : : 215 : : uint16_t used_vecs_num; 216 : : 217 : : rte_spinlock_t vport_map_lock; 218 : : struct rte_hash *vport_map_hash; 219 : : 220 : : rte_spinlock_t repr_lock; 221 : : struct rte_hash *repr_allowlist_hash; 222 : : 223 : : struct cpfl_flow_js_parser *flow_parser; 224 : : struct rte_bitmap *mod_bm; 225 : : void *mod_bm_mem; 226 : : 227 : : struct cpfl_metadata meta; 228 : : 229 : : /* ctrl vport and ctrl queues. */ 230 : : struct cpfl_vport ctrl_vport; 231 : : uint8_t ctrl_vport_recv_info[IDPF_DFLT_MBX_BUF_SIZE]; 232 : : struct idpf_ctlq_info *ctlqp[CPFL_CFGQ_NUM]; 233 : : struct cpfl_ctlq_create_info cfgq_info[CPFL_CFGQ_NUM]; 234 : : uint8_t host_id; 235 : : }; 236 : : 237 : : TAILQ_HEAD(cpfl_adapter_list, cpfl_adapter_ext); 238 : : 239 : : int cpfl_vport_info_create(struct cpfl_adapter_ext *adapter, 240 : : struct cpfl_vport_id *vport_identity, 241 : : struct cpchnl2_event_vport_created *vport); 242 : : int cpfl_cc_vport_list_get(struct cpfl_adapter_ext *adapter, 243 : : struct cpfl_vport_id *vi, 244 : : struct cpchnl2_get_vport_list_response *response); 245 : : int cpfl_cc_vport_info_get(struct cpfl_adapter_ext *adapter, 246 : : struct cpchnl2_vport_id *vport_id, 247 : : struct cpfl_vport_id *vi, 248 : : struct cpchnl2_get_vport_info_response *response); 249 : : int cpfl_vc_create_ctrl_vport(struct cpfl_adapter_ext *adapter); 250 : : int cpfl_config_ctlq_rx(struct cpfl_adapter_ext *adapter); 251 : : int cpfl_config_ctlq_tx(struct cpfl_adapter_ext *adapter); 252 : : int cpfl_alloc_dma_mem_batch(struct idpf_dma_mem *orig_dma, struct idpf_dma_mem *dma, 253 : : uint32_t size, int batch_size); 254 : : 255 : : #define CPFL_DEV_TO_PCI(eth_dev) \ 256 : : RTE_DEV_TO_PCI((eth_dev)->device) 257 : : #define CPFL_ADAPTER_TO_EXT(p) \ 258 : : container_of((p), struct cpfl_adapter_ext, base) 259 : : #define CPFL_DEV_TO_VPORT(dev) \ 260 : : ((struct cpfl_vport *)((dev)->data->dev_private)) 261 : : #define CPFL_DEV_TO_REPR(dev) \ 262 : : ((struct cpfl_repr *)((dev)->data->dev_private)) 263 : : #define CPFL_DEV_TO_ITF(dev) \ 264 : : ((struct cpfl_itf *)((dev)->data->dev_private)) 265 : : 266 : : static inline uint16_t 267 : : cpfl_get_port_id(struct cpfl_itf *itf) 268 : : { 269 [ # # ]: 0 : if (!itf) 270 : : return CPFL_INVALID_HW_ID; 271 : : 272 [ # # ]: 0 : if (itf->type == CPFL_ITF_TYPE_VPORT) { 273 : : struct cpfl_vport *vport = (void *)itf; 274 : : 275 [ # # ]: 0 : return vport->base.devarg_id; 276 : : } 277 : : 278 : : return CPFL_INVALID_HW_ID; 279 : : } 280 : : 281 : : static inline uint16_t 282 : 0 : cpfl_get_vsi_id(struct cpfl_itf *itf) 283 : : { 284 : : struct cpfl_vport_info *info; 285 : : uint32_t vport_id; 286 : : int ret; 287 : : struct cpfl_vport_id vport_identity; 288 : : 289 [ # # ]: 0 : if (!itf) 290 : : return CPFL_INVALID_HW_ID; 291 : : 292 [ # # ]: 0 : if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) { 293 : : struct cpfl_repr *repr = (void *)itf; 294 : : 295 : 0 : return repr->vport_info->vport.info.vsi_id; 296 [ # # ]: 0 : } else if (itf->type == CPFL_ITF_TYPE_VPORT) { 297 : 0 : vport_id = ((struct cpfl_vport *)itf)->base.vport_id; 298 : : 299 : 0 : vport_identity.func_type = CPCHNL2_FTYPE_LAN_PF; 300 : : /* host: CPFL_HOST0_CPF_ID, acc: CPFL_ACC_CPF_ID */ 301 [ # # ]: 0 : vport_identity.pf_id = (itf->adapter->host_id == CPFL_HOST_ID_ACC) ? 302 : : CPFL_ACC_CPF_ID : CPFL_HOST0_CPF_ID; 303 : 0 : vport_identity.vf_id = 0; 304 : 0 : vport_identity.vport_id = vport_id; 305 : 0 : ret = rte_hash_lookup_data(itf->adapter->vport_map_hash, 306 : : &vport_identity, 307 : : (void **)&info); 308 [ # # ]: 0 : if (ret < 0) { 309 : 0 : PMD_DRV_LOG(ERR, "vport id not exist"); 310 : 0 : goto err; 311 : : } 312 : : 313 : 0 : return info->vport.info.vsi_id; 314 : : } 315 : : 316 : 0 : err: 317 : : return CPFL_INVALID_HW_ID; 318 : : } 319 : : 320 : : static inline struct cpfl_itf * 321 : 0 : cpfl_get_itf_by_port_id(uint16_t port_id) 322 : : { 323 : : struct rte_eth_dev *dev; 324 : : 325 [ # # ]: 0 : if (port_id >= RTE_MAX_ETHPORTS) { 326 : 0 : PMD_DRV_LOG(ERR, "port_id should be < %d.", RTE_MAX_ETHPORTS); 327 : 0 : return NULL; 328 : : } 329 : : 330 : 0 : dev = &rte_eth_devices[port_id]; 331 [ # # ]: 0 : if (dev->state == RTE_ETH_DEV_UNUSED) { 332 : 0 : PMD_DRV_LOG(ERR, "eth_dev[%d] is unused.", port_id); 333 : 0 : return NULL; 334 : : } 335 : : 336 [ # # ]: 0 : if (!dev->data) { 337 : 0 : PMD_DRV_LOG(ERR, "eth_dev[%d] data not be allocated.", port_id); 338 : 0 : return NULL; 339 : : } 340 : : 341 : 0 : return CPFL_DEV_TO_ITF(dev); 342 : : } 343 : : #endif /* _CPFL_ETHDEV_H_ */