Hi, > -----Original Message----- > From: Junfeng Guo <junfeng....@intel.com> > Sent: Wednesday, August 3, 2022 2:31 PM > To: qi.z.zh...@intel.com; jingjing...@intel.com; beilei.x...@intel.com > Cc: dev@dpdk.org; junfeng....@intel.com; Xiaoyun Li > <xiaoyun...@intel.com>; Xiao Wang <xiao.w.w...@intel.com> > Subject: [PATCH 03/13] net/idpf: support device initialization > > Support device init and the following dev ops: > - dev_configure > - dev_start > - dev_stop > - dev_close > > Signed-off-by: Beilei Xing <beilei.x...@intel.com> > Signed-off-by: Xiaoyun Li <xiaoyun...@intel.com> > Signed-off-by: Xiao Wang <xiao.w.w...@intel.com> > Signed-off-by: Junfeng Guo <junfeng....@intel.com> > --- > drivers/net/idpf/idpf_ethdev.c | 651 > +++++++++++++++++++++++++++++++++ drivers/net/idpf/idpf_ethdev.h > | 205 +++++++++++ drivers/net/idpf/idpf_vchnl.c | 476 > ++++++++++++++++++++++++ > drivers/net/idpf/meson.build | 18 + > drivers/net/idpf/version.map | 3 + > drivers/net/meson.build | 1 + > 6 files changed, 1354 insertions(+) > create mode 100644 drivers/net/idpf/idpf_ethdev.c create mode 100644 > drivers/net/idpf/idpf_ethdev.h create mode 100644 > drivers/net/idpf/idpf_vchnl.c create mode 100644 > drivers/net/idpf/meson.build create mode 100644 > drivers/net/idpf/version.map > > diff --git a/drivers/net/idpf/idpf_ethdev.c b/drivers/net/idpf/idpf_ethdev.c > new file mode 100644 index 0000000000..87c68226dd > --- /dev/null > +++ b/drivers/net/idpf/idpf_ethdev.c > @@ -0,0 +1,651 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#include <rte_atomic.h> > +#include <rte_eal.h> > +#include <rte_ether.h> > +#include <ethdev_driver.h> > +#include <ethdev_pci.h> > +#include <rte_malloc.h> > +#include <rte_memzone.h> > +#include <rte_dev.h> > + > +#include "idpf_ethdev.h" > + > +#define REPRESENTOR "representor" > + > +struct idpf_adapter *adapter; > +uint16_t used_vecs_num; > + > +static const char * const idpf_valid_args[] = { > + REPRESENTOR, > + NULL > +}; > + > +static int idpf_dev_configure(struct rte_eth_dev *dev); static int > +idpf_dev_start(struct rte_eth_dev *dev); static int > +idpf_dev_stop(struct rte_eth_dev *dev); static int > +idpf_dev_close(struct rte_eth_dev *dev); > + > +static const struct eth_dev_ops idpf_eth_dev_ops = { > + .dev_configure = idpf_dev_configure, > + .dev_start = idpf_dev_start, > + .dev_stop = idpf_dev_stop, > + .dev_close = idpf_dev_close, > +}; > + > +static int > +idpf_init_vport_req_info(struct rte_eth_dev *dev) { > + struct virtchnl2_create_vport *vport_info; > + uint16_t idx = adapter->next_vport_idx; > + > + if (!adapter->vport_req_info[idx]) { > + adapter->vport_req_info[idx] = rte_zmalloc(NULL, > + sizeof(struct virtchnl2_create_vport), 0); > + if (!adapter->vport_req_info[idx]) { > + PMD_INIT_LOG(ERR, "Failed to allocate > vport_req_info"); > + return -1; > + } > + } > + > + vport_info = > + (struct virtchnl2_create_vport *)adapter- > >vport_req_info[idx]; > + > + vport_info->vport_type = > +rte_cpu_to_le_16(VIRTCHNL2_VPORT_TYPE_DEFAULT); > + > + return 0; > +} > + > +static uint16_t > +idpf_get_next_vport_idx(struct idpf_vport **vports, uint16_t > max_vport_nb, > + uint16_t cur_vport_idx) > +{ > + uint16_t vport_idx; > + uint16_t i; > + > + if (cur_vport_idx < max_vport_nb && !vports[cur_vport_idx + 1]) { > + vport_idx = cur_vport_idx + 1; > + return vport_idx; > + } > + > + for (i = 0; i < max_vport_nb; i++) { > + if (!vports[i]) > + break; > + } > + > + if (i == max_vport_nb) > + vport_idx = IDPF_INVALID_VPORT_IDX; > + else > + vport_idx = i; > + > + return vport_idx; > +} > + > +#ifndef IDPF_RSS_KEY_LEN > +#define IDPF_RSS_KEY_LEN 52 > +#endif > + > +static int > +idpf_init_vport(struct rte_eth_dev *dev) { > + uint16_t idx = adapter->next_vport_idx; > + struct virtchnl2_create_vport *vport_info = > + (struct virtchnl2_create_vport *)adapter- > >vport_recv_info[idx]; > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + int i; > + > + vport->adapter = adapter; > + vport->vport_id = vport_info->vport_id; > + vport->txq_model = vport_info->txq_model; > + vport->rxq_model = vport_info->rxq_model; > + vport->num_tx_q = vport_info->num_tx_q; > + vport->num_tx_complq = vport_info->num_tx_complq; > + vport->num_rx_q = vport_info->num_rx_q; > + vport->num_rx_bufq = vport_info->num_rx_bufq; > + vport->max_mtu = vport_info->max_mtu; > + rte_memcpy(vport->default_mac_addr, > + vport_info->default_mac_addr, ETH_ALEN); > + vport->rss_algorithm = vport_info->rss_algorithm; > + vport->rss_key_size = RTE_MIN(IDPF_RSS_KEY_LEN, > + vport_info->rss_key_size); > + vport->rss_lut_size = vport_info->rss_lut_size; > + vport->sw_idx = idx; > + > + for (i = 0; i < vport_info->chunks.num_chunks; i++) { > + if (vport_info->chunks.chunks[i].type == > + VIRTCHNL2_QUEUE_TYPE_TX) { > + vport->chunks_info.tx_start_qid = > + vport_info- > >chunks.chunks[i].start_queue_id; > + vport->chunks_info.tx_qtail_start = > + vport_info- > >chunks.chunks[i].qtail_reg_start; > + vport->chunks_info.tx_qtail_spacing = > + vport_info- > >chunks.chunks[i].qtail_reg_spacing; > + } else if (vport_info->chunks.chunks[i].type == > + VIRTCHNL2_QUEUE_TYPE_RX) { > + vport->chunks_info.rx_start_qid = > + vport_info- > >chunks.chunks[i].start_queue_id; > + vport->chunks_info.rx_qtail_start = > + vport_info- > >chunks.chunks[i].qtail_reg_start; > + vport->chunks_info.rx_qtail_spacing = > + vport_info- > >chunks.chunks[i].qtail_reg_spacing; > + } else if (vport_info->chunks.chunks[i].type == > + VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION) { > + vport->chunks_info.tx_compl_start_qid = > + vport_info- > >chunks.chunks[i].start_queue_id; > + vport->chunks_info.tx_compl_qtail_start = > + vport_info- > >chunks.chunks[i].qtail_reg_start; > + vport->chunks_info.tx_compl_qtail_spacing = > + vport_info- > >chunks.chunks[i].qtail_reg_spacing; > + } else if (vport_info->chunks.chunks[i].type == > + VIRTCHNL2_QUEUE_TYPE_RX_BUFFER) { > + vport->chunks_info.rx_buf_start_qid = > + vport_info- > >chunks.chunks[i].start_queue_id; > + vport->chunks_info.rx_buf_qtail_start = > + vport_info- > >chunks.chunks[i].qtail_reg_start; > + vport->chunks_info.rx_buf_qtail_spacing = > + vport_info- > >chunks.chunks[i].qtail_reg_spacing; > + } > + } > + > + adapter->vports[idx] = vport; > + adapter->cur_vport_nb++; > + adapter->next_vport_idx = idpf_get_next_vport_idx(adapter- > >vports, > + adapter->max_vport_nb, > idx); > + if (adapter->next_vport_idx == IDPF_INVALID_VPORT_IDX) { > + PMD_INIT_LOG(ERR, "Failed to get next vport id"); > + return -1; > + } > + > + return 0; > +} > + > +static int > +idpf_dev_configure(struct rte_eth_dev *dev) { > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + int ret = 0; > + > + ret = idpf_init_vport_req_info(dev); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to init vport req_info."); > + return ret; > + } > + > + ret = idpf_create_vport(dev); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to create vport."); > + return ret; > + } > + > + ret = idpf_init_vport(dev); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to init vports."); > + return ret; > + } > + > + rte_ether_addr_copy((struct rte_ether_addr *)vport- > >default_mac_addr, > + &dev->data->mac_addrs[0]); > + > + return ret; > +} > + > +static int > +idpf_dev_start(struct rte_eth_dev *dev) { > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + > + PMD_INIT_FUNC_TRACE(); > + > + vport->stopped = 0; > + > + if (idpf_ena_dis_vport(vport, true)) { > + PMD_DRV_LOG(ERR, "Failed to enable vport"); > + goto err_vport; > + } > + > + return 0; > + > +err_vport: > + return -1; > +} > + > +static int > +idpf_dev_stop(struct rte_eth_dev *dev) > +{ > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + > + PMD_INIT_FUNC_TRACE(); > + > + if (vport->stopped == 1) > + return 0; > + > + if (idpf_ena_dis_vport(vport, false)) > + PMD_DRV_LOG(ERR, "disable vport failed"); > + > + vport->stopped = 1; > + dev->data->dev_started = 0; > + > + return 0; > +} > + > +static int > +idpf_dev_close(struct rte_eth_dev *dev) { > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) > + return 0; > + > + idpf_dev_stop(dev); > + idpf_destroy_vport(vport); > + > + return 0; > +} > + > +static int idpf_parse_devargs(struct rte_eth_dev *dev) { > + struct rte_devargs *devargs = dev->device->devargs; > + struct rte_kvargs *kvlist; > + int ret = 0; > + > + if (!devargs) > + return 0; > + > + kvlist = rte_kvargs_parse(devargs->args, idpf_valid_args); > + if (!kvlist) { > + PMD_INIT_LOG(ERR, "invalid kvargs key"); > + return -EINVAL; > + } > + > + rte_kvargs_free(kvlist); > + return ret; > +} > + > +static void > +idpf_reset_pf(struct iecm_hw *hw) > +{ > + uint32_t reg; > + > + reg = IECM_READ_REG(hw, PFGEN_CTRL); > + IECM_WRITE_REG(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR)); } > + > +#define IDPF_RESET_WAIT_CNT 100 > +static int > +idpf_check_pf_reset_done(struct iecm_hw *hw) { > + uint32_t reg; > + int i; > + > + for (i = 0; i < IDPF_RESET_WAIT_CNT; i++) { > + reg = IECM_READ_REG(hw, PFGEN_RSTAT); > + if (reg != 0xFFFFFFFF && (reg & > PFGEN_RSTAT_PFR_STATE_M)) > + return 0; > + rte_delay_ms(1000); > + } > + > + PMD_INIT_LOG(ERR, "IDPF reset timeout"); > + return -EBUSY; > +} > + > +#define CTLQ_NUM 2 > +static int > +idpf_init_mbx(struct iecm_hw *hw) > +{ > + struct iecm_ctlq_create_info ctlq_info[CTLQ_NUM] = { > + { > + .type = IECM_CTLQ_TYPE_MAILBOX_TX, > + .id = IDPF_CTLQ_ID, > + .len = IDPF_CTLQ_LEN, > + .buf_size = IDPF_DFLT_MBX_BUF_SIZE, > + .reg = { > + .head = PF_FW_ATQH, > + .tail = PF_FW_ATQT, > + .len = PF_FW_ATQLEN, > + .bah = PF_FW_ATQBAH, > + .bal = PF_FW_ATQBAL, > + .len_mask = PF_FW_ATQLEN_ATQLEN_M, > + .len_ena_mask = > PF_FW_ATQLEN_ATQENABLE_M, > + .head_mask = PF_FW_ATQH_ATQH_M, > + } > + }, > + { > + .type = IECM_CTLQ_TYPE_MAILBOX_RX, > + .id = IDPF_CTLQ_ID, > + .len = IDPF_CTLQ_LEN, > + .buf_size = IDPF_DFLT_MBX_BUF_SIZE, > + .reg = { > + .head = PF_FW_ARQH, > + .tail = PF_FW_ARQT, > + .len = PF_FW_ARQLEN, > + .bah = PF_FW_ARQBAH, > + .bal = PF_FW_ARQBAL, > + .len_mask = PF_FW_ARQLEN_ARQLEN_M, > + .len_ena_mask = > PF_FW_ARQLEN_ARQENABLE_M, > + .head_mask = PF_FW_ARQH_ARQH_M, > + } > + } > + }; > + struct iecm_ctlq_info *ctlq; > + int ret = 0; > + > + ret = iecm_ctlq_init(hw, CTLQ_NUM, ctlq_info); > + if (ret) > + return ret; > + > + LIST_FOR_EACH_ENTRY_SAFE(ctlq, NULL, &hw->cq_list_head, > + struct iecm_ctlq_info, cq_list) { > + if (ctlq->q_id == IDPF_CTLQ_ID && ctlq->cq_type == > IECM_CTLQ_TYPE_MAILBOX_TX) > + hw->asq = ctlq; > + if (ctlq->q_id == IDPF_CTLQ_ID && ctlq->cq_type == > IECM_CTLQ_TYPE_MAILBOX_RX) > + hw->arq = ctlq; > + } > + > + if (!hw->asq || !hw->arq) { > + iecm_ctlq_deinit(hw); > + ret = -ENOENT; > + } > + > + return ret; > +} > + > +static int > +idpf_adapter_init(struct rte_eth_dev *dev) { > + struct iecm_hw *hw = &adapter->hw; > + struct rte_pci_device *pci_dev = IDPF_DEV_TO_PCI(dev); > + int ret = 0; > + > + if (adapter->initialized) > + return 0; > + > + hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; > + hw->hw_addr_len = pci_dev->mem_resource[0].len; > + hw->back = adapter; > + hw->vendor_id = pci_dev->id.vendor_id; > + hw->device_id = pci_dev->id.device_id; > + hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id; > + > + ret = idpf_parse_devargs(dev); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to parse devargs"); > + goto err; > + } > + > + idpf_reset_pf(hw); > + ret = idpf_check_pf_reset_done(hw); > + if (ret) { > + PMD_INIT_LOG(ERR, "IDPF is still resetting"); > + goto err; > + } > + > + ret = idpf_init_mbx(hw); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to init mailbox"); > + goto err; > + } > + > + adapter->mbx_resp = rte_zmalloc("idpf_adapter_mbx_resp", > IDPF_DFLT_MBX_BUF_SIZE, 0); > + if (!adapter->mbx_resp) { > + PMD_INIT_LOG(ERR, "Failed to allocate > idpf_adapter_mbx_resp memory"); > + goto err_mbx; > + } > + > + if (idpf_check_api_version(adapter)) { > + PMD_INIT_LOG(ERR, "Failed to check api version"); > + goto err_api; > + } > + > + adapter->caps = rte_zmalloc("idpf_caps", > + sizeof(struct virtchnl2_get_capabilities), 0); > + if (!adapter->caps) { > + PMD_INIT_LOG(ERR, "Failed to allocate idpf_caps memory"); > + goto err_api; > + } > + > + if (idpf_get_caps(adapter)) { > + PMD_INIT_LOG(ERR, "Failed to get capabilities"); > + goto err_caps; > + } > + > + adapter->max_vport_nb = adapter->caps->max_vports; > + > + adapter->vport_req_info = rte_zmalloc("vport_req_info", > + adapter->max_vport_nb * > + sizeof(*adapter- > >vport_req_info), > + 0); > + if (!adapter->vport_req_info) { > + PMD_INIT_LOG(ERR, "Failed to allocate vport_req_info > memory"); > + goto err_caps; > + } > + > + adapter->vport_recv_info = rte_zmalloc("vport_recv_info", > + adapter->max_vport_nb * > + sizeof(*adapter- > >vport_recv_info), > + 0); > + if (!adapter->vport_recv_info) { > + PMD_INIT_LOG(ERR, "Failed to allocate vport_recv_info > memory"); > + goto err_vport_recv_info; > + } > + > + adapter->vports = rte_zmalloc("vports", > + adapter->max_vport_nb * > + sizeof(*adapter->vports), > + 0); > + if (!adapter->vports) { > + PMD_INIT_LOG(ERR, "Failed to allocate vports memory"); > + goto err_vports; > + } > + > + adapter->max_rxq_per_msg = (IDPF_DFLT_MBX_BUF_SIZE - > + sizeof(struct virtchnl2_config_rx_queues)) / > + sizeof(struct virtchnl2_rxq_info); > + adapter->max_txq_per_msg = (IDPF_DFLT_MBX_BUF_SIZE - > + sizeof(struct virtchnl2_config_tx_queues)) / > + sizeof(struct virtchnl2_txq_info); > + > + adapter->cur_vport_nb = 0; > + adapter->next_vport_idx = 0; > + adapter->initialized = true; > + > + return ret; > + > +err_vports: > + rte_free(adapter->vports); > + adapter->vports = NULL; > +err_vport_recv_info: > + rte_free(adapter->vport_req_info); > + adapter->vport_req_info = NULL; > +err_caps: > + rte_free(adapter->caps); > + adapter->caps = NULL; > +err_api: > + rte_free(adapter->mbx_resp); > + adapter->mbx_resp = NULL; > +err_mbx: > + iecm_ctlq_deinit(hw); > +err: > + return -1; > +} > + > + > +static int > +idpf_dev_init(struct rte_eth_dev *dev, __rte_unused void *init_params) > +{ > + struct idpf_vport *vport = > + (struct idpf_vport *)dev->data->dev_private; > + int ret = 0; > + > + PMD_INIT_FUNC_TRACE(); > + > + dev->dev_ops = &idpf_eth_dev_ops; > + > + /* for secondary processes, we don't initialise any further as primary > + * has already done this work. > + */ > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) > + return ret; > + > + ret = idpf_adapter_init(dev); > + if (ret) { > + PMD_INIT_LOG(ERR, "Failed to init adapter."); > + return ret; > + } > + > + dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; > + > + vport->dev_data = dev->data; > + > + dev->data->mac_addrs = rte_zmalloc(NULL, RTE_ETHER_ADDR_LEN, > 0); > + if (dev->data->mac_addrs == NULL) { > + PMD_INIT_LOG(ERR, "Cannot allocate mac_addr memory."); > + ret = -ENOMEM; > + goto err; > + } > + > +err: > + return ret; > +} > + > +static int > +idpf_dev_uninit(struct rte_eth_dev *dev) { > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) > + return -EPERM; > + > + idpf_dev_close(dev); > + > + return 0; > +} > + > +static const struct rte_pci_id pci_id_idpf_map[] = { > + { RTE_PCI_DEVICE(IECM_INTEL_VENDOR_ID, IECM_DEV_ID_PF) }, > + { .vendor_id = 0, /* sentinel */ }, > +}; > + > +static int > +idpf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, > + struct rte_pci_device *pci_dev) > +{ > + struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; > + char name[RTE_ETH_NAME_MAX_LEN]; > + int i, retval; > + > + if (pci_dev->device.devargs) { > + retval = rte_eth_devargs_parse(pci_dev->device.devargs- > >args, > + ð_da); > + if (retval) > + return retval; > + } > + > + if (!eth_da.nb_representor_ports) { > + PMD_INIT_LOG(ERR, "Failed to probe, need to add > representor devargs."); > + return -1; > + } > + > + if (!adapter) { > + adapter = (struct idpf_adapter *)rte_zmalloc("idpf_adapter", > + sizeof(struct idpf_adapter), 0); > + if (!adapter) { > + PMD_INIT_LOG(ERR, "Failed to allocate adapter."); > + return -1; > + } > + } > + > + for (i = 0; i < eth_da.nb_representor_ports; i++) { > + snprintf(name, sizeof(name), "idpf_vport_%d", > + eth_da.representor_ports[i]); > + retval = rte_eth_dev_create(&pci_dev->device, name, > + sizeof(struct idpf_vport), > + NULL, NULL, idpf_dev_init, > + NULL); > + if (retval) > + PMD_DRV_LOG(ERR, "failed to creat vport %d", i); > + } > + > + return 0; > +} > + > +static void > +idpf_adapter_rel(struct idpf_adapter *adapter) { > + struct iecm_hw *hw = &adapter->hw; > + int i; > + > + iecm_ctlq_deinit(hw); > + > + if (adapter->caps) { > + rte_free(adapter->caps); > + adapter->caps = NULL; > + } > + > + if (adapter->mbx_resp) { > + rte_free(adapter->mbx_resp); > + adapter->mbx_resp = NULL; > + } > + > + if (adapter->vport_req_info) { > + for (i = 0; i < adapter->max_vport_nb; i++) { > + if (adapter->vport_req_info[i]) { > + rte_free(adapter->vport_req_info[i]); > + adapter->vport_req_info[i] = NULL; > + } > + } > + rte_free(adapter->vport_req_info); > + adapter->vport_req_info = NULL; > + } > + > + if (adapter->vport_recv_info) { > + for (i = 0; i < adapter->max_vport_nb; i++) { > + if (adapter->vport_recv_info[i]) { > + rte_free(adapter->vport_recv_info[i]); > + adapter->vport_recv_info[i] = NULL; > + } > + } > + } > + > + if (adapter->vports) { > + /* Needn't free adapter->vports[i] since it's private data */ > + rte_free(adapter->vports); > + adapter->vports = NULL; > + } > +} > + > +static int > +idpf_pci_remove(struct rte_pci_device *pci_dev) { > + if (adapter) { > + idpf_adapter_rel(adapter); > + rte_free(adapter); > + adapter = NULL; > + } > + > + return rte_eth_dev_pci_generic_remove(pci_dev, idpf_dev_uninit); > } > + > +static struct rte_pci_driver rte_idpf_pmd = { > + .id_table = pci_id_idpf_map, > + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | > RTE_PCI_DRV_INTR_LSC | > + RTE_PCI_DRV_PROBE_AGAIN, > + .probe = idpf_pci_probe, > + .remove = idpf_pci_remove, > +}; > + > +/** > + * Driver initialization routine. > + * Invoked once at EAL init time. > + * Register itself as the [Poll Mode] Driver of PCI devices. > + */ > +RTE_PMD_REGISTER_PCI(net_idpf, rte_idpf_pmd); > +RTE_PMD_REGISTER_PCI_TABLE(net_idpf, pci_id_idpf_map); > +RTE_PMD_REGISTER_KMOD_DEP(net_ice, "* igb_uio | uio_pci_generic | > +vfio-pci"); > + > +RTE_LOG_REGISTER_SUFFIX(idpf_logtype_init, init, NOTICE); > +RTE_LOG_REGISTER_SUFFIX(idpf_logtype_driver, driver, NOTICE); > diff --git a/drivers/net/idpf/idpf_ethdev.h b/drivers/net/idpf/idpf_ethdev.h > new file mode 100644 index 0000000000..501f772fa8 > --- /dev/null > +++ b/drivers/net/idpf/idpf_ethdev.h > @@ -0,0 +1,205 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#ifndef _IDPF_ETHDEV_H_ > +#define _IDPF_ETHDEV_H_ > + > +#include <stdint.h> > +#include <rte_mbuf.h> > +#include <rte_mempool.h> > +#include <rte_malloc.h> > +#include <rte_spinlock.h> > +#include <rte_ethdev.h> > +#include <rte_kvargs.h> > +#include <ethdev_driver.h> > + > +#include "base/iecm_osdep.h" > +#include "base/iecm_type.h" > +#include "base/iecm_devids.h" > +#include "base/iecm_lan_txrx.h" > +#include "base/iecm_lan_pf_regs.h" > +#include "base/virtchnl.h" > +#include "base/virtchnl2.h" > + > +#define IDPF_INVALID_VPORT_IDX 0xffff > +#define IDPF_TXQ_PER_GRP 1 > +#define IDPF_TX_COMPLQ_PER_GRP 1 > +#define IDPF_RXQ_PER_GRP 1 > +#define IDPF_RX_BUFQ_PER_GRP 2 > + > +#define IDPF_CTLQ_ID -1 > +#define IDPF_CTLQ_LEN 64 > +#define IDPF_DFLT_MBX_BUF_SIZE 4096 > + > +#define IDPF_DFLT_Q_VEC_NUM 1 > +#define IDPF_DFLT_INTERVAL 16 > + > +#define IDPF_MAX_NUM_QUEUES 256 > +#define IDPF_MIN_BUF_SIZE 1024 > +#define IDPF_MAX_FRAME_SIZE 9728 > + > +#define IDPF_NUM_MACADDR_MAX 64 > + > +#define IDPF_MAX_PKT_TYPE 1024 > + > +#define IDPF_VLAN_TAG_SIZE 4 > +#define IDPF_ETH_OVERHEAD \ > + (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + > IDPF_VLAN_TAG_SIZE * 2) > + > +#ifndef ETH_ADDR_LEN > +#define ETH_ADDR_LEN 6 > +#endif > + > +/* Message type read in virtual channel from PF */ enum idpf_vc_result > +{ > + IDPF_MSG_ERR = -1, /* Meet error when accessing admin queue */ > + IDPF_MSG_NON, /* Read nothing from admin queue */ > + IDPF_MSG_SYS, /* Read system msg from admin queue */ > + IDPF_MSG_CMD, /* Read async command result */ > +}; > + > +struct idpf_chunks_info { > + uint32_t tx_start_qid; > + uint32_t rx_start_qid; > + /* Valid only if split queue model */ > + uint32_t tx_compl_start_qid; > + uint32_t rx_buf_start_qid; > + > + uint64_t tx_qtail_start; > + uint32_t tx_qtail_spacing; > + uint64_t rx_qtail_start; > + uint32_t rx_qtail_spacing; > + uint64_t tx_compl_qtail_start; > + uint32_t tx_compl_qtail_spacing; > + uint64_t rx_buf_qtail_start; > + uint32_t rx_buf_qtail_spacing; > +}; > + > +struct idpf_vport { > + struct idpf_adapter *adapter; /* Backreference to associated > adapter */ > + uint16_t vport_id; > + uint32_t txq_model; > + uint32_t rxq_model; > + uint16_t num_tx_q; > + /* valid only if txq_model is split Q */ > + uint16_t num_tx_complq; > + uint16_t num_rx_q; > + /* valid only if rxq_model is split Q */ > + uint16_t num_rx_bufq; > + > + uint16_t max_mtu; > + uint8_t default_mac_addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS]; > + > + enum virtchnl_rss_algorithm rss_algorithm; > + uint16_t rss_key_size; > + uint16_t rss_lut_size; > + > + uint16_t sw_idx; /* SW idx */ > + > + struct rte_eth_dev_data *dev_data; /* Pointer to the device data */ > + uint16_t max_pkt_len; /* Maximum packet length */ > + > + /* RSS info */ > + uint32_t *rss_lut; > + uint8_t *rss_key; > + uint64_t rss_hf; > + > + /* Chunk info */ > + struct idpf_chunks_info chunks_info; > + > + /* Event from ipf */ > + bool link_up; > + uint32_t link_speed; > + > + bool stopped; > + struct virtchnl2_vport_stats eth_stats_offset; }; > + > +struct idpf_adapter { > + struct iecm_hw hw; > + > + struct virtchnl_version_info virtchnl_version; > + struct virtchnl2_get_capabilities *caps; > + > + volatile enum virtchnl_ops pend_cmd; /* pending command not > finished */ > + uint32_t cmd_retval; /* return value of the cmd response from ipf */ > + uint8_t *mbx_resp; /* buffer to store the mailbox response from ipf > */ > + > + uint32_t txq_model; > + uint32_t rxq_model; > + > + /* Vport info */ > + uint8_t **vport_req_info; > + uint8_t **vport_recv_info; > + struct idpf_vport **vports; > + uint16_t max_vport_nb; > + uint16_t cur_vport_nb; > + uint16_t next_vport_idx; > + > + /* Max config queue number per VC message */ > + uint32_t max_rxq_per_msg; > + uint32_t max_txq_per_msg; > + > + uint32_t ptype_tbl[IDPF_MAX_PKT_TYPE] > __rte_cache_min_aligned; > + > + bool initialized; > + bool stopped; > +}; > + > +extern struct idpf_adapter *adapter; > + > +#define IDPF_DEV_TO_PCI(eth_dev) \ > + RTE_DEV_TO_PCI((eth_dev)->device) > + > +/* structure used for sending and checking response of virtchnl ops */ > +struct idpf_cmd_info { > + uint32_t ops; > + uint8_t *in_args; /* buffer for sending */ > + uint32_t in_args_size; /* buffer size for sending */ > + uint8_t *out_buffer; /* buffer for response */ > + uint32_t out_size; /* buffer size for response */ > +}; > + > +/* notify current command done. Only call in case execute > + * _atomic_set_cmd successfully. > + */ > +static inline void > +_notify_cmd(struct idpf_adapter *adapter, int msg_ret) { > + adapter->cmd_retval = msg_ret; > + rte_wmb(); > + adapter->pend_cmd = VIRTCHNL_OP_UNKNOWN; } > + > +/* clear current command. Only call in case execute > + * _atomic_set_cmd successfully. > + */ > +static inline void > +_clear_cmd(struct idpf_adapter *adapter) { > + rte_wmb(); > + adapter->pend_cmd = VIRTCHNL_OP_UNKNOWN; > + adapter->cmd_retval = VIRTCHNL_STATUS_SUCCESS; } > + > +/* Check there is pending cmd in execution. If none, set new command. > +*/ static inline int _atomic_set_cmd(struct idpf_adapter *adapter, enum > +virtchnl_ops ops) { > + int ret = rte_atomic32_cmpset(&adapter->pend_cmd, > VIRTCHNL_OP_UNKNOWN, > +ops); > + > + if (!ret) > + PMD_DRV_LOG(ERR, "There is incomplete cmd %d", > adapter->pend_cmd); > + > + return !ret; > +} > + > +void idpf_handle_virtchnl_msg(struct rte_eth_dev *dev); int > +idpf_check_api_version(struct idpf_adapter *adapter); int > +idpf_get_caps(struct idpf_adapter *adapter); int > +idpf_create_vport(__rte_unused struct rte_eth_dev *dev); int > +idpf_destroy_vport(struct idpf_vport *vport); int > +idpf_ena_dis_vport(struct idpf_vport *vport, bool enable); > + > +#endif /* _IDPF_ETHDEV_H_ */ > diff --git a/drivers/net/idpf/idpf_vchnl.c b/drivers/net/idpf/idpf_vchnl.c new > file mode 100644 index 0000000000..4fc15d5b71 > --- /dev/null > +++ b/drivers/net/idpf/idpf_vchnl.c > @@ -0,0 +1,476 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#include <stdio.h> > +#include <errno.h> > +#include <stdint.h> > +#include <string.h> > +#include <unistd.h> > +#include <stdarg.h> > +#include <inttypes.h> > +#include <rte_byteorder.h> > +#include <rte_common.h> > + > +#include <rte_debug.h> > +#include <rte_atomic.h> > +#include <rte_eal.h> > +#include <rte_ether.h> > +#include <ethdev_driver.h> > +#include <ethdev_pci.h> > +#include <rte_dev.h> > + > +#include "idpf_ethdev.h" > + > +#include "base/iecm_prototype.h" > + > +#define IDPF_CTLQ_LEN 64 > + > +static int > +idpf_vc_clean(struct idpf_adapter *adapter) { > + struct iecm_ctlq_msg *q_msg[IDPF_CTLQ_LEN]; > + uint16_t num_q_msg = IDPF_CTLQ_LEN; > + struct iecm_dma_mem *dma_mem; > + int err = 0; > + uint32_t i; > + > + for (i = 0; i < 10; i++) { > + err = iecm_ctlq_clean_sq(adapter->hw.asq, &num_q_msg, > q_msg); > + msleep(20); > + if (num_q_msg) > + break; > + } > + if (err) > + goto error; > + > + /* Empty queue is not an error */ > + for (i = 0; i < num_q_msg; i++) { > + dma_mem = q_msg[i]->ctx.indirect.payload; > + if (dma_mem) { > + iecm_free_dma_mem(&adapter->hw, dma_mem); > + rte_free(dma_mem); > + } > + rte_free(q_msg[i]); > + } > + > +error: > + return err; > +} > + > +static int > +idpf_send_vc_msg(struct idpf_adapter *adapter, enum virtchnl_ops op, > + uint16_t msg_size, uint8_t *msg) > +{ > + struct iecm_ctlq_msg *ctlq_msg; > + struct iecm_dma_mem *dma_mem; > + int err = 0; > + > + err = idpf_vc_clean(adapter); > + if (err) > + goto err; > + > + ctlq_msg = (struct iecm_ctlq_msg *)rte_zmalloc(NULL, > + sizeof(struct iecm_ctlq_msg), 0); > + if (!ctlq_msg) { > + err = -ENOMEM; > + goto err; > + } > + > + dma_mem = (struct iecm_dma_mem *)rte_zmalloc(NULL, > + sizeof(struct iecm_dma_mem), 0); > + if (!dma_mem) { > + err = -ENOMEM; > + goto dma_mem_error; > + } > + > + dma_mem->size = IDPF_DFLT_MBX_BUF_SIZE; > + iecm_alloc_dma_mem(&adapter->hw, dma_mem, dma_mem- > >size); > + if (!dma_mem->va) { > + err = -ENOMEM; > + goto dma_alloc_error; > + } > + > + memcpy(dma_mem->va, msg, msg_size); > + > + ctlq_msg->opcode = iecm_mbq_opc_send_msg_to_pf; > + ctlq_msg->func_id = 0; > + ctlq_msg->data_len = msg_size; > + ctlq_msg->cookie.mbx.chnl_opcode = op; > + ctlq_msg->cookie.mbx.chnl_retval = VIRTCHNL_STATUS_SUCCESS; > + ctlq_msg->ctx.indirect.payload = dma_mem; > + > + err = iecm_ctlq_send(&adapter->hw, adapter->hw.asq, 1, ctlq_msg); > + if (err) > + goto send_error; > + > + return err; > + > +send_error: > + iecm_free_dma_mem(&adapter->hw, dma_mem); > +dma_alloc_error: > + rte_free(dma_mem); > +dma_mem_error: > + rte_free(ctlq_msg); > +err: > + return err; > +} > + > +static enum idpf_vc_result > +idpf_read_msg_from_ipf(struct idpf_adapter *adapter, uint16_t buf_len, > + uint8_t *buf) > +{ > + struct iecm_hw *hw = &adapter->hw; > + struct iecm_ctlq_msg ctlq_msg; > + struct iecm_dma_mem *dma_mem = NULL; > + enum idpf_vc_result result = IDPF_MSG_NON; > + enum virtchnl_ops opcode; > + uint16_t pending = 1; > + int ret; > + > + ret = iecm_ctlq_recv(hw->arq, &pending, &ctlq_msg); > + if (ret) { > + PMD_DRV_LOG(DEBUG, "Can't read msg from AQ"); > + if (ret != IECM_ERR_CTLQ_NO_WORK) > + result = IDPF_MSG_ERR; > + return result; > + } > + > + rte_memcpy(buf, ctlq_msg.ctx.indirect.payload->va, buf_len); > + > + opcode = (enum > virtchnl_ops)rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_opcode); > + adapter->cmd_retval = > + (enum > +virtchnl_status_code)rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_retval); > + > + PMD_DRV_LOG(DEBUG, "CQ from ipf carries opcode %u, retval %d", > + opcode, adapter->cmd_retval); > + > + if (opcode == VIRTCHNL2_OP_EVENT) { > + struct virtchnl2_event *ve = > + (struct virtchnl2_event > *)ctlq_msg.ctx.indirect.payload->va; > + > + result = IDPF_MSG_SYS; > + switch (ve->event) { > + case VIRTCHNL2_EVENT_LINK_CHANGE: > + /* TBD */ > + break; > + default: > + PMD_DRV_LOG(ERR, "%s: Unknown event %d from > ipf", > + __func__, ve->event); > + break; > + } > + } else { > + /* async reply msg on command issued by pf previously */ > + result = IDPF_MSG_CMD; > + if (opcode != adapter->pend_cmd) { > + PMD_DRV_LOG(WARNING, "command mismatch, > expect %u, get %u", > + adapter->pend_cmd, opcode); > + result = IDPF_MSG_ERR; > + } > + } > + > + if (ctlq_msg.data_len) > + dma_mem = ctlq_msg.ctx.indirect.payload; > + else > + pending = 0; > + > + ret = iecm_ctlq_post_rx_buffs(hw, hw->arq, &pending, > &dma_mem); > + if (ret && dma_mem) > + iecm_free_dma_mem(hw, dma_mem); > + > + return result; > +} > + > +#define MAX_TRY_TIMES 200 > +#define ASQ_DELAY_MS 10 > + > +static int > +idpf_execute_vc_cmd(struct idpf_adapter *adapter, struct idpf_cmd_info > +*args) { > + enum idpf_vc_result result; > + int err = 0; > + int i = 0; > + int ret; > + > + if (_atomic_set_cmd(adapter, args->ops)) > + return -1; > + > + ret = idpf_send_vc_msg(adapter, args->ops, > + args->in_args_size, > + args->in_args); > + if (ret) { > + PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops); > + _clear_cmd(adapter); > + return ret; > + } > + > + switch (args->ops) { > + case VIRTCHNL_OP_VERSION: > + case VIRTCHNL2_OP_GET_CAPS: > + case VIRTCHNL2_OP_CREATE_VPORT: > + case VIRTCHNL2_OP_DESTROY_VPORT: > + case VIRTCHNL2_OP_SET_RSS_KEY: > + case VIRTCHNL2_OP_SET_RSS_LUT: > + case VIRTCHNL2_OP_SET_RSS_HASH: > + case VIRTCHNL2_OP_CONFIG_RX_QUEUES: > + case VIRTCHNL2_OP_CONFIG_TX_QUEUES: > + case VIRTCHNL2_OP_ENABLE_QUEUES: > + case VIRTCHNL2_OP_DISABLE_QUEUES: > + case VIRTCHNL2_OP_ENABLE_VPORT: > + case VIRTCHNL2_OP_DISABLE_VPORT: > + /* for init virtchnl ops, need to poll the response */ > + do { > + result = idpf_read_msg_from_ipf(adapter, > + args->out_size, > + args->out_buffer); > + if (result == IDPF_MSG_CMD) > + break; > + rte_delay_ms(ASQ_DELAY_MS); > + } while (i++ < MAX_TRY_TIMES); > + if (i >= MAX_TRY_TIMES || > + adapter->cmd_retval != VIRTCHNL_STATUS_SUCCESS) { > + err = -1; > + PMD_DRV_LOG(ERR, "No response or return failure > (%d) for cmd %d", > + adapter->cmd_retval, args->ops); > + } > + _clear_cmd(adapter); > + break; > + default: > + /* For other virtchnl ops in running time, > + * wait for the cmd done flag. > + */ > + do { > + if (adapter->pend_cmd == > VIRTCHNL_OP_UNKNOWN) > + break; > + rte_delay_ms(ASQ_DELAY_MS); > + /* If don't read msg or read sys event, continue */ > + } while (i++ < MAX_TRY_TIMES); > + /* If there's no response is received, clear command */ > + if (i >= MAX_TRY_TIMES || > + adapter->cmd_retval != VIRTCHNL_STATUS_SUCCESS) { > + err = -1; > + PMD_DRV_LOG(ERR, "No response or return failure > (%d) for cmd %d", > + adapter->cmd_retval, args->ops); > + _clear_cmd(adapter); > + } > + break; > + } > + > + return err; > +} > + > +int > +idpf_check_api_version(struct idpf_adapter *adapter) { > + struct virtchnl_version_info version; > + struct idpf_cmd_info args; > + int err; > + > + memset(&version, 0, sizeof(struct virtchnl_version_info)); > + version.major = VIRTCHNL_VERSION_MAJOR_2; > + version.minor = VIRTCHNL_VERSION_MINOR_0; > + > + args.ops = VIRTCHNL_OP_VERSION; > + args.in_args = (uint8_t *)&version; > + args.in_args_size = sizeof(version); > + args.out_buffer = adapter->mbx_resp; > + args.out_size = IDPF_DFLT_MBX_BUF_SIZE; > + > + err = idpf_execute_vc_cmd(adapter, &args); > + if (err) { > + PMD_DRV_LOG(ERR, > + "Failed to execute command of > VIRTCHNL_OP_VERSION"); > + return err; > + } > + > + return err; > +} > + > +int > +idpf_get_caps(struct idpf_adapter *adapter) { > + struct virtchnl2_get_capabilities caps_msg; > + struct idpf_cmd_info args; > + int err; > + > + memset(&caps_msg, 0, sizeof(struct virtchnl2_get_capabilities)); > + caps_msg.csum_caps = > + VIRTCHNL2_CAP_TX_CSUM_L3_IPV4 | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP | > + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP | > + VIRTCHNL2_CAP_TX_CSUM_GENERIC | > + VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP | > + VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP | > + VIRTCHNL2_CAP_RX_CSUM_GENERIC; > + > + caps_msg.seg_caps = > + VIRTCHNL2_CAP_SEG_IPV4_TCP | > + VIRTCHNL2_CAP_SEG_IPV4_UDP | > + VIRTCHNL2_CAP_SEG_IPV4_SCTP | > + VIRTCHNL2_CAP_SEG_IPV6_TCP | > + VIRTCHNL2_CAP_SEG_IPV6_UDP | > + VIRTCHNL2_CAP_SEG_IPV6_SCTP | > + VIRTCHNL2_CAP_SEG_GENERIC; > + > + caps_msg.rss_caps = > + VIRTCHNL2_CAP_RSS_IPV4_TCP | > + VIRTCHNL2_CAP_RSS_IPV4_UDP | > + VIRTCHNL2_CAP_RSS_IPV4_SCTP | > + VIRTCHNL2_CAP_RSS_IPV4_OTHER | > + VIRTCHNL2_CAP_RSS_IPV6_TCP | > + VIRTCHNL2_CAP_RSS_IPV6_UDP | > + VIRTCHNL2_CAP_RSS_IPV6_SCTP | > + VIRTCHNL2_CAP_RSS_IPV6_OTHER | > + VIRTCHNL2_CAP_RSS_IPV4_AH | > + VIRTCHNL2_CAP_RSS_IPV4_ESP | > + VIRTCHNL2_CAP_RSS_IPV4_AH_ESP | > + VIRTCHNL2_CAP_RSS_IPV6_AH | > + VIRTCHNL2_CAP_RSS_IPV6_ESP | > + VIRTCHNL2_CAP_RSS_IPV6_AH_ESP; > + > + caps_msg.hsplit_caps = > + VIRTCHNL2_CAP_RX_HSPLIT_AT_L2 | > + VIRTCHNL2_CAP_RX_HSPLIT_AT_L3 | > + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 | > + VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6; > + > + caps_msg.rsc_caps = > + VIRTCHNL2_CAP_RSC_IPV4_TCP | > + VIRTCHNL2_CAP_RSC_IPV4_SCTP | > + VIRTCHNL2_CAP_RSC_IPV6_TCP | > + VIRTCHNL2_CAP_RSC_IPV6_SCTP; > + > + caps_msg.other_caps = > + VIRTCHNL2_CAP_RDMA | > + VIRTCHNL2_CAP_SRIOV | > + VIRTCHNL2_CAP_MACFILTER | > + VIRTCHNL2_CAP_FLOW_DIRECTOR | > + VIRTCHNL2_CAP_SPLITQ_QSCHED | > + VIRTCHNL2_CAP_CRC | > + VIRTCHNL2_CAP_WB_ON_ITR | > + VIRTCHNL2_CAP_PROMISC | > + VIRTCHNL2_CAP_LINK_SPEED | > + VIRTCHNL2_CAP_VLAN; > + > + args.ops = VIRTCHNL2_OP_GET_CAPS; > + args.in_args = (uint8_t *)&caps_msg; > + args.in_args_size = sizeof(caps_msg); > + args.out_buffer = adapter->mbx_resp; > + args.out_size = IDPF_DFLT_MBX_BUF_SIZE; > + > + err = idpf_execute_vc_cmd(adapter, &args); > + if (err) { > + PMD_DRV_LOG(ERR, > + "Failed to execute command of > VIRTCHNL2_OP_GET_CAPS"); > + return err; > + } > + > + rte_memcpy(adapter->caps, args.out_buffer, sizeof(caps_msg)); > + > + return err; > +} > + > +int > +idpf_create_vport(__rte_unused struct rte_eth_dev *dev) { > + uint16_t idx = adapter->next_vport_idx; > + struct virtchnl2_create_vport *vport_req_info = > + (struct virtchnl2_create_vport *)adapter- > >vport_req_info[idx]; > + struct virtchnl2_create_vport vport_msg; > + struct idpf_cmd_info args; > + int err = -1; > + > + memset(&vport_msg, 0, sizeof(struct virtchnl2_create_vport)); > + vport_msg.vport_type = vport_req_info->vport_type; > + vport_msg.txq_model = vport_req_info->txq_model; > + vport_msg.rxq_model = vport_req_info->rxq_model; > + vport_msg.num_tx_q = vport_req_info->num_tx_q; > + vport_msg.num_tx_complq = vport_req_info->num_tx_complq; > + vport_msg.num_rx_q = vport_req_info->num_rx_q; > + vport_msg.num_rx_bufq = vport_req_info->num_rx_bufq; > + > + memset(&args, 0, sizeof(args)); > + args.ops = VIRTCHNL2_OP_CREATE_VPORT; > + args.in_args = (uint8_t *)&vport_msg; > + args.in_args_size = sizeof(vport_msg); > + args.out_buffer = adapter->mbx_resp; > + args.out_size = IDPF_DFLT_MBX_BUF_SIZE; > + > + err = idpf_execute_vc_cmd(adapter, &args); > + if (err) { > + PMD_DRV_LOG(ERR, > + "Failed to execute command of > VIRTCHNL2_OP_CREATE_VPORT"); > + return err; > + } > + > + if (!adapter->vport_recv_info[idx]) { > + adapter->vport_recv_info[idx] = rte_zmalloc(NULL, > + > IDPF_DFLT_MBX_BUF_SIZE, 0); > + if (!adapter->vport_recv_info[idx]) { > + PMD_INIT_LOG(ERR, "Failed to alloc > vport_recv_info."); > + return err; > + } > + } > + rte_memcpy(adapter->vport_recv_info[idx], args.out_buffer, > + IDPF_DFLT_MBX_BUF_SIZE); > + return err; > +} > + > +int > +idpf_destroy_vport(struct idpf_vport *vport) { > + struct virtchnl2_vport vc_vport; > + struct idpf_cmd_info args; > + int err; > + > + vc_vport.vport_id = vport->vport_id; > + > + memset(&args, 0, sizeof(args)); > + args.ops = VIRTCHNL2_OP_DESTROY_VPORT; > + args.in_args = (uint8_t *)&vc_vport; > + args.in_args_size = sizeof(vc_vport); > + args.out_buffer = adapter->mbx_resp; > + args.out_size = IDPF_DFLT_MBX_BUF_SIZE; > + > + err = idpf_execute_vc_cmd(adapter, &args); > + if (err) { > + PMD_DRV_LOG(ERR, "Failed to execute command of > VIRTCHNL2_OP_DESTROY_VPORT"); > + return err; > + } > + > + return err; > +} > + > +int > +idpf_ena_dis_vport(struct idpf_vport *vport, bool enable) { > + struct virtchnl2_vport vc_vport; > + struct idpf_cmd_info args; > + int err; > + > + vc_vport.vport_id = vport->vport_id; > + args.ops = enable ? VIRTCHNL2_OP_ENABLE_VPORT : > + VIRTCHNL2_OP_DISABLE_VPORT; > + args.in_args = (u8 *)&vc_vport; > + args.in_args_size = sizeof(vc_vport); > + args.out_buffer = adapter->mbx_resp; > + args.out_size = IDPF_DFLT_MBX_BUF_SIZE; > + > + err = idpf_execute_vc_cmd(adapter, &args); > + if (err) { > + PMD_DRV_LOG(ERR, "Failed to execute command of > VIRTCHNL2_OP_%s_VPORT", > + enable ? "ENABLE" : "DISABLE"); > + } > + > + return err; > +} > + > diff --git a/drivers/net/idpf/meson.build b/drivers/net/idpf/meson.build > new file mode 100644 index 0000000000..3a84162f93 > --- /dev/null > +++ b/drivers/net/idpf/meson.build > @@ -0,0 +1,18 @@ > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2022 Intel > +Corporation > + > +if is_windows > + build = false > + reason = 'not supported on Windows' > + subdir_done() > +endif > + > +subdir('base') > +objs = [base_objs] > + > +sources = files( > + 'idpf_ethdev.c', > + 'idpf_vchnl.c', > +) > + > +includes += include_directories('base') > diff --git a/drivers/net/idpf/version.map b/drivers/net/idpf/version.map > new file mode 100644 index 0000000000..b7da224860 > --- /dev/null > +++ b/drivers/net/idpf/version.map > @@ -0,0 +1,3 @@ > +DPDK_22 { > + local: *; > +}; > \ No newline at end of file > diff --git a/drivers/net/meson.build b/drivers/net/meson.build index > e35652fe63..8910154544 100644 > --- a/drivers/net/meson.build > +++ b/drivers/net/meson.build > @@ -28,6 +28,7 @@ drivers = [ > 'i40e', > 'iavf', > 'ice', > + 'idpf', > 'igc', > 'ionic', > 'ipn3ke', > -- > 2.25.1 I'd like to report that this patch is causing a compilation failure over the main tree 22.11-rc2:
this is the failure which I see: ing-field-initializers -D_GNU_SOURCE -fPIC -march=native -mno-avx512f -mno-avx512f -DALLOW_EXPERIMENTAL_API -DALLOW_INTERNAL_API -DRTE_LOG_DEFAULT_LOGTYPE=pmd.net.idpf -MD -MQ drivers/libtmp_rte_net_idpf.a.p/net_idpf_idpf_vchnl.c.o -MF drivers/libtmp_rte_net_idpf.a.p/net_idpf_idpf_vchnl.c.o.d -o drivers/libtmp_rte_net_idpf.a.p/net_idpf_idpf_vchnl.c.o -c ../../root/dpdk/drivers/net/idpf/idpf_vchnl.c ../../root/dpdk/drivers/net/idpf/idpf_vchnl.c:142:13: error: comparison of constant 522 with expression of type 'enum virtchnl_ops' is always false [-Werror,-Wtautological-constant-out-of-range-compare] if (opcode == VIRTCHNL2_OP_EVENT) { ~~~~~~ ^ ~~~~~~~~~~~~~~~~~~ 1 error generated. [1424/2559] Generating eal.sym_chk with a meson_exe.py custom command ninja: build stopped: subcommand failed. And it's happening with the CLANG compiler: clang version 3.4.2 (tags/RELEASE_34/dot2-final) Kindest regards, Raslan Darawsheh