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