diff mbox

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

Message ID 20171222145221.10474-5-remy.horton@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers show

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Remy Horton Dec. 22, 2017, 2:52 p.m. UTC
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@intel.com>
Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
---
 drivers/net/ixgbe/Makefile         |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c   |  22 +++-
 drivers/net/ixgbe/ixgbe_ethdev.h   |   5 +
 drivers/net/ixgbe/ixgbe_prep_ops.c | 259 +++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_prep_ops.h |  15 +++
 5 files changed, 301 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h
diff mbox

Patch

diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 511a64e..4ec2422 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -130,6 +130,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_prep_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 ff19a56..a48b783 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -75,6 +75,7 @@ 
 #include "base/ixgbe_type.h"
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
+#include "ixgbe_prep_ops.h"
 
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
@@ -1138,6 +1139,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();
 
@@ -1261,6 +1265,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);
 
@@ -1363,6 +1378,8 @@  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;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1371,6 +1388,9 @@  eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 
+	if (rte_representor_enabled())
+		rte_representor_broker_uninit(eth_adapter->broker);
+
 	if (hw->adapter_stopped == 0)
 		ixgbe_dev_close(eth_dev);
 
@@ -3962,7 +3982,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 51ddcfd..4cc2cf0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -499,6 +499,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)\
@@ -673,6 +674,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_prep_ops.c b/drivers/net/ixgbe/ixgbe_prep_ops.c
new file mode 100644
index 0000000..a06df27
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_prep_ops.c
@@ -0,0 +1,259 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ */
+
+#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_rxtx.h"
+#include "rte_pmd_ixgbe.h"
+
+#include "ixgbe_prep_ops.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);
+}
diff --git a/drivers/net/ixgbe/ixgbe_prep_ops.h b/drivers/net/ixgbe/ixgbe_prep_ops.h
new file mode 100644
index 0000000..744aa3e
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_prep_ops.h
@@ -0,0 +1,15 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ */
+
+#ifndef _IXGBE_PREP_OPS_H_
+#define _IXGBE_PREP_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);
+
+#endif /* _IXGBE_PREP_OPS_H_ */