[dpdk-dev] [PATCH v5 4/5] drivers/net/ixgbe: add Port Representor functionality

Remy Horton remy.horton at intel.com
Wed Jan 10 16:54:05 CET 2018


Port Representors provide a logical presentation in DPDK of VF (virtual
function) ports for the purposes of control and monitoring. Each port
representor device represents a single VF and is associated with it's
parent physical function (PF) PMD which provides the back-end hooks for
the representor device ops and defines the control domain to which that
port belongs. This allows to use existing DPDK APIs to monitor and control
the port without the need to create and maintain VF specific APIs.

This patch adds to the ixgbe PMD PMD the functions required to enable
port representor functionality.

Signed-off-by: Declan Doherty <declan.doherty at intel.com>
Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal at intel.com>
Signed-off-by: Remy Horton <remy.horton at intel.com>
---
 MAINTAINERS                                    |   2 +
 drivers/net/ixgbe/Makefile                     |   2 +
 drivers/net/ixgbe/ixgbe_ethdev.c               |  29 ++-
 drivers/net/ixgbe/ixgbe_ethdev.h               |   5 +
 drivers/net/ixgbe/ixgbe_port_representor_ops.c | 274 +++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_port_representor_ops.h |  19 ++
 6 files changed, 330 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_port_representor_ops.c
 create mode 100644 drivers/net/ixgbe/ixgbe_port_representor_ops.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b720566..b467c6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -789,6 +789,8 @@ F: lib/librte_representor
 F: doc/guides/prog_guide/representor_lib.rst
 F: drivers/net/i40e/i40e_prep_ops.c
 F: drivers/net/i40e/i40e_prep_ops.h
+F: drivers/net/ixgbe/ixgbe_prep_ops.c
+F: drivers/net/ixgbe/ixgbe_prep_ops.h
 
 
 Packet Framework
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 9efa5a4..39fe184 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -57,6 +57,7 @@ endif
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
 LDLIBS += -lrte_bus_pci
+LDLIBS += -lrte_representor
 
 #
 # Add extra flags for base driver files (also known as shared code)
@@ -102,6 +103,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ipsec.c
 endif
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += rte_pmd_ixgbe.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_port_representor_ops.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 43e0132..96c5eaf 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -46,6 +46,7 @@
 #include "base/ixgbe_type.h"
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
+#include "ixgbe_port_representor_ops.h"
 
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
@@ -1109,6 +1110,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 	uint32_t ctrl_ext;
 	uint16_t csum;
 	int diag, i;
+	int ret;
+	struct ixgbe_adapter *eth_adapter =
+		(struct ixgbe_adapter *)eth_dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1232,6 +1236,17 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 		return -EIO;
 	}
 
+	/* Init port representor broker */
+	if (rte_representor_enabled()) {
+		ret = ixgbe_port_representor_broker_init(eth_dev,
+			&eth_adapter->broker, pci_dev);
+		if (ret) {
+			PMD_INIT_LOG(ERR, "Representor broker register failed "
+				"with ret=%d\n", ret);
+			return ret;
+		}
+	}
+
 	/* Reset the hw statistics */
 	ixgbe_dev_stats_reset(eth_dev);
 
@@ -1334,6 +1349,9 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	struct ixgbe_hw *hw;
+	struct ixgbe_adapter *eth_adapter =
+		(struct ixgbe_adapter *)eth_dev->data->dev_private;
+	int ret;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1342,6 +1360,15 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 
+	/* free port representor pmds */
+	if (rte_representor_enabled()) {
+		ret = ixgbe_port_representor_broker_uninit(eth_dev,
+			eth_adapter->broker);
+		if (ret)
+			PMD_INIT_LOG(ERR, "Representor broker unregister "
+				"failed " "with ret=%d\n", ret);
+	}
+
 	if (hw->adapter_stopped == 0)
 		ixgbe_dev_close(eth_dev);
 
@@ -3933,7 +3960,7 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 }
 
 /* return 0 means link status changed, -1 means not changed */
-static int
+int
 ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 			    int wait_to_complete, int vf)
 {
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 1db29bd..c2df08e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -470,6 +470,7 @@ struct ixgbe_adapter {
 	struct rte_timecounter      rx_tstamp_tc;
 	struct rte_timecounter      tx_tstamp_tc;
  	struct ixgbe_tm_conf        tm_conf;
+	struct rte_representor_broker *broker;
 };
 
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
@@ -644,6 +645,10 @@ int ixgbe_fdir_filter_program(struct rte_eth_dev *dev,
 
 void ixgbe_configure_dcb(struct rte_eth_dev *dev);
 
+int
+ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
+			    int wait_to_complete, int vf);
+
 /*
  * misc function prototypes
  */
diff --git a/drivers/net/ixgbe/ixgbe_port_representor_ops.c b/drivers/net/ixgbe/ixgbe_port_representor_ops.c
new file mode 100644
index 0000000..4547cbc
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_port_representor_ops.c
@@ -0,0 +1,274 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+#include <rte_port_representor_driver.h>
+
+#include "base/ixgbe_type.h"
+#include "base/ixgbe_vf.h"
+#include "ixgbe_ethdev.h"
+#include "ixgbe_port_representor_ops.h"
+#include "ixgbe_rxtx.h"
+#include "rte_pmd_ixgbe.h"
+
+
+struct ixgbe_representor_private_data {
+	struct rte_eth_dev *pf_ethdev;
+};
+
+static int
+ixgbe_representor_link_update(struct rte_eth_dev *ethdev,
+	int wait_to_complete)
+{
+	struct rte_representor_port *prep_priv_data =
+			ethdev->data->dev_private;
+	struct ixgbe_representor_private_data *ixgbe_priv_data =
+			prep_priv_data->priv_data;
+
+	return ixgbe_dev_link_update_share(ixgbe_priv_data->pf_ethdev,
+		wait_to_complete, 1);
+}
+
+static void
+ixgbe_representor_mac_addr_set(struct rte_eth_dev *ethdev,
+	struct ether_addr *mac_addr)
+{
+	struct rte_representor_port *prep_priv_data = ethdev->data->dev_private;
+	struct ixgbe_representor_private_data *ixgbe_priv_data =
+		prep_priv_data->priv_data;
+
+	rte_pmd_ixgbe_set_vf_mac_addr(ixgbe_priv_data->pf_ethdev->data->port_id,
+		prep_priv_data->vport_id, mac_addr);
+}
+
+static void
+ixgbe_representor_dev_infos_get(struct rte_eth_dev *ethdev,
+	struct rte_eth_dev_info *dev_info)
+{
+	struct rte_representor_port *prep_priv_data =
+		ethdev->data->dev_private;
+	struct ixgbe_representor_private_data *ixgbe_priv_data =
+		prep_priv_data->priv_data;
+
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(
+		ixgbe_priv_data->pf_ethdev->data->dev_private);
+
+	dev_info->pci_dev = NULL;
+
+	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 = IXGBE_VF_MAX_RX_QUEUES;
+	/**< Maximum number of RX queues. */
+	dev_info->max_tx_queues = IXGBE_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;
+	/**< Device TX offload capabilities. */
+
+	dev_info->speed_capa =
+		ixgbe_priv_data->pf_ethdev->data->dev_link.link_speed;
+	/**< Supported speeds bitmap (ETH_LINK_SPEED_). */
+}
+
+static int ixgbe_representor_dev_configure(__rte_unused struct rte_eth_dev *dev)
+{
+	return 0;
+}
+
+static int ixgbe_representor_rx_queue_setup(
+	__rte_unused struct rte_eth_dev *dev,
+	__rte_unused uint16_t rx_queue_id,
+	__rte_unused uint16_t nb_rx_desc,
+	__rte_unused unsigned int socket_id,
+	__rte_unused const struct rte_eth_rxconf *rx_conf,
+	__rte_unused struct rte_mempool *mb_pool)
+{
+	return 0;
+}
+
+static int ixgbe_representor_tx_queue_setup(
+	__rte_unused struct rte_eth_dev *dev,
+	__rte_unused uint16_t rx_queue_id,
+	__rte_unused uint16_t nb_rx_desc,
+	__rte_unused unsigned int socket_id,
+	__rte_unused const struct rte_eth_txconf *tx_conf)
+{
+	return 0;
+}
+
+static int ixgbe_representor_dev_start(__rte_unused struct rte_eth_dev *dev)
+{
+	return 0;
+}
+
+static void ixgbe_representor_dev_stop(__rte_unused struct rte_eth_dev *dev)
+{
+}
+
+static int
+ixgbe_representor_vlan_filter_set(struct rte_eth_dev *ethdev,
+	uint16_t vlan_id, int on)
+{
+	struct rte_representor_port *prep_priv_data =
+		ethdev->data->dev_private;
+	struct ixgbe_representor_private_data *ixgbe_priv_data =
+		prep_priv_data->priv_data;
+
+	uint32_t pfid;
+	uint32_t vfid;
+	uint64_t vf_mask;
+
+	pfid = ixgbe_priv_data->pf_ethdev->data->port_id;
+	vfid = prep_priv_data->vport_id;
+	vf_mask = 1ULL << vfid;
+
+	return rte_pmd_ixgbe_set_vf_vlan_filter(pfid, vlan_id, vf_mask, on);
+}
+
+static void
+ixgbe_representor_vlan_strip_queue_set(struct rte_eth_dev *ethdev,
+	__rte_unused uint16_t rx_queue_id, int on)
+{
+	struct rte_representor_port *prep_priv_data = ethdev->data->dev_private;
+	struct ixgbe_representor_private_data *ixgbe_priv_data =
+		prep_priv_data->priv_data;
+
+	uint32_t pfid;
+	uint32_t vfid;
+
+	pfid = ixgbe_priv_data->pf_ethdev->data->port_id;
+	vfid = prep_priv_data->vport_id;
+
+	rte_pmd_ixgbe_set_vf_vlan_stripq(pfid, vfid, on);
+}
+
+struct eth_dev_ops ixgbe_representor_dev_ops = {
+	.link_update                  = ixgbe_representor_link_update,
+	.dev_infos_get                = ixgbe_representor_dev_infos_get,
+	.dev_configure	              = ixgbe_representor_dev_configure,
+	.rx_queue_setup               = ixgbe_representor_rx_queue_setup,
+	.tx_queue_setup               = ixgbe_representor_tx_queue_setup,
+	.dev_start                    = ixgbe_representor_dev_start,
+	.dev_stop                     = ixgbe_representor_dev_stop,
+	.mac_addr_set                 = ixgbe_representor_mac_addr_set,
+	.vlan_filter_set              = ixgbe_representor_vlan_filter_set,
+	.vlan_strip_queue_set         = ixgbe_representor_vlan_strip_queue_set
+};
+
+static int
+ixgbe_port_representor_init(struct rte_representor_broker *broker,
+		struct rte_eth_dev *ethdev)
+{
+	struct rte_eth_dev *pf_ethdev;
+	struct rte_eth_link *link;
+	struct rte_representor_port *port = ethdev->data->dev_private;
+
+	/**
+	 * Allocate private data for i40e port representor and save the physical
+	 * functions ethdev handle
+	 */
+	port->priv_data = rte_zmalloc_socket("ixgbe_port_representor_priv_data",
+			sizeof(struct ixgbe_representor_private_data),
+			RTE_CACHE_LINE_SIZE, ethdev->device->numa_node);
+	if (!port->priv_data)
+		return -ENOMEM;
+	pf_ethdev = (struct rte_eth_dev *)broker->private_data;
+
+	((struct ixgbe_representor_private_data *)port->priv_data)->pf_ethdev =
+			pf_ethdev;
+
+	/* Set representor device ops */
+	ethdev->dev_ops = &ixgbe_representor_dev_ops;
+
+	/* Setting the number queues allocated to the VF */
+	ethdev->data->nb_rx_queues = IXGBE_VF_MAX_RX_QUEUES;
+	ethdev->data->nb_tx_queues = IXGBE_VF_MAX_TX_QUEUES;
+
+	/* Link state. Inherited from PF */
+	link = &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;
+
+	/* No data-path so no RX/TX functions */
+	ethdev->rx_pkt_burst = NULL;
+	ethdev->tx_pkt_burst = NULL;
+
+	return 0;
+}
+
+static int
+ixgbe_port_representor_uninit(
+	__rte_unused struct rte_representor_broker *broker,
+	struct rte_eth_dev *ethdev)
+{
+	struct rte_representor_port *port = ethdev->data->dev_private;
+
+	rte_free(port->priv_data);
+
+	return 0;
+}
+
+struct rte_representor_broker_port_ops ixgbe_broker_port_ops = {
+	.port_init = ixgbe_port_representor_init,
+	.port_uninit = ixgbe_port_representor_uninit
+};
+
+int
+ixgbe_port_representor_broker_init(struct rte_eth_dev *dev,
+	struct rte_representor_broker **broker,
+	const struct rte_pci_device *pci_dev)
+{
+	struct rte_bus *bus;
+
+	*broker = rte_zmalloc_socket("rte_port_representor_broker",
+		sizeof(**broker), RTE_CACHE_LINE_SIZE,
+		rte_socket_id());
+	if (!*broker) {
+		RTE_LOG(ERR, EAL, "Not enough memory for representor "
+			"broker\n");
+		return -ENOMEM;
+	}
+	bus = rte_bus_find_by_device(&pci_dev->device);
+
+	/* Set IXGBE broker parameters */
+	(*broker)->bus = bus->name;
+	(*broker)->device = pci_dev->name;
+	(*broker)->nb_virtual_ports = pci_dev->max_vfs;
+	(*broker)->ops = &ixgbe_broker_port_ops;
+	(*broker)->private_data = dev;
+
+	return rte_representor_broker_init(*broker);
+}
+
+int
+ixgbe_port_representor_broker_uninit(__rte_unused struct rte_eth_dev *dev,
+	struct rte_representor_broker *broker)
+{
+	int ret;
+
+	ret = rte_representor_broker_uninit(broker);
+	if (ret)
+		return ret;
+
+	rte_free(broker);
+
+	return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_port_representor_ops.h b/drivers/net/ixgbe/ixgbe_port_representor_ops.h
new file mode 100644
index 0000000..3c797c4
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_port_representor_ops.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation.
+ */
+
+#ifndef _IXGBE_PORT_REPRESENTOR_OPS_H_
+#define _IXGBE_PORT_REPRESENTOR_OPS_H_
+
+#include <rte_port_representor_driver.h>
+
+int
+ixgbe_port_representor_broker_init(struct rte_eth_dev *dev,
+	struct rte_representor_broker **broker,
+	const struct rte_pci_device *pci_dev);
+
+int
+ixgbe_port_representor_broker_uninit(struct rte_eth_dev *dev,
+	struct rte_representor_broker *broker);
+
+#endif /* _IXGBE_PORT_REPRESENTOR_OPS_H_ */
-- 
2.9.5



More information about the dev mailing list