Create and init VF representor ports in PF probe process, and uninit the
ports when PF device removed. In addition, support to get device
information for VF representor.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/meson.build | 1 +
drivers/net/txgbe/txgbe_ethdev.c | 38 +++++-
drivers/net/txgbe/txgbe_ethdev.h | 12 ++
drivers/net/txgbe/txgbe_vf_representor.c | 144 +++++++++++++++++++++++
4 files changed, 193 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/txgbe/txgbe_vf_representor.c
@@ -20,6 +20,7 @@ sources = files(
'txgbe_pf.c',
'txgbe_rxtx.c',
'txgbe_tm.c',
+ 'txgbe_vf_representor.c',
)
deps += ['hash', 'security']
@@ -862,9 +862,10 @@ static int
eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
+ char name[RTE_ETH_NAME_MAX_LEN];
struct rte_eth_dev *pf_ethdev;
struct rte_eth_devargs eth_da;
- int retval;
+ int i, retval;
if (pci_dev->device.devargs) {
retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
@@ -887,6 +888,36 @@ eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
if (pf_ethdev == NULL)
return -ENODEV;
+ /* probe VF representor ports */
+ for (i = 0; i < eth_da.nb_representor_ports; i++) {
+ struct txgbe_vf_info *vfinfo;
+ struct txgbe_vf_representor representor;
+
+ vfinfo = *TXGBE_DEV_VFDATA(pf_ethdev);
+ if (vfinfo == NULL) {
+ PMD_DRV_LOG(ERR,
+ "no virtual functions supported by PF");
+ break;
+ }
+
+ representor.vf_id = eth_da.representor_ports[i];
+ representor.switch_domain_id = vfinfo->switch_domain_id;
+ representor.pf_ethdev = pf_ethdev;
+
+ /* representor port net_bdf_port */
+ snprintf(name, sizeof(name), "net_%s_representor_%d",
+ pci_dev->device.name,
+ eth_da.representor_ports[i]);
+
+ retval = rte_eth_dev_create(&pci_dev->device, name,
+ sizeof(struct txgbe_vf_representor), NULL, NULL,
+ txgbe_vf_representor_init, &representor);
+
+ if (retval)
+ PMD_DRV_LOG(ERR, "failed to create txgbe vf "
+ "representor %s.", name);
+ }
+
return 0;
}
@@ -898,7 +929,10 @@ static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev)
if (!ethdev)
return -ENODEV;
- return rte_eth_dev_destroy(ethdev, eth_txgbe_dev_uninit);
+ if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+ return rte_eth_dev_destroy(ethdev, txgbe_vf_representor_uninit);
+ else
+ return rte_eth_dev_destroy(ethdev, eth_txgbe_dev_uninit);
}
static struct rte_pci_driver rte_txgbe_pmd = {
@@ -373,6 +373,18 @@ struct txgbe_adapter {
uint8_t rss_reta_updated;
};
+struct txgbe_vf_representor {
+ uint16_t vf_id;
+ uint16_t switch_domain_id;
+ struct rte_eth_dev *pf_ethdev;
+};
+
+int txgbe_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);
+int txgbe_vf_representor_uninit(struct rte_eth_dev *ethdev);
+
+#define TXGBE_DEV_REPRESENTOR(dev) \
+ ((struct txgbe_vf_representor *)(dev)->data->dev_private)
+
#define TXGBE_DEV_ADAPTER(dev) \
((struct txgbe_adapter *)(dev)->data->dev_private)
new file mode 100644
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015-2020
+ */
+
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+#include <rte_malloc.h>
+
+#include "base/txgbe_type.h"
+#include "base/txgbe_vf.h"
+#include "txgbe_ethdev.h"
+#include "txgbe_rxtx.h"
+
+static int
+txgbe_vf_representor_dev_infos_get(struct rte_eth_dev *ethdev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct txgbe_vf_representor *representor =
+ TXGBE_DEV_REPRESENTOR(ethdev);
+
+ struct txgbe_hw *hw = TXGBE_DEV_HW(representor->pf_ethdev);
+
+ dev_info->device = representor->pf_ethdev->device;
+
+ dev_info->min_rx_bufsize = 1024;
+ /**< Minimum size of RX buffer. */
+ dev_info->max_rx_pktlen = 9728;
+ /**< Maximum configurable length of RX pkt. */
+ dev_info->max_rx_queues = TXGBE_VF_MAX_RX_QUEUES;
+ /**< Maximum number of RX queues. */
+ dev_info->max_tx_queues = TXGBE_VF_MAX_TX_QUEUES;
+ /**< Maximum number of TX queues. */
+
+ dev_info->max_mac_addrs = hw->mac.num_rar_entries;
+ /**< Maximum number of MAC addresses. */
+
+ dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
+ DEV_RX_OFFLOAD_IPV4_CKSUM | DEV_RX_OFFLOAD_UDP_CKSUM |
+ DEV_RX_OFFLOAD_TCP_CKSUM;
+ /**< Device RX offload capabilities. */
+
+ dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
+ DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_CKSUM | DEV_TX_OFFLOAD_SCTP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_MULTI_SEGS;
+ /**< Device TX offload capabilities. */
+
+ dev_info->speed_capa =
+ representor->pf_ethdev->data->dev_link.link_speed;
+ /**< Supported speeds bitmap (ETH_LINK_SPEED_). */
+
+ dev_info->switch_info.name =
+ representor->pf_ethdev->device->name;
+ dev_info->switch_info.domain_id = representor->switch_domain_id;
+ dev_info->switch_info.port_id = representor->vf_id;
+
+ return 0;
+}
+
+static const struct eth_dev_ops txgbe_vf_representor_dev_ops = {
+ .dev_infos_get = txgbe_vf_representor_dev_infos_get,
+};
+
+static uint16_t
+txgbe_vf_representor_rx_burst(__rte_unused void *rx_queue,
+ __rte_unused struct rte_mbuf **rx_pkts, __rte_unused uint16_t nb_pkts)
+{
+ return 0;
+}
+
+static uint16_t
+txgbe_vf_representor_tx_burst(__rte_unused void *tx_queue,
+ __rte_unused struct rte_mbuf **tx_pkts, __rte_unused uint16_t nb_pkts)
+{
+ return 0;
+}
+
+int
+txgbe_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
+{
+ struct txgbe_vf_representor *representor =
+ TXGBE_DEV_REPRESENTOR(ethdev);
+
+ struct txgbe_vf_info *vf_data;
+ struct rte_pci_device *pci_dev;
+ struct rte_eth_link *link;
+
+ if (!representor)
+ return -ENOMEM;
+
+ representor->vf_id =
+ ((struct txgbe_vf_representor *)init_params)->vf_id;
+ representor->switch_domain_id =
+ ((struct txgbe_vf_representor *)init_params)->switch_domain_id;
+ representor->pf_ethdev =
+ ((struct txgbe_vf_representor *)init_params)->pf_ethdev;
+
+ pci_dev = RTE_ETH_DEV_TO_PCI(representor->pf_ethdev);
+
+ if (representor->vf_id >= pci_dev->max_vfs)
+ return -ENODEV;
+
+ ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+ ethdev->data->representor_id = representor->vf_id;
+
+ /* Set representor device ops */
+ ethdev->dev_ops = &txgbe_vf_representor_dev_ops;
+
+ /* No data-path, but need stub Rx/Tx functions to avoid crash
+ * when testing with the likes of testpmd.
+ */
+ ethdev->rx_pkt_burst = txgbe_vf_representor_rx_burst;
+ ethdev->tx_pkt_burst = txgbe_vf_representor_tx_burst;
+
+ /* Setting the number queues allocated to the VF */
+ ethdev->data->nb_rx_queues = TXGBE_VF_MAX_RX_QUEUES;
+ ethdev->data->nb_tx_queues = TXGBE_VF_MAX_RX_QUEUES;
+
+ /* Reference VF mac address from PF data structure */
+ vf_data = *TXGBE_DEV_VFDATA(representor->pf_ethdev);
+
+ ethdev->data->mac_addrs = (struct rte_ether_addr *)
+ vf_data[representor->vf_id].vf_mac_addresses;
+
+ /* Link state. Inherited from PF */
+ link = &representor->pf_ethdev->data->dev_link;
+
+ ethdev->data->dev_link.link_speed = link->link_speed;
+ ethdev->data->dev_link.link_duplex = link->link_duplex;
+ ethdev->data->dev_link.link_status = link->link_status;
+ ethdev->data->dev_link.link_autoneg = link->link_autoneg;
+
+ return 0;
+}
+
+int
+txgbe_vf_representor_uninit(struct rte_eth_dev *ethdev)
+{
+ /* mac_addrs must not be freed because part of txgbe_vf_info */
+ ethdev->data->mac_addrs = NULL;
+
+ return 0;
+}
+