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 <idpf_ptp.h> 20 : : #include <base/idpf_prototype.h> 21 : : #include <base/virtchnl2.h> 22 : : 23 : : #include "cpfl_logs.h" 24 : : #include "cpfl_cpchnl.h" 25 : : #include "cpfl_representor.h" 26 : : #include "cpfl_controlq.h" 27 : : 28 : : /* Currently, backend supports up to 8 vports */ 29 : : #define CPFL_MAX_VPORT_NUM 8 30 : : 31 : : #define CPFL_INVALID_VPORT_IDX 0xffff 32 : : 33 : : #define CPFL_DFLT_Q_VEC_NUM 1 34 : : 35 : : #define CPFL_MIN_BUF_SIZE 1024 36 : : #define CPFL_MAX_FRAME_SIZE 9728 37 : : #define CPFL_DEFAULT_MTU RTE_ETHER_MTU 38 : : 39 : : #define CPFL_VLAN_TAG_SIZE 4 40 : : #define CPFL_ETH_OVERHEAD \ 41 : : (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + CPFL_VLAN_TAG_SIZE * 2) 42 : : 43 : : #define CPFL_RSS_OFFLOAD_ALL ( \ 44 : : RTE_ETH_RSS_IPV4 | \ 45 : : RTE_ETH_RSS_FRAG_IPV4 | \ 46 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP | \ 47 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP | \ 48 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP | \ 49 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \ 50 : : RTE_ETH_RSS_IPV6 | \ 51 : : RTE_ETH_RSS_FRAG_IPV6 | \ 52 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP | \ 53 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ 54 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP | \ 55 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER | \ 56 : : RTE_ETH_RSS_L2_PAYLOAD) 57 : : 58 : : #define CPFL_ADAPTER_NAME_LEN (PCI_PRI_STR_SIZE + 1) 59 : : 60 : : #define CPFL_ALARM_INTERVAL 50000 /* us */ 61 : : 62 : : /* Device IDs */ 63 : : #define CPFL_DEV_ID_MMG 0x11E0 64 : : #define CPFL_DEV_ID_MEV 0x1453 65 : : #define VIRTCHNL2_QUEUE_GROUP_P2P 0x100 66 : : 67 : : #define CPFL_HOST_ID_NUM 2 68 : : #define CPFL_PF_TYPE_NUM 2 69 : : #define CPFL_HOST_ID_HOST 0 70 : : #define CPFL_HOST_ID_ACC 1 71 : : #define CPFL_INVALID_HOST_ID UINT8_MAX 72 : : #define CPFL_PF_TYPE_APF 0 73 : : #define CPFL_PF_TYPE_CPF 1 74 : : 75 : : /* Function IDs on IMC side */ 76 : : #define CPFL_HOST0_APF 0 77 : : #define CPFL_ACC_APF_ID 4 78 : : #define CPFL_HOST0_CPF_ID 8 79 : : #define CPFL_ACC_CPF_ID 12 80 : : 81 : : #define CPFL_VPORT_LAN_PF 0 82 : : #define CPFL_VPORT_LAN_VF 1 83 : : 84 : : #define CPFL_FLOW_FILE_LEN 100 85 : : #define CPFL_INVALID_HW_ID UINT16_MAX 86 : : #define CPFL_META_CHUNK_LENGTH 1024 87 : : #define CPFL_META_LENGTH 32 88 : : 89 : : #define CPFL_RX_CFGQ_NUM 4 90 : : #define CPFL_TX_CFGQ_NUM 4 91 : : #define CPFL_FPCP_CFGQ_TX 0 92 : : #define CPFL_FPCP_CFGQ_RX 1 93 : : #define CPFL_CFGQ_NUM 8 94 : : #define VCPF_RX_CFGQ_NUM 1 95 : : #define VCPF_TX_CFGQ_NUM 1 96 : : #define VCPF_CFGQ_NUM 2 97 : : 98 : : /* bit[15:14] type 99 : : * bit[13] host/accelerator core 100 : : * bit[12] apf/cpf 101 : : * bit[11:0] vf 102 : : */ 103 : : #define CPFL_REPRESENTOR_ID(type, host_id, pf_id, vf_id) \ 104 : : ((((type) & 0x3) << 14) + (((host_id) & 0x1) << 13) + \ 105 : : (((pf_id) & 0x1) << 12) + ((vf_id) & 0xfff)) 106 : : 107 : : /* Max VFs per PCI device (functions 0-7) */ 108 : : #define VCPF_VFS_PER_PCI_DEV 8 109 : : 110 : : /* Calculate VF ID from PCI device and function IDs. 111 : : * VFs span multiple PCI devices, e.g.: 112 : : * device 0: VF 0-7, device 1: VF 8-15, etc. 113 : : */ 114 : : #define VCPF_VF_ID_FROM_PCI(device_id, function) \ 115 : : (((device_id) * VCPF_VFS_PER_PCI_DEV) + (function)) 116 : : 117 : : struct cpfl_vport_param { 118 : : struct cpfl_adapter_ext *adapter; 119 : : uint16_t devarg_id; /* arg id from user */ 120 : : uint16_t idx; /* index in adapter->vports[]*/ 121 : : }; 122 : : 123 : : #define CPFL_REPR_ARG_NUM_MAX 4 124 : : /* Struct used when parse driver specific devargs */ 125 : : struct cpfl_devargs { 126 : : uint16_t req_vports[CPFL_MAX_VPORT_NUM]; 127 : : uint16_t req_vport_nb; 128 : : uint8_t repr_args_num; 129 : : struct rte_eth_devargs repr_args[CPFL_REPR_ARG_NUM_MAX]; 130 : : char flow_parser[CPFL_FLOW_FILE_LEN]; 131 : : }; 132 : : 133 : : struct p2p_queue_chunks_info { 134 : : uint32_t tx_start_qid; 135 : : uint32_t rx_start_qid; 136 : : uint32_t tx_compl_start_qid; 137 : : uint32_t rx_buf_start_qid; 138 : : 139 : : uint64_t tx_qtail_start; 140 : : uint32_t tx_qtail_spacing; 141 : : uint64_t rx_qtail_start; 142 : : uint32_t rx_qtail_spacing; 143 : : uint64_t tx_compl_qtail_start; 144 : : uint32_t tx_compl_qtail_spacing; 145 : : uint64_t rx_buf_qtail_start; 146 : : uint32_t rx_buf_qtail_spacing; 147 : : }; 148 : : 149 : : struct cpfl_vport_id { 150 : : uint32_t vport_id; 151 : : uint8_t func_type; 152 : : uint8_t pf_id; 153 : : uint16_t vf_id; 154 : : }; 155 : : 156 : : struct cpfl_vport_info { 157 : : struct cpchnl2_event_vport_created vport; 158 : : bool enabled; 159 : : }; 160 : : 161 : : enum cpfl_itf_type { 162 : : CPFL_ITF_TYPE_VPORT, 163 : : CPFL_ITF_TYPE_REPRESENTOR, 164 : : }; 165 : : 166 : : TAILQ_HEAD(cpfl_flow_list, rte_flow); 167 : : 168 : : #define CPFL_FLOW_BATCH_SIZE 490 169 : : struct cpfl_itf { 170 : : enum cpfl_itf_type type; 171 : : struct cpfl_adapter_ext *adapter; 172 : : struct cpfl_flow_list flow_list; 173 : : struct idpf_dma_mem flow_dma; 174 : : struct idpf_dma_mem dma[CPFL_FLOW_BATCH_SIZE]; 175 : : struct idpf_ctlq_msg msg[CPFL_FLOW_BATCH_SIZE]; 176 : : void *data; 177 : : }; 178 : : 179 : : struct vcpf_vport_info { 180 : : u16 vport_index; 181 : : u16 vsi_id; 182 : : u32 abs_start_txq_id; 183 : : u32 num_tx_q; 184 : : u32 abs_start_rxq_id; 185 : : u32 num_rx_q; 186 : : }; 187 : : 188 : : struct cpfl_vport { 189 : : struct cpfl_itf itf; 190 : : struct idpf_vport base; 191 : : struct p2p_queue_chunks_info *p2p_q_chunks_info; 192 : : struct vcpf_vport_info vport_info; 193 : : 194 : : struct rte_mempool *p2p_mp; 195 : : 196 : : uint16_t nb_data_rxq; 197 : : uint16_t nb_data_txq; 198 : : uint16_t nb_p2p_rxq; 199 : : uint16_t nb_p2p_txq; 200 : : 201 : : struct idpf_rx_queue *p2p_rx_bufq; 202 : : struct idpf_complq *p2p_tx_complq; 203 : : bool p2p_manual_bind; 204 : : }; 205 : : 206 : : struct cpfl_repr { 207 : : struct cpfl_itf itf; 208 : : struct cpfl_repr_id repr_id; 209 : : struct rte_ether_addr mac_addr; 210 : : struct cpfl_vport_info *vport_info; 211 : : bool func_up; /* If the represented function is up */ 212 : : }; 213 : : 214 : : struct cpfl_metadata_chunk { 215 : : int type; 216 : : uint8_t data[CPFL_META_CHUNK_LENGTH]; 217 : : }; 218 : : 219 : : /** 220 : : * It is driver's responsibility to simlulate a metadata buffer which 221 : : * can be used as data source to fill the key of a flow rule. 222 : : */ 223 : : struct cpfl_metadata { 224 : : int length; 225 : : struct cpfl_metadata_chunk chunks[CPFL_META_LENGTH]; 226 : : }; 227 : : 228 : : /** 229 : : * struct vcpf_cfg_queue - config queue information 230 : : * @qid: rx/tx queue id 231 : : * @qtail_reg_start: rx/tx tail queue register start 232 : : * @qtail_reg_spacing: rx/tx tail queue register spacing 233 : : */ 234 : : struct vcpf_cfg_queue { 235 : : u32 qid; 236 : : u64 qtail_reg_start; 237 : : u32 qtail_reg_spacing; 238 : : }; 239 : : 240 : : /** 241 : : * struct vcpf_cfgq_info - config queue information 242 : : * @num_cfgq: number of config queues 243 : : * @cfgq_add: config queue add information 244 : : * @cfgq: config queue information 245 : : */ 246 : : struct vcpf_cfgq_info { 247 : : u16 num_cfgq; 248 : : struct virtchnl2_add_queues *cfgq_add; 249 : : struct vcpf_cfg_queue *cfgq; 250 : : }; 251 : : 252 : : struct cpfl_adapter_ext { 253 : : TAILQ_ENTRY(cpfl_adapter_ext) next; 254 : : struct idpf_adapter base; 255 : : 256 : : char name[CPFL_ADAPTER_NAME_LEN]; 257 : : 258 : : struct cpfl_vport **vports; 259 : : uint16_t max_vport_nb; 260 : : 261 : : uint16_t cur_vports; /* bit mask of created vport */ 262 : : uint16_t cur_vport_nb; 263 : : 264 : : uint16_t used_vecs_num; 265 : : 266 : : rte_spinlock_t vport_map_lock; 267 : : struct rte_hash *vport_map_hash; 268 : : 269 : : rte_spinlock_t repr_lock; 270 : : struct rte_hash *repr_allowlist_hash; 271 : : 272 : : struct cpfl_flow_js_parser *flow_parser; 273 : : struct rte_bitmap *mod_bm; 274 : : void *mod_bm_mem; 275 : : 276 : : struct cpfl_metadata meta; 277 : : 278 : : /* ctrl vport and ctrl queues. */ 279 : : struct cpfl_vport ctrl_vport; 280 : : uint8_t ctrl_vport_recv_info[IDPF_DFLT_MBX_BUF_SIZE]; 281 : : struct idpf_ctlq_info **ctlqp; 282 : : struct cpfl_ctlq_create_info *cfgq_info; 283 : : struct vcpf_cfgq_info cfgq_in; 284 : : uint8_t addq_recv_info[IDPF_DFLT_MBX_BUF_SIZE]; 285 : : uint16_t num_cfgq; 286 : : uint16_t num_rx_cfgq; 287 : : uint16_t num_tx_cfgq; 288 : : uint8_t host_id; 289 : : }; 290 : : 291 : : TAILQ_HEAD(cpfl_adapter_list, cpfl_adapter_ext); 292 : : 293 : : int cpfl_vport_info_create(struct cpfl_adapter_ext *adapter, 294 : : struct cpfl_vport_id *vport_identity, 295 : : struct cpchnl2_event_vport_created *vport); 296 : : int cpfl_cc_vport_list_get(struct cpfl_adapter_ext *adapter, 297 : : struct cpfl_vport_id *vi, 298 : : struct cpchnl2_get_vport_list_response *response); 299 : : int cpfl_cc_vport_info_get(struct cpfl_adapter_ext *adapter, 300 : : struct cpchnl2_vport_id *vport_id, 301 : : struct cpfl_vport_id *vi, 302 : : struct cpchnl2_get_vport_info_response *response); 303 : : int cpfl_vc_create_ctrl_vport(struct cpfl_adapter_ext *adapter); 304 : : int cpfl_config_ctlq_rx(struct cpfl_adapter_ext *adapter); 305 : : int cpfl_config_ctlq_tx(struct cpfl_adapter_ext *adapter); 306 : : int cpfl_alloc_dma_mem_batch(struct idpf_dma_mem *orig_dma, struct idpf_dma_mem *dma, 307 : : uint32_t size, int batch_size); 308 : : int vcpf_add_queues(struct cpfl_adapter_ext *adapter); 309 : : int vcpf_del_queues(struct cpfl_adapter_ext *adapter); 310 : : 311 : : #define CPFL_DEV_TO_PCI(eth_dev) \ 312 : : RTE_CLASS_TO_BUS_DEVICE(eth_dev, struct rte_pci_device) 313 : : #define CPFL_ADAPTER_TO_EXT(p) \ 314 : : container_of((p), struct cpfl_adapter_ext, base) 315 : : #define CPFL_DEV_TO_VPORT(dev) \ 316 : : ((struct cpfl_vport *)((dev)->data->dev_private)) 317 : : #define CPFL_DEV_TO_REPR(dev) \ 318 : : ((struct cpfl_repr *)((dev)->data->dev_private)) 319 : : #define CPFL_DEV_TO_ITF(dev) \ 320 : : ((struct cpfl_itf *)((dev)->data->dev_private)) 321 : : 322 : : static inline uint16_t 323 : : cpfl_get_port_id(struct cpfl_itf *itf) 324 : : { 325 [ # # ]: 0 : if (!itf) 326 : : return CPFL_INVALID_HW_ID; 327 : : 328 [ # # ]: 0 : if (itf->type == CPFL_ITF_TYPE_VPORT) { 329 : : struct cpfl_vport *vport = (void *)itf; 330 : : 331 [ # # ]: 0 : return vport->base.devarg_id; 332 : : } 333 : : 334 : : return CPFL_INVALID_HW_ID; 335 : : } 336 : : 337 : : static inline uint16_t 338 : 0 : cpfl_get_vsi_id(struct cpfl_itf *itf) 339 : : { 340 : : struct cpfl_vport_info *info; 341 : : uint32_t vport_id; 342 : : int ret; 343 : : struct cpfl_vport_id vport_identity; 344 : : u16 vsi_id = 0; 345 : : 346 [ # # ]: 0 : if (!itf) 347 : : return CPFL_INVALID_HW_ID; 348 : : 349 [ # # ]: 0 : if (itf->type == CPFL_ITF_TYPE_REPRESENTOR) { 350 : : struct cpfl_repr *repr = (void *)itf; 351 : : 352 : 0 : return repr->vport_info->vport.info.vsi_id; 353 [ # # ]: 0 : } else if (itf->type == CPFL_ITF_TYPE_VPORT) { 354 [ # # ]: 0 : if (!idpf_is_vf_device(&itf->adapter->base.hw)) { 355 : 0 : vport_id = ((struct cpfl_vport *)itf)->base.vport_id; 356 : : 357 : 0 : vport_identity.func_type = CPCHNL2_FTYPE_LAN_PF; 358 : : /* host: CPFL_HOST0_CPF_ID, acc: CPFL_ACC_CPF_ID */ 359 [ # # ]: 0 : vport_identity.pf_id = (itf->adapter->host_id == CPFL_HOST_ID_ACC) ? 360 : : CPFL_ACC_CPF_ID : CPFL_HOST0_CPF_ID; 361 : 0 : vport_identity.vf_id = 0; 362 : 0 : vport_identity.vport_id = vport_id; 363 : 0 : ret = rte_hash_lookup_data(itf->adapter->vport_map_hash, 364 : : &vport_identity, 365 : : (void **)&info); 366 [ # # ]: 0 : if (ret < 0) { 367 : 0 : PMD_DRV_LOG(ERR, "vport id not exist"); 368 : 0 : goto err; 369 : : } 370 : : 371 : 0 : vsi_id = info->vport.info.vsi_id; 372 : : } else { 373 [ # # ]: 0 : if (idpf_is_vf_device(&itf->adapter->base.hw)) 374 : 0 : vsi_id = (uint16_t)((struct cpfl_vport *)itf)->vport_info.vsi_id; 375 : : } 376 : : } 377 : : return vsi_id; 378 : : 379 : : err: 380 : 0 : return CPFL_INVALID_HW_ID; 381 : : } 382 : : 383 : : static inline struct cpfl_itf * 384 : 0 : cpfl_get_itf_by_port_id(uint16_t port_id) 385 : : { 386 : : struct rte_eth_dev *dev; 387 : : 388 [ # # ]: 0 : if (port_id >= RTE_MAX_ETHPORTS) { 389 : 0 : PMD_DRV_LOG(ERR, "port_id should be < %d.", RTE_MAX_ETHPORTS); 390 : 0 : return NULL; 391 : : } 392 : : 393 : 0 : dev = &rte_eth_devices[port_id]; 394 [ # # ]: 0 : if (dev->state == RTE_ETH_DEV_UNUSED) { 395 : 0 : PMD_DRV_LOG(ERR, "eth_dev[%d] is unused.", port_id); 396 : 0 : return NULL; 397 : : } 398 : : 399 [ # # ]: 0 : if (!dev->data) { 400 : 0 : PMD_DRV_LOG(ERR, "eth_dev[%d] data not be allocated.", port_id); 401 : 0 : return NULL; 402 : : } 403 : : 404 : 0 : return CPFL_DEV_TO_ITF(dev); 405 : : } 406 : : 407 : : static inline uint32_t 408 : : vcpf_get_abs_qid(uint16_t port_id, uint32_t queue_type) 409 : : { 410 : : struct cpfl_itf *itf = cpfl_get_itf_by_port_id(port_id); 411 : : struct cpfl_vport *vport; 412 : : if (!itf) 413 : : return CPFL_INVALID_HW_ID; 414 : : if (itf->type == CPFL_ITF_TYPE_VPORT) { 415 : : vport = (void *)itf; 416 : : if (idpf_is_vf_device(&itf->adapter->base.hw)) { 417 : : switch (queue_type) { 418 : : case VIRTCHNL2_QUEUE_TYPE_TX: 419 : : return vport->vport_info.abs_start_txq_id; 420 : : case VIRTCHNL2_QUEUE_TYPE_RX: 421 : : return vport->vport_info.abs_start_rxq_id; 422 : : } 423 : : } 424 : : } 425 : : return 0; 426 : : } 427 : : #endif /* _CPFL_ETHDEV_H_ */