DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
@ 2017-09-07  8:35 Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 1/5] Implemented port representor broker infrastructure, created BDF to port function Mohammad Abdul Awal
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
This RFC introduces a port representor based model for the control, management
and monitoring of SR-IOV virtual function (VF) devices for control plane
applications which have bound the devices physical function.

Port Representors are virtual poll mode drivers (PMD) which provide a logical
representation in DPDK for VF ports for control and monitoring. Each port
representor PMD 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.


+-----------------------------+   +---------------+  +---------------+
|        Control Plane        |   |   Data Plane  |  |   Data Plane  |
|         Application         |   |   Application |  |   Application |
+-----------------------------+   +---------------+  +---------------+
|         eth dev api         |   |  eth dev api  |  |  eth dev api  |
+-----------------------------+   +---------------+  +---------------+
+-------+  +-------+  +-------+   +---------------+  +---------------+
|  PF0  |  | Port  |  | Port  |   |    VF0 PMD    |  |    VF0 PMD    |
|  PMD  <--+ Rep 0 |  | Rep 1 |   +---------------+  +------+--------+
|       |  | PMD   |  | PMD   |                             |
+---+--^+  +-------+  +-+-----+                             |
    |  |                |  |                                |
    |  +----------------+  |                                |
    |                      |                                |
    |                      |                                |
+--------------------------------+                          |
|   |  HW (logical view)   |     |                          |
| --+------+ +-------+ +---+---+ |                          |
| |   PF   | |  VF0  | |  VF1  | |                          |
| |        | |       | |       +----------------------------+
| +--------+ +-------+ +-------+ |
| +----------------------------+ |
| |        VEB                 | |
| +----------------------------+ |
| +--------+                     |
| |  Port  |                     |
| |   0    |                     |
| +--------+                     |
+--------------------------------+

The figure above shows a deployment where the PF is bound to a DPDK control
plane application which uses representor ports to manage the configuration and
monitoring of it's VF ports. Each virtual function is represented in the
application by a representor port PMD which enables control of the corresponding
VF through eth dev APIs on the representor PMD such as:

- void rte_eth_promiscuous_enable(uint8_t port_id);
- void rte_eth_promiscuous_disable(uint8_t port_id);
- void rte_eth_allmulticast_enable(uint8_t port_id);
- void rte_eth_allmulticast_disable(uint8_t port_id);
- int rte_eth_dev_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
	uint32_t pool);
- int rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask);

as well as monitoring through API's like

- void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *link);
- int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats);

The port representor infrastructure is enabled through a single common, device
independent, virtual PMD whos context is initialized and enabled through a
broker instance running within the context of the physical function device
driver.

+-------------------------+       +-------------------------+
|        rte_ethdev       |       |       rte_ethdev        |
+-------------------------+       +-------------------------+
|  Physical Function PMD  |       |  Port Reperesentor PMD  |
|         +-------------+ |       | +---------+ +---------+ |
|         | Representor | |       | | dev_data| | dev_ops | |
|         |    Broker   | |       | +----+----+ +----+----+ |
|         | +---------+ | |       +------|-----------|------+
|         | | VF Port | | |              |           |
|         | | Context +------------------+           |
|         | +---------+ | |                          |
|         | +---------+ | |                          |
|         | | Handler +------------------------------+
|         | |   Ops   | | |
|         | +---------+ | |
|         +-------------+ |
+-------------------------+

Creation of representor ports can be achieved either through the --vdev EAL
option or through the rte_vdev_init() API. Each port representor requires the
BDF of it's parent PF and the Virtual Function ID of the port which the
representor will support. During initialization of the representor PMD, it calls
the broker API to register itself with the PF PMD and to get it's context
configured which includes the setting up of it's context and ops function
handlers.


As the port representor model is based around the paradigm of using standard
port based APIs, it will allow future expansion of functionality without the
need to add new APIs. For example it should be possible to support configuration
of egress QoS parameters using existing TM APIs by extending the port
representor PMD/broker infrastructure.

Mohammad Abdul Awal (5):
  Implemented port representor broker infrastructure, created BDF to
    port     function.
  added --enable-representor command line argument in EAL to load    
    representor broker infrastructure.
  Implement port representor PMD
  Enable port representor PMD and broker for fortville PMD driver
  Enable port representor PMD and broker for ixgbe PMD driver.

 config/common_base                                 |   5 +
 drivers/net/Makefile                               |   2 +
 drivers/net/i40e/Makefile                          |   1 +
 drivers/net/i40e/i40e_ethdev.c                     |  17 +
 drivers/net/i40e/i40e_prep_ops.c                   | 402 +++++++++
 drivers/net/i40e/i40e_prep_ops.h                   |  41 +
 drivers/net/i40e/rte_pmd_i40e.c                    |  47 +
 drivers/net/i40e/rte_pmd_i40e.h                    |  18 +
 drivers/net/ixgbe/Makefile                         |   2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c                   |  33 +-
 drivers/net/ixgbe/ixgbe_ethdev.h                   |  11 +
 drivers/net/ixgbe/ixgbe_prep_ops.c                 | 279 ++++++
 drivers/net/ixgbe/ixgbe_prep_ops.h                 |  41 +
 drivers/net/representor/Makefile                   |  51 ++
 drivers/net/representor/rte_eth_representor.c      | 973 +++++++++++++++++++++
 .../representor/rte_pmd_representor_version.map    |   4 +
 lib/librte_eal/bsdapp/eal/eal.c                    |   6 +
 lib/librte_eal/common/eal_common_options.c         |   1 +
 lib/librte_eal/common/eal_internal_cfg.h           |   2 +
 lib/librte_eal/common/eal_options.h                |   2 +
 lib/librte_eal/common/include/rte_eal.h            |   8 +
 lib/librte_eal/linuxapp/eal/eal.c                  |   9 +
 lib/librte_ether/Makefile                          |   2 +
 lib/librte_ether/rte_ethdev.c                      |  93 ++
 lib/librte_ether/rte_ethdev.h                      |  26 +
 lib/librte_ether/rte_ethdev_vdev.h                 |  37 +-
 lib/librte_ether/rte_ether_version.map             |   9 +
 lib/librte_ether/rte_port_representor.c            | 160 ++++
 lib/librte_ether/rte_port_representor.h            | 289 ++++++
 mk/rte.app.mk                                      |   1 +
 30 files changed, 2556 insertions(+), 16 deletions(-)
 create mode 100644 drivers/net/i40e/i40e_prep_ops.c
 create mode 100644 drivers/net/i40e/i40e_prep_ops.h
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h
 create mode 100644 drivers/net/representor/Makefile
 create mode 100644 drivers/net/representor/rte_eth_representor.c
 create mode 100644 drivers/net/representor/rte_pmd_representor_version.map
 create mode 100644 lib/librte_ether/rte_port_representor.c
 create mode 100644 lib/librte_ether/rte_port_representor.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [dpdk-dev] [RFC 1/5] Implemented port representor broker infrastructure, created BDF to port function.
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
@ 2017-09-07  8:35 ` Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 2/5] added --enable-representor command line argument in EAL to load representor broker infrastructure Mohammad Abdul Awal
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 lib/librte_ether/Makefile               |   2 +
 lib/librte_ether/rte_ethdev.c           |  93 ++++++++++
 lib/librte_ether/rte_ethdev.h           |  26 +++
 lib/librte_ether/rte_ether_version.map  |   9 +
 lib/librte_ether/rte_port_representor.c | 160 ++++++++++++++++++
 lib/librte_ether/rte_port_representor.h | 289 ++++++++++++++++++++++++++++++++
 6 files changed, 579 insertions(+)
 create mode 100644 lib/librte_ether/rte_port_representor.c
 create mode 100644 lib/librte_ether/rte_port_representor.h

diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index db692ae..b61a84b 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -46,6 +46,7 @@ LIBABIVER := 6
 SRCS-y += rte_ethdev.c
 SRCS-y += rte_flow.c
 SRCS-y += rte_tm.c
+SRCS-y += rte_port_representor.c
 
 #
 # Export include files
@@ -59,5 +60,6 @@ SYMLINK-y-include += rte_flow.h
 SYMLINK-y-include += rte_flow_driver.h
 SYMLINK-y-include += rte_tm.h
 SYMLINK-y-include += rte_tm_driver.h
+SYMLINK-y-include += rte_port_representor.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..3bca00f 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -67,6 +67,7 @@
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
+#include "rte_port_representor.h"
 
 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
@@ -360,6 +361,98 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)
 	return -ENODEV;
 }
 
+#define RTE_ETH_EBDF_MAX_COLONS 2
+#define RTE_ETH_EBDF_MAX_PERIODS 1
+
+static inline int
+char_to_value(char value)
+{
+	if (value >= '0' && value <= '9')
+		return value - '0';
+	if (value >= 'A' && value <= 'F')
+		return value - 'A' + 10;
+	if (value >= 'a' && value <= 'f')
+		return value - 'a' + 10;
+	return -1;
+}
+
+static int
+parse_ebdf_addr(const char * const addr_str, struct rte_pci_addr *pci_addr)
+{
+	const char *str_pos;
+
+	int cnt_colons = 0;
+	int cnt_periods = 0;
+	int nibbles[RTE_ETH_EBDF_MAX_COLONS + RTE_ETH_EBDF_MAX_PERIODS + 1];
+	int param_value;
+	int digit_value;
+
+	str_pos = addr_str;
+	param_value = 0;
+	while (*str_pos) {
+		if (isxdigit(*str_pos)) {
+			digit_value = char_to_value(*str_pos);
+			if (digit_value == -1)
+				return -EINVAL;
+			param_value = (param_value << 4) | digit_value;
+		} else if (*str_pos == ':') {
+			if (cnt_periods != 0 ||
+					cnt_colons >= RTE_ETH_EBDF_MAX_COLONS)
+				return -EINVAL;
+			nibbles[cnt_colons++] = param_value;
+			param_value = 0;
+		} else if (*str_pos == '.') {
+			if (cnt_periods >= RTE_ETH_EBDF_MAX_PERIODS)
+				return -EINVAL;
+			nibbles[cnt_colons + cnt_periods] = param_value;
+			param_value = 0;
+			cnt_periods++;
+		} else
+			return -EINVAL;
+		str_pos++;
+	}
+	nibbles[cnt_colons + cnt_periods] = param_value;
+
+	if (cnt_colons == 2 && cnt_periods == 1) {
+		pci_addr->domain = nibbles[0];
+		pci_addr->bus = nibbles[1];
+		pci_addr->devid = nibbles[2];
+		pci_addr->function = nibbles[3];
+	} else if (cnt_colons == 1 && cnt_periods == 1) {
+		pci_addr->domain = 0;
+		pci_addr->bus = nibbles[0];
+		pci_addr->devid = nibbles[1];
+		pci_addr->function = nibbles[2];
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+int
+rte_eth_dev_get_port_by_pci_addr_str(const char *pci_str, uint8_t *port_id)
+{
+	struct rte_pci_device *pci_dev;
+	struct rte_pci_addr pci_addr;
+
+	if (parse_ebdf_addr(pci_str, &pci_addr) != 0)
+		return -EINVAL;
+
+	FOREACH_DEVICE_ON_PCIBUS(pci_dev) {
+		if (pci_dev->driver == NULL) {
+			/* No loaded driver - skip */
+			continue;
+		}
+		if (rte_eal_compare_pci_addr(&pci_addr, &pci_dev->addr) == 0) {
+			/* (E)BDF resolved to device name. Now get port_id..
+			 */
+			return rte_eth_dev_get_port_by_name(
+				pci_dev->device.name, port_id);
+		}
+	}
+	return -ENODEV;
+}
+
 static int
 rte_eth_dev_is_detachable(uint8_t port_id)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0adf327..9342e45 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -967,6 +967,7 @@ struct rte_eth_dev_info {
 	/** Configured number of rx/tx queues */
 	uint16_t nb_rx_queues; /**< Number of RX queues. */
 	uint16_t nb_tx_queues; /**< Number of TX queues. */
+	uint16_t switch_domain; /**< Switch domain which port belongs to. */
 };
 
 /**
@@ -1618,6 +1619,8 @@ enum rte_eth_dev_state {
 	RTE_ETH_DEV_DEFERRED,
 };
 
+struct rte_representor_broker;
+
 /**
  * @internal
  * The generic data structure associated with each ethernet device.
@@ -1633,6 +1636,8 @@ struct rte_eth_dev {
 	eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
 	eth_tx_prep_t tx_pkt_prepare; /**< Pointer to PMD transmit prepare function. */
 	struct rte_eth_dev_data *data;  /**< Pointer to device data */
+	struct rte_port_representor_broker *rep_broker;
+	/**< Pointer to representor broker */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_device *device; /**< Backing device */
 	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
@@ -1711,6 +1716,7 @@ struct rte_eth_dev_data {
 	int numa_node;  /**< NUMA node connection */
 	struct rte_vlan_filter_conf vlan_filter_conf;
 	/**< VLAN filter configuration. */
+	uint16_t switch_domain; /**< Switch domain which port belongs to. */
 };
 
 /** Device supports hotplug detach */
@@ -1730,6 +1736,12 @@ struct rte_eth_dev_data {
 extern struct rte_eth_dev rte_eth_devices[];
 
 /**
+ * The pci device list needed to map the PF BDF to port id mapping for
+ * port representor pmd argument parsing.
+ */
+extern struct rte_pci_bus rte_pci_bus;
+
+/**
  * Iterates over valid ethdev ports.
  *
  * @param port_id
@@ -4436,6 +4448,20 @@ int rte_eth_dev_adjust_nb_rx_tx_desc(uint8_t port_id,
 				     uint16_t *nb_rx_desc,
 				     uint16_t *nb_tx_desc);
 
+/**
+* Get the port id from (E)BDF PCI address.
+*
+* @param pci_str
+*  Address as string
+* @param port_id
+*   pointer to port identifier of the device
+* @return
+*   - (0) if successful and port_id is filled.
+*   - (-ENODEV or -EINVAL) on failure.
+*/
+int rte_eth_dev_get_port_by_pci_addr_str(const char *pci_str, uint8_t *port_id);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 4283728..c08d469 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -187,3 +187,12 @@ DPDK_17.08 {
 	rte_tm_wred_profile_delete;
 
 } DPDK_17.05;
+
+DPDK_17.11 {
+	global:
+
+	rte_representor_broker_init;
+	rte_representor_add;
+	rte_representor_broker_fini;
+
+} DPDK_17.08;
diff --git a/lib/librte_ether/rte_port_representor.c b/lib/librte_ether/rte_port_representor.c
new file mode 100644
index 0000000..ed5faa5
--- /dev/null
+++ b/lib/librte_ether/rte_port_representor.c
@@ -0,0 +1,160 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rte_ethdev.h"
+
+#include "rte_port_representor.h"
+
+/*
+ * Helper functions.
+ */
+static inline struct rte_port_representor *
+get_representor(struct rte_port_representor_list *list)
+{
+	struct rte_port_representor *rep;
+
+	rep = NULL;
+	if (list->num == 0)
+		return rep;
+
+	rep = STAILQ_FIRST(&list->head);
+	STAILQ_REMOVE_HEAD(&list->head, next);
+	list->num--;
+
+	return rep;
+}
+
+static inline void
+put_representor(struct rte_port_representor_list *list,
+	struct rte_port_representor *rep)
+{
+	STAILQ_INSERT_TAIL(&list->head, rep, next);
+	list->num++;
+}
+
+static inline void
+rem_representor(struct rte_port_representor_list *list,
+	struct rte_port_representor *rep)
+{
+	STAILQ_REMOVE(&list->head, rep, rte_port_representor, next);
+	list->num--;
+}
+
+struct rte_port_representor_broker *
+rte_representor_broker_init(struct rte_eth_dev *dev, uint16_t max_vfs,
+	struct representor_ops *ops)
+{
+	struct rte_port_representor_broker *rb;
+	uint32_t port_id;
+
+	if (!dev && !dev->data && !ops) {
+		errno = -EINVAL;
+		return NULL;
+	}
+	port_id = dev->data->port_id;
+
+	rb = rte_zmalloc_socket(NULL, sizeof(*rb), RTE_CACHE_LINE_SIZE,
+		rte_socket_id());
+	if (rb == NULL) {
+		errno = -ENOMEM;
+		return NULL;
+	}
+	/* update broker */
+	rb->pfid = port_id;
+	STAILQ_INIT(&rb->rep_list.head);
+	rb->max_vf = max_vfs;
+	rb->rep_ops = ops;
+
+	dev->rep_broker = rb;
+
+	/* update switch domain */
+	dev->data->switch_domain = port_id;
+
+	return rb;
+}
+
+void
+rte_representor_broker_free(uint32_t port_id)
+{
+	struct rte_port_representor *rep;
+	struct rte_eth_dev *eth_dev;
+	struct rte_port_representor_broker *rb;
+
+	eth_dev = &rte_eth_devices[port_id];
+	rb = eth_dev->rep_broker;
+	while (!STAILQ_EMPTY(&rb->rep_list.head)) {
+		rep = get_representor(&rb->rep_list);
+		rte_free(rep);
+	}
+	STAILQ_INIT(&rb->rep_list.head);
+	rte_free(rb);
+}
+
+struct rte_port_representor *
+rte_representor_initialize(uint32_t port_id, uint32_t vf_index,
+	struct rte_eth_dev *vdev)
+{
+	struct rte_port_representor *rep;
+	struct rte_eth_dev *eth_dev;
+	struct rte_port_representor_broker *rb;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
+	eth_dev = &rte_eth_devices[port_id];
+	rb = eth_dev->rep_broker;
+
+	if (vf_index >= rb->max_vf) {
+		RTE_LOG(ERR, EAL, "Invalid vf_index=%u. Max allowed=%u\n",
+			vf_index, rb->max_vf - 1);
+		errno = -EINVAL;
+		return NULL;
+	}
+
+	rep = rte_zmalloc_socket(NULL, sizeof(*rep), RTE_CACHE_LINE_SIZE,
+		rte_socket_id());
+	if (rep == NULL) {
+		RTE_LOG(ERR, EAL, "Not enough memory for representor.\n");
+		errno = -ENOMEM;
+		return NULL;
+	}
+
+	rep->pfid = rb->pfid;
+	rep->vf_index = vf_index;
+	rep->pdev = eth_dev;
+	rep->vdev = vdev;
+	vdev->data->switch_domain = eth_dev->data->switch_domain;
+	put_representor(&rb->rep_list, rep);
+	RTE_LOG(INFO, EAL, "%s: Added representor <pfid=%u, vf_index=%u>\n",
+		__func__, rb->pfid, vf_index);
+
+	return rep;
+}
diff --git a/lib/librte_ether/rte_port_representor.h b/lib/librte_ether/rte_port_representor.h
new file mode 100644
index 0000000..b132ead
--- /dev/null
+++ b/lib/librte_ether/rte_port_representor.h
@@ -0,0 +1,289 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_PORT_REPRESENTOR_H_
+#define _RTE_PORT_REPRESENTOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_malloc.h>
+#include <rte_flow.h>
+
+struct rte_port_representor;
+
+/*
+ * Definitions of all functions exported by an Ethernet representor driver
+ * through the structure of type *representor_ops*.
+ */
+
+typedef int (*representor_link_update_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	int wait_to_complete);
+/**< @internal Get link speed, duplex mode and state (up/down) of a device. */
+
+typedef void (*representor_promiscuous_enable_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep);
+/**< @internal Function used to enable the RX promiscuous mode of a device. */
+
+typedef void (*representor_promiscuous_disable_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep);
+/**< @internal Function used to disable the RX promiscuous mode of a device. */
+
+typedef void (*representor_allmulticast_enable_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep);
+/**< @internal Enable the receipt of all multicast packets by a device. */
+
+typedef void (*representor_allmulticast_disable_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep);
+/**< @internal Disable the receipt of all multicast packets by a device. */
+
+typedef void (*representor_mac_addr_remove_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	uint32_t index);
+/**< @internal Remove MAC address from a device. */
+
+typedef int (*representor_mac_addr_add_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	struct ether_addr *mac_addr, uint32_t index, uint32_t vmdq);
+/**< @internal Add a MAC address into a device */
+
+typedef void (*representor_mac_addr_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	struct ether_addr *mac_addr);
+/**< @internal Set a MAC address of a device. */
+
+typedef int (*representor_stats_get_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	struct rte_eth_stats *stats);
+/**< @internal Get I/O statistics of a device. */
+
+typedef void (*representor_stats_reset_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep);
+/**< @internal Reset global I/O statistics of an Ethernet device to 0. */
+
+typedef void (*representor_dev_infos_get_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	struct rte_eth_dev_info *dev_info);
+/**< @internal Get specific information of an Ethernet device. */
+
+typedef int (*representor_vlan_filter_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint16_t vlan_id, int on);
+/**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
+
+typedef int (*representor_vlan_tpid_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	enum rte_vlan_type type, uint16_t tpid);
+/**< @internal set the outer/inner VLAN-TPID by an Ethernet device. */
+
+typedef void (*representor_vlan_offload_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int mask);
+/**< @internal set VLAN offload function by an Ethernet device. */
+
+typedef void (*representor_vlan_strip_queue_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int on);
+/**< @internal VLAN stripping enable/disable by an queue of Ethernet device. */
+
+typedef int (*representor_vlan_pvid_set_t)(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint16_t vlan_id);
+/**< @internal set port based TX VLAN insertion by an Ethernet device. */
+
+typedef int (*representor_flow_validate_t)(
+		struct rte_port_representor_broker *rb,
+		struct rte_port_representor *prep,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item pattern[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error);
+/**< @internal Check whether a flow rule can be created on a given port. */
+
+typedef struct rte_flow * (*representor_flow_create_t)(
+		struct rte_port_representor_broker *rb,
+		struct rte_port_representor *prep,
+		const struct rte_flow_attr *attr,
+		const struct rte_flow_item pattern[],
+		const struct rte_flow_action actions[],
+		struct rte_flow_error *error);
+/**< @internal Create a flow rule on a given port. */
+
+typedef int (*representor_flow_destroy_t)(
+		struct rte_port_representor_broker *rb,
+		struct rte_port_representor *prep,
+		struct rte_flow *flow,
+		struct rte_flow_error *error);
+/**< @internal Destroy a flow rule on a given port. */
+
+typedef int (*representor_flow_flush_t)(
+		struct rte_port_representor_broker *rb,
+		struct rte_port_representor *prep,
+		struct rte_flow_error *error);
+/**< @internal Destroy all flow rules associated with a port. */
+
+/**
+ * @internal A structure containing the functions exported by a
+ * representor PMD.
+ */
+struct representor_ops {
+	representor_link_update_t link_update; /**< Get device link state. */
+
+	representor_promiscuous_enable_t promiscuous_enable;
+	/**< Promiscuous ON. */
+
+	representor_promiscuous_disable_t promiscuous_disable;
+	/**< Promiscuous OFF. */
+
+	representor_allmulticast_enable_t allmulticast_enable;
+	/**< RX multicast ON. */
+
+	representor_allmulticast_disable_t allmulticast_disable;
+	/**< RX multicast OFF. */
+
+	representor_mac_addr_remove_t mac_addr_remove;
+	/**< Remove MAC address. */
+	representor_mac_addr_add_t mac_addr_add; /**< Add a MAC address. */
+	representor_mac_addr_set_t mac_addr_set; /**< Set a MAC address. */
+
+	representor_stats_get_t stats_get;
+	/**< Get generic device statistics. */
+	representor_stats_reset_t stats_reset;
+	/**< Reset generic device statistics. */
+
+	representor_dev_infos_get_t dev_infos_get;
+	/**< Get device info. */
+
+	representor_vlan_filter_set_t vlan_filter_set;
+	/**< Filter VLAN Setup. */
+	representor_vlan_tpid_set_t vlan_tpid_set;
+	/**< Outer/Inner VLAN TPID Setup. */
+	representor_vlan_offload_set_t vlan_offload_set;
+	/**< Set VLAN Offload. */
+	representor_vlan_strip_queue_set_t vlan_strip_queue_set;
+	/**< VLAN Stripping on queue. */
+	representor_vlan_pvid_set_t vlan_pvid_set;
+	/**< Set port based TX VLAN insertion. */
+
+	representor_flow_validate_t flow_validate;
+	/** Check whether a flow rule can be created on a given port. */
+	representor_flow_create_t flow_create;
+	/** Create a flow rule on a given port. */
+	representor_flow_destroy_t flow_destroy;
+	/** Destroy a flow rule on a given port. */
+	representor_flow_flush_t flow_flush;
+	/** Destroy all flow rules associated with a port. */
+};
+
+struct rte_port_representor {
+	uint32_t pfid; /**< parent physical function id */
+	uint32_t vf_index; /**< virtual function index */
+	struct rte_eth_dev *pdev; /**< parent PF PMD */
+	struct rte_eth_dev *vdev; /**< representor PMD */
+	STAILQ_ENTRY(rte_port_representor) next; /**< list pointer */
+};
+
+struct rte_port_representor_list {
+	uint32_t num; /**< number of representors in the list */
+	STAILQ_HEAD(, rte_port_representor) head; /**< list head */
+};
+
+struct rte_port_representor_broker {
+	uint32_t pfid; /**< physical function id that broker belongs to. */
+	uint32_t max_vf; /**< maximum number of VF to support. */
+	const struct representor_ops *rep_ops;
+	/**< supported ops by representor */
+	struct rte_port_representor_list rep_list; /**< list of representors */
+};
+
+/**
+ * Port representor broker initialization function
+ *
+ * This function is called in HW driver initialization routine if the port
+ * representor is enabled by EAL command line argument.
+ *
+ * @param dev
+ *   The eth_dev structure for physical function.
+ * @param max_vfs
+ *   The maximum number of VFs can be represented by this broker.
+ * @param ops
+ *   Supported representor ops.
+ * @return
+ *   Return the pointer to allocated memory for representor broker.
+ */
+struct rte_port_representor_broker *
+rte_representor_broker_init(struct rte_eth_dev *dev, uint16_t max_vfs,
+	struct representor_ops *ops);
+
+/**
+ * This function adds creates a representor PMD and add to the broker
+ * @param port_id
+ *    The physical function identifier
+ * @param vf_index
+ *    The virtual function index
+ * @param vdev
+ *    Pointer to the allocated rte_eth_dev structure for the representor PMD
+ * @return
+ *    Returns the pointer in broker for the representor PMD
+ */
+struct rte_port_representor *
+rte_representor_initialize(uint32_t port_id, uint32_t vf_index,
+	struct rte_eth_dev *vdev);
+
+/**
+ * This functions deallocates all the allocated memory for representor PMDs
+ * @param port_id
+ *    The physical function identifier
+ */
+void
+rte_representor_broker_free(uint32_t port_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PORT_REPRESENTOR_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [dpdk-dev] [RFC 2/5] added --enable-representor command line argument in EAL to load representor broker infrastructure.
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 1/5] Implemented port representor broker infrastructure, created BDF to port function Mohammad Abdul Awal
@ 2017-09-07  8:35 ` Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 3/5] Implement port representor PMD Mohammad Abdul Awal
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 lib/librte_eal/bsdapp/eal/eal.c            | 6 ++++++
 lib/librte_eal/common/eal_common_options.c | 1 +
 lib/librte_eal/common/eal_internal_cfg.h   | 2 ++
 lib/librte_eal/common/eal_options.h        | 2 ++
 lib/librte_eal/common/include/rte_eal.h    | 8 ++++++++
 lib/librte_eal/linuxapp/eal/eal.c          | 9 +++++++++
 6 files changed, 28 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5fa5988..d1a3c79 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -698,3 +698,9 @@ rte_eal_process_type(void)
 {
 	return rte_config.process_type;
 }
+
+/* return non-zero if port-representor is enabled. */
+int rte_representor_enabled(void)
+{
+	return internal_config.enable_representor;
+}
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1da185e..f9c0b42 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -78,6 +78,7 @@ const struct option
 eal_long_options[] = {
 	{OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
 	{OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
+	{OPT_ENABLE_REPRESENTOR, 0, NULL, OPT_ENABLE_REPRESENTOR_NUM   },
 	{OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
 	{OPT_HELP,              0, NULL, OPT_HELP_NUM             },
 	{OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 7b7e8c8..d0b3080 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -72,6 +72,8 @@ struct internal_config {
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
 	volatile unsigned create_uio_dev; /**< true to create /dev/uioX devices */
+	volatile unsigned enable_representor;
+	/**< true to enable port representor broker for all PFs */
 	volatile enum rte_proc_type_t process_type; /**< multi-process proc type */
 	/** true to try allocating memory on specific sockets */
 	volatile unsigned force_sockets;
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 439a261..a8be6e3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
 	OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_REPRESENTOR    "enable-representor"
+	OPT_ENABLE_REPRESENTOR_NUM,
 #define OPT_FILE_PREFIX       "file-prefix"
 	OPT_FILE_PREFIX_NUM,
 #define OPT_HUGE_DIR          "huge-dir"
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 0e7363d..4d4a6ce 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -287,6 +287,14 @@ static inline int rte_gettid(void)
 	return RTE_PER_LCORE(_thread_id);
 }
 
+/**
+ * Get flag for port representor should be enabled or not.
+ *
+ * @return
+ *   Returns the enable-representor flag.
+ */
+int rte_representor_enabled(void);
+
 #define RTE_INIT(func) \
 static void __attribute__((constructor, used)) func(void)
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..165da30 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -610,6 +610,10 @@ eal_parse_args(int argc, char **argv)
 			internal_config.create_uio_dev = 1;
 			break;
 
+		case OPT_ENABLE_REPRESENTOR_NUM:
+			internal_config.enable_representor = 1;
+			break;
+
 		default:
 			if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
 				RTE_LOG(ERR, EAL, "Option %c is not supported "
@@ -1016,3 +1020,8 @@ rte_eal_check_module(const char *module_name)
 	/* Module has been found */
 	return 1;
 }
+
+int rte_representor_enabled(void)
+{
+	return internal_config.enable_representor;
+}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [dpdk-dev] [RFC 3/5] Implement port representor PMD
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 1/5] Implemented port representor broker infrastructure, created BDF to port function Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 2/5] added --enable-representor command line argument in EAL to load representor broker infrastructure Mohammad Abdul Awal
@ 2017-09-07  8:35 ` Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 4/5] Enable port representor PMD and broker for fortville PMD driver Mohammad Abdul Awal
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 config/common_base                                 |   5 +
 drivers/net/Makefile                               |   2 +
 drivers/net/representor/Makefile                   |  51 ++
 drivers/net/representor/rte_eth_representor.c      | 973 +++++++++++++++++++++
 .../representor/rte_pmd_representor_version.map    |   4 +
 lib/librte_ether/rte_ethdev_vdev.h                 |  37 +-
 mk/rte.app.mk                                      |   1 +
 7 files changed, 1070 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/representor/Makefile
 create mode 100644 drivers/net/representor/rte_eth_representor.c
 create mode 100644 drivers/net/representor/rte_pmd_representor_version.map

diff --git a/config/common_base b/config/common_base
index 5e97a08..d7ba871 100644
--- a/config/common_base
+++ b/config/common_base
@@ -750,3 +750,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile representor PMD
+#
+CONFIG_RTE_LIBRTE_PMD_REPRESENTOR=y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d33c959..1b76a42 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -83,6 +83,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DEPDIRS-pcap = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede
 DEPDIRS-qede = $(core-libs)
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_REPRESENTOR) += representor
+DEPDIRS-representor = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
 DEPDIRS-ring = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc
diff --git a/drivers/net/representor/Makefile b/drivers/net/representor/Makefile
new file mode 100644
index 0000000..18b23f4
--- /dev/null
+++ b/drivers/net/representor/Makefile
@@ -0,0 +1,51 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2017 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_representor.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pmd_representor_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_REPRESENTOR) += rte_eth_representor.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/representor/rte_eth_representor.c b/drivers/net/representor/rte_eth_representor.c
new file mode 100644
index 0000000..cec532d
--- /dev/null
+++ b/drivers/net/representor/rte_eth_representor.c
@@ -0,0 +1,973 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_ethdev_vdev.h>
+#include <rte_vdev.h>
+#include <rte_kvargs.h>
+#include <rte_port_representor.h>
+#include <rte_flow_driver.h>
+
+#define PORT_REP_MAX_VFS 64
+
+static struct ether_addr list_eth_addrs[PORT_REP_MAX_VFS];
+
+struct port_rep_parameters {
+	uint32_t mask;
+	uint64_t vf_mask;
+	uint8_t parent;
+};
+
+struct port_rep_internals {
+	uint8_t port_id;
+	struct port_rep_parameters params;
+	struct rte_port_representor *port_rep;
+};
+
+static struct port_rep_parameters vdev_params;
+
+static inline void
+apply_range_to_mask(int lower, int upper, uint64_t *mask)
+{
+	int idx_mask;
+
+	for (idx_mask = lower; idx_mask <= upper; idx_mask++)
+		*mask = *mask | (0x01ULL << idx_mask);
+}
+
+static int
+range_to_mask(const char *range_str, uint64_t *mask)
+{
+	int value;
+	int state;
+	int lower_bound;
+
+	state = 0;
+	while (1) {
+		switch (state) {
+		case 0: /* Initial */
+			if (!isdigit(*range_str))
+				return -EINVAL;
+			value = *range_str - '0';
+			state = 1;
+			break;
+
+		case 1: /* Parsing lower bound */
+			if (isdigit(*range_str)) {
+				value *= 10;
+				value += *range_str - '0';
+			} else if (*range_str == '-') {
+				state = '-';
+				lower_bound = value;
+				value = 0;
+			} else if (*range_str == '\0') {
+				apply_range_to_mask(value, value, mask);
+				return 0;
+			} else if (*range_str == ':') {
+				apply_range_to_mask(value, value, mask);
+				value = 0;
+				state = 0;
+			} else {
+				return -EINVAL;
+			}
+			break;
+
+		case '-': /* Parsing upper bound */
+			if (isdigit(*range_str)) {
+				value *= 10;
+				value += *range_str - '0';
+			} else if (*range_str == '\0') {
+				apply_range_to_mask(lower_bound, value, mask);
+				return 0;
+			} else if (*range_str == ':') {
+				apply_range_to_mask(lower_bound, value, mask);
+				value = 0;
+				state = 0;
+			} else {
+				return -EINVAL;
+			}
+			break;
+		}
+		range_str++;
+	}
+
+	return -EINVAL;
+}
+
+/****************************************************************************
+ * PMD operation callbacks
+ ****************************************************************************/
+
+static void
+port_rep_info(struct rte_eth_dev *dev,
+		struct rte_eth_dev_info *dev_info)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev || !dev_info)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep) {
+		RTE_LOG(ERR, PMD, "Representor PMD is NULL\n");
+		return;
+	}
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker) {
+		RTE_LOG(ERR, PMD, "Representor Broker is NULL\n");
+		return;
+	}
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->dev_infos_get);
+	repr_broker->rep_ops->dev_infos_get(repr_broker, internals->port_rep,
+		dev_info);
+}
+
+static int
+port_rep_start(struct rte_eth_dev *dev)
+{
+	if (!dev)
+		return -EINVAL;
+
+	dev->data->dev_link.link_status = ETH_LINK_UP;
+	return 0;
+}
+
+static void
+port_rep_stop(struct rte_eth_dev *dev)
+{
+	if (!dev)
+		return;
+
+	dev->data->dev_link.link_status = ETH_LINK_DOWN;
+}
+
+static int
+port_rep_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		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)
+{
+	if (!dev || !mb_pool)
+		return -EINVAL;
+
+	if (rx_queue_id >= dev->data->nb_rx_queues)
+		return -ENODEV;
+
+	dev->data->rx_queues[rx_queue_id] = (void *)0xdeadbeef;
+
+	return 0;
+}
+
+static int
+port_rep_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+		uint16_t nb_tx_desc __rte_unused,
+		unsigned int socket_id __rte_unused,
+		const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+	if (!dev)
+		return -EINVAL;
+
+	if (tx_queue_id >= dev->data->nb_tx_queues)
+		return -ENODEV;
+
+	dev->data->tx_queues[tx_queue_id] = (void *)0xdeadbeef;
+
+	return 0;
+}
+
+static void
+port_rep_queue_release(__rte_unused void *q)
+{
+}
+
+static int
+port_rep_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->link_update, -ENOTSUP);
+
+	return repr_broker->rep_ops->link_update(repr_broker,
+		internals->port_rep, wait_to_complete);
+}
+
+static void
+port_rep_promiscuous_enable(struct rte_eth_dev *dev)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->promiscuous_enable);
+	repr_broker->rep_ops->promiscuous_enable(
+		repr_broker, internals->port_rep);
+}
+
+static void
+port_rep_promiscuous_disable(struct rte_eth_dev *dev)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->promiscuous_disable);
+	repr_broker->rep_ops->promiscuous_disable(
+		repr_broker, internals->port_rep);
+}
+
+static void
+port_rep_allmulticast_enable(struct rte_eth_dev *dev)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->allmulticast_enable);
+	repr_broker->rep_ops->allmulticast_enable(
+		repr_broker, internals->port_rep);
+}
+
+static void
+port_rep_allmulticast_disable(struct rte_eth_dev *dev)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->allmulticast_disable);
+	repr_broker->rep_ops->allmulticast_disable(
+		repr_broker, internals->port_rep);
+}
+
+static void
+port_rep_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->mac_addr_remove);
+	repr_broker->rep_ops->mac_addr_remove(
+		repr_broker, internals->port_rep, index);
+}
+
+static int
+port_rep_mac_addr_add(__rte_unused struct rte_eth_dev *dev,
+	struct ether_addr *mac_addr, uint32_t index, uint32_t vmdq)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->mac_addr_add, -ENOTSUP);
+
+	return repr_broker->rep_ops->mac_addr_add(repr_broker,
+		internals->port_rep, mac_addr, index, vmdq);
+}
+
+static void
+port_rep_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev || !mac_addr)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->mac_addr_set);
+	repr_broker->rep_ops->mac_addr_set(repr_broker, internals->port_rep,
+		mac_addr);
+}
+
+static int
+port_rep_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id,  int on)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->vlan_filter_set,
+		-ENOTSUP);
+	return repr_broker->rep_ops->vlan_filter_set(repr_broker,
+		internals->port_rep, vlan_id, on);
+}
+
+static int
+port_rep_vlan_tpid_set(struct rte_eth_dev *dev, enum rte_vlan_type type,
+	uint16_t tpid)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->vlan_tpid_set, -ENOTSUP);
+
+	return repr_broker->rep_ops->vlan_tpid_set(repr_broker,
+		internals->port_rep, type, tpid);
+}
+
+static void
+port_rep_vlan_strip_queue_set(struct rte_eth_dev *dev,
+	__rte_unused uint16_t rx_queue_id, int on)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->vlan_strip_queue_set);
+	repr_broker->rep_ops->vlan_strip_queue_set(repr_broker,
+		internals->port_rep, on);
+}
+
+static void
+port_rep_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->vlan_offload_set);
+	repr_broker->rep_ops->vlan_offload_set(repr_broker,
+		internals->port_rep, mask);
+}
+
+static int
+port_rep_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t vlan_id,
+	__rte_unused int on)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->vlan_pvid_set, -ENOTSUP);
+
+	return repr_broker->rep_ops->vlan_pvid_set(repr_broker,
+		internals->port_rep, vlan_id);
+}
+
+static void
+port_rep_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->stats_get);
+	repr_broker->rep_ops->stats_get(repr_broker,
+		internals->port_rep, stats);
+}
+
+static void
+port_rep_stats_reset(struct rte_eth_dev *dev)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return;
+
+	RTE_FUNC_PTR_OR_RET(*repr_broker->rep_ops->stats_reset);
+	repr_broker->rep_ops->stats_reset(repr_broker,
+		internals->port_rep);
+}
+
+static int
+port_rep_flow_validate(struct rte_eth_dev *dev,
+	const struct rte_flow_attr *attr, const struct rte_flow_item pattern[],
+	const struct rte_flow_action actions[], struct rte_flow_error *error)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->flow_validate, -EINVAL);
+	return repr_broker->rep_ops->flow_validate(repr_broker,
+		internals->port_rep, attr, pattern, actions, error);
+}
+
+static struct rte_flow *
+port_rep_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
+	const struct rte_flow_item pattern[],
+	const struct rte_flow_action actions[], struct rte_flow_error *error)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return NULL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return NULL;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return NULL;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->flow_validate, NULL);
+	return repr_broker->rep_ops->flow_create(repr_broker,
+		internals->port_rep, attr, pattern, actions, error);
+}
+
+static int
+port_rep_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
+	struct rte_flow_error *error)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->flow_validate, -EINVAL);
+	return repr_broker->rep_ops->flow_destroy(repr_broker,
+		internals->port_rep, flow, error);
+}
+
+static int
+port_rep_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
+{
+	struct port_rep_internals *internals;
+	struct rte_port_representor_broker *repr_broker;
+
+	if (!dev)
+		return -EINVAL;
+
+	internals = dev->data->dev_private;
+	if (!internals->port_rep)
+		return -ENODEV;
+	repr_broker = internals->port_rep->pdev->rep_broker;
+	if (!repr_broker)
+		return -ENODEV;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*repr_broker->rep_ops->flow_validate, -EINVAL);
+	return repr_broker->rep_ops->flow_flush(repr_broker,
+		internals->port_rep, error);
+}
+
+static const struct rte_flow_ops port_rep_flow_ops = {
+	.validate = port_rep_flow_validate,
+	.create = port_rep_flow_create,
+	.destroy = port_rep_flow_destroy,
+	.flush = port_rep_flow_flush,
+};
+
+static int
+port_rep_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type,
+	enum rte_filter_op filter_op, void *arg)
+{
+	int ret = 0;
+
+	if (!dev)
+		return -EINVAL;
+
+	switch (filter_type) {
+	case RTE_ETH_FILTER_GENERIC:
+		if (filter_op != RTE_ETH_FILTER_GET)
+			return -EINVAL;
+		*(const void **)arg = &port_rep_flow_ops;
+		break;
+	default:
+		RTE_LOG(WARNING, PMD, "Filter type (%d) not supported",
+			filter_type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/* Stub function to make eth_dev happy */
+static int
+port_rep_configure(__rte_unused struct rte_eth_dev *dev)
+{
+	return 0;
+}
+
+/* Stub function to make eth_dev happy */
+static uint16_t
+port_rep_rx(__rte_unused void *q, __rte_unused struct rte_mbuf **bufs,
+	__rte_unused uint16_t nb_bufs)
+{
+	return 0;
+}
+
+/* Stub function to make eth_dev happy */
+static uint16_t
+port_rep_tx(__rte_unused void *q, __rte_unused struct rte_mbuf **bufs,
+	__rte_unused uint16_t nb_bufs)
+{
+	return 0;
+}
+
+static const struct eth_dev_ops port_rep_ops = {
+	.dev_start = port_rep_start,
+	.dev_stop = port_rep_stop,
+	.dev_configure = port_rep_configure,
+	.dev_infos_get = port_rep_info,
+	.rx_queue_setup = port_rep_rx_queue_setup,
+	.tx_queue_setup = port_rep_tx_queue_setup,
+	.rx_queue_release = port_rep_queue_release,
+	.tx_queue_release = port_rep_queue_release,
+
+	.link_update = port_rep_link_update,
+
+	.promiscuous_enable = port_rep_promiscuous_enable,
+	.promiscuous_disable = port_rep_promiscuous_disable,
+	.allmulticast_enable = port_rep_allmulticast_enable,
+	.allmulticast_disable = port_rep_allmulticast_disable,
+
+	.mac_addr_remove = port_rep_mac_addr_remove,
+	.mac_addr_add = port_rep_mac_addr_add,
+	.mac_addr_set = port_rep_mac_addr_set,
+
+	.vlan_filter_set = port_rep_vlan_filter_set,
+	.vlan_tpid_set = port_rep_vlan_tpid_set,
+	.vlan_strip_queue_set = port_rep_vlan_strip_queue_set,
+	.vlan_offload_set = port_rep_vlan_offload_set,
+	.vlan_pvid_set = port_rep_vlan_pvid_set,
+
+	.stats_get = port_rep_stats_get,
+	.stats_reset = port_rep_stats_reset,
+
+	.filter_ctrl = port_rep_filter_ctrl,
+};
+
+/****************************************************************************
+ * Startup & parameter handling
+ ****************************************************************************/
+
+static void port_rep_default_params(struct port_rep_parameters *params)
+{
+	params->parent = -1;
+	params->vf_mask = 0UL;
+}
+
+static int
+port_rep_kvargs_parent(__rte_unused const char *key,
+	const char *value, void *ptr)
+{
+	struct port_rep_parameters *params = ptr;
+	int ret = 0;
+
+	/* only added this check to accept uint values as we do not have
+	 * B:D:F to uint mapping function
+	 */
+	if (!strchr(value, ':')) {
+		params->parent = strtoul(value, NULL, 0);
+	} else {
+		ret = rte_eth_dev_get_port_by_pci_addr_str(value,
+			&params->parent);
+		if (ret != 0)
+			RTE_LOG(ERR, PMD,
+				"'pfid=%s' does not give a valid device name\n",
+				value);
+	}
+
+	return ret;
+}
+
+static int
+port_rep_kvargs_vf_index(__rte_unused const char *key,
+	const char *value, void *ptr)
+{
+	struct port_rep_parameters *params = ptr;
+	int ret;
+
+	ret = range_to_mask(value, &params->vf_mask);
+	if (ret != 0)
+		RTE_LOG(ERR, PMD, "'vf_index=%s' does not give a valid device "
+			"name\n", value);
+	return ret;
+}
+
+typedef int (*port_rep_arg_func_t)(const char*, const char*, void*);
+
+static const char * const port_rep_kvargs_codes[] = {
+	"parent", "vf_index", NULL
+};
+
+static port_rep_arg_func_t port_rep_kvargs_callbacks[] = {
+	&port_rep_kvargs_parent,
+	&port_rep_kvargs_vf_index,
+	NULL
+};
+
+static int
+port_rep_create(struct rte_vdev_device *dev,
+	struct port_rep_parameters *params)
+{
+	const unsigned nb_rx_queues = 1;
+	const unsigned nb_tx_queues = 1;
+	struct rte_eth_dev_data *data = NULL;
+	struct port_rep_internals *internals = NULL;
+	struct rte_eth_dev *eth_dev = NULL;
+	struct rte_port_representor *rep = NULL;
+	uint64_t vf_mask;
+	uint16_t idx_vf;
+
+	char name_buffer[RTE_ETH_NAME_MAX_LEN];
+
+	if (dev->device.numa_node == SOCKET_ID_ANY)
+		dev->device.numa_node = rte_socket_id();
+
+	RTE_LOG(INFO, PMD, "Creating representor ethdev on numa socket %u\n",
+		dev->device.numa_node);
+
+	memset(&list_eth_addrs, 0, sizeof(list_eth_addrs));
+
+	vf_mask = 1;
+	idx_vf = 0;
+	while (vf_mask <= params->vf_mask) {
+		if (params->vf_mask & vf_mask) {
+			/* now do all data allocation - for eth_dev structure,
+			 * dummy pci driver and internal (private) data
+			 */
+			data = rte_zmalloc_socket(rte_vdev_device_name(dev),
+				sizeof(*data), 0, dev->device.numa_node);
+			if (!data)
+				return -ENOMEM;
+
+			snprintf(name_buffer, RTE_ETH_NAME_MAX_LEN,
+				"%s.%i", rte_vdev_device_name(dev), idx_vf);
+
+			eth_dev = rte_eth_vdev_allocate_2(dev,
+				sizeof(*internals), name_buffer);
+			if (!eth_dev) {
+				rte_free(data);
+				return -ENOMEM;
+			}
+			/* create hook for port representor in broker */
+			rep = NULL;
+			if (rte_representor_enabled()) {
+				rep = rte_representor_initialize(
+					params->parent, idx_vf, eth_dev);
+				if (!rep) {
+					rte_free(data);
+					return -ENOMEM;
+				}
+			}
+			/* now put it all together
+			 * - store queue data in internals,
+			 * - store numa_node info in ethdev data
+			 * - point eth_dev_data to internals
+			 * - and point eth_dev structure to new eth_dev_data
+			 *   structure
+			 */
+			/* NOTE: we'll replace the data element, of originally
+			 * allocated eth_dev so the nulls are local per-process
+			 */
+
+			internals = eth_dev->data->dev_private;
+
+			rte_memcpy(&internals->params, params,
+				sizeof(struct port_rep_parameters));
+			internals->port_id = eth_dev->data->port_id;
+			internals->port_rep = rep;
+
+			rte_memcpy(data, eth_dev->data, sizeof(*data));
+			data->nb_rx_queues = (uint16_t)nb_rx_queues;
+			data->nb_tx_queues = (uint16_t)nb_tx_queues;
+
+			/* Link state. */
+			data->dev_link.link_speed = ETH_SPEED_NUM_10G;
+			data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+			data->dev_link.link_status = ETH_LINK_DOWN;
+			data->dev_link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
+
+			/* MAC address. Same caveats as link state. */
+			data->mac_addrs = &list_eth_addrs[idx_vf];
+
+			eth_dev->data = data;
+			eth_dev->dev_ops = &port_rep_ops;
+
+			data->dev_flags = RTE_ETH_DEV_DETACHABLE;
+
+			/* finally assign rx and tx ops */
+			eth_dev->rx_pkt_burst = port_rep_rx;
+			eth_dev->tx_pkt_burst = port_rep_tx;
+		}
+		/* Keep bitmask and bit index in sync */
+		vf_mask = vf_mask << 1;
+		idx_vf++;
+	}
+
+	return 0;
+}
+
+static int
+port_rep_probe(struct rte_vdev_device *dev)
+{
+	const char *name;
+	const char *args;
+	struct rte_kvargs *kvlist = NULL;
+	int ret;
+	int idx_table;
+
+	if (!dev)
+		return -EINVAL;
+
+	port_rep_default_params(&vdev_params);
+
+	name = rte_vdev_device_name(dev);
+	args = rte_vdev_device_args(dev);
+	RTE_LOG(INFO, PMD, "Initializing port_representor pmd for %s\n", name);
+	if (args) {
+		kvlist = rte_kvargs_parse(args, port_rep_kvargs_codes);
+		if (!kvlist)
+			return -1;
+
+		idx_table = 0;
+		while (port_rep_kvargs_codes[idx_table] != NULL) {
+			ret = rte_kvargs_process(kvlist,
+				port_rep_kvargs_codes[idx_table],
+				port_rep_kvargs_callbacks[idx_table],
+				&vdev_params);
+			if (ret != 0) {
+				RTE_LOG(ERR, PMD, "port_representor pmd "
+					"parameter error\n");
+				rte_kvargs_free(kvlist);
+				return -1;
+			}
+			idx_table++;
+		}
+	}
+	RTE_LOG(INFO, PMD, "Configure port_representor pmd with args=\"%s\"\n",
+		args);
+
+	ret = port_rep_create(dev, &vdev_params);
+
+	if (kvlist)
+		rte_kvargs_free(kvlist);
+
+	return ret;
+}
+
+static int
+port_rep_remove(struct rte_vdev_device *dev)
+{
+	struct rte_eth_dev *eth_dev = NULL;
+	uint64_t vf_mask;
+	uint16_t cnt_vf;
+	char name_buffer[RTE_ETH_NAME_MAX_LEN];
+
+	if (!dev)
+		return -EINVAL;
+
+	RTE_LOG(INFO, PMD, "Closing representor port on numa socket %u\n",
+			rte_socket_id());
+
+	vf_mask = 1;
+	cnt_vf = 0;
+	while (vf_mask <= vdev_params.vf_mask) {
+		if (vdev_params.vf_mask & vf_mask) {
+			snprintf(name_buffer, RTE_ETH_NAME_MAX_LEN, "%s.%i",
+				rte_vdev_device_name(dev), cnt_vf);
+
+			/* Find and deallocate the ethdev entry */
+			eth_dev = rte_eth_dev_allocated(
+					rte_vdev_device_name(dev));
+			if (!eth_dev)
+				return -1;
+
+			rte_free(eth_dev->data->dev_private);
+			rte_free(eth_dev->data);
+			rte_eth_dev_release_port(eth_dev);
+		}
+
+		cnt_vf++;
+		vf_mask = vf_mask << 1;
+	}
+
+	return 0;
+}
+
+static struct rte_vdev_driver port_rep_vdev_drv = {
+	.probe = port_rep_probe,
+	.remove = port_rep_remove,
+};
+
+RTE_PMD_REGISTER_VDEV(net_representor, port_rep_vdev_drv);
+RTE_PMD_REGISTER_ALIAS(net_representor, eth_representor);
+RTE_PMD_REGISTER_PARAM_STRING(net_representor,
+	"parent=<pci addr>:vf_index=<uint range>");
diff --git a/drivers/net/representor/rte_pmd_representor_version.map b/drivers/net/representor/rte_pmd_representor_version.map
new file mode 100644
index 0000000..ef35398
--- /dev/null
+++ b/drivers/net/representor/rte_pmd_representor_version.map
@@ -0,0 +1,4 @@
+DPDK_2.0 {
+
+	local: *;
+};
diff --git a/lib/librte_ether/rte_ethdev_vdev.h b/lib/librte_ether/rte_ethdev_vdev.h
index 4d2c3e2..7aaaca3 100644
--- a/lib/librte_ether/rte_ethdev_vdev.h
+++ b/lib/librte_ether/rte_ethdev_vdev.h
@@ -49,18 +49,29 @@
  * @param private_data_size
  *	Size of private data structure
  *
+ * @param override_name
+ *	Given name for the vdev instead of default one
+ *
  * @return
  *	A pointer to a rte_eth_dev or NULL if allocation failed.
  */
 static inline struct rte_eth_dev *
-rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
+rte_eth_vdev_allocate_2(struct rte_vdev_device *dev, size_t private_data_size,
+	const char *override_name)
 {
 	struct rte_eth_dev *eth_dev;
-	const char *name = rte_vdev_device_name(dev);
+	const char *name;
+
+	if (override_name)
+		name = override_name;
+	else
+		name = rte_vdev_device_name(dev);
 
 	eth_dev = rte_eth_dev_allocate(name);
-	if (!eth_dev)
+	if (!eth_dev) {
+		printf("FAILED!\n");
 		return NULL;
+	}
 
 	if (private_data_size) {
 		eth_dev->data->dev_private = rte_zmalloc_socket(name,
@@ -80,4 +91,24 @@ rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
 	return eth_dev;
 }
 
+/**
+ * @internal
+ * Allocates a new ethdev slot for an ethernet device and returns the pointer
+ * to that slot for the driver to use.
+ *
+ * @param dev
+ *	Pointer to virtual device
+ *
+ * @param private_data_size
+ *	Size of private data structure
+ *
+ * @return
+ *	A pointer to a rte_eth_dev or NULL if allocation failed.
+ */
+static inline struct rte_eth_dev *
+rte_eth_vdev_allocate(struct rte_vdev_device *dev, size_t private_data_size)
+{
+	return rte_eth_vdev_allocate_2(dev, private_data_size, NULL);
+}
+
 #endif /* _RTE_ETHDEV_VDEV_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..3dbbe3a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -132,6 +132,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4 -libverbs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_REPRESENTOR) += -lrte_pmd_representor
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap -lpcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD)       += -lrte_pmd_qede
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [dpdk-dev] [RFC 4/5] Enable port representor PMD and broker for fortville PMD driver
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
                   ` (2 preceding siblings ...)
  2017-09-07  8:35 ` [dpdk-dev] [RFC 3/5] Implement port representor PMD Mohammad Abdul Awal
@ 2017-09-07  8:35 ` Mohammad Abdul Awal
  2017-09-07  8:35 ` [dpdk-dev] [RFC 5/5] Enable port representor PMD and broker for ixgbe " Mohammad Abdul Awal
  2017-09-07 10:01 ` [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Alejandro Lucero
  5 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 drivers/net/i40e/Makefile        |   1 +
 drivers/net/i40e/i40e_ethdev.c   |  17 ++
 drivers/net/i40e/i40e_prep_ops.c | 402 +++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_prep_ops.h |  41 ++++
 drivers/net/i40e/rte_pmd_i40e.c  |  47 +++++
 drivers/net/i40e/rte_pmd_i40e.h  |  18 ++
 6 files changed, 526 insertions(+)
 create mode 100644 drivers/net/i40e/i40e_prep_ops.c
 create mode 100644 drivers/net/i40e/i40e_prep_ops.h

diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 55c79a6..a299a1e 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -110,6 +110,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_fdir.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += rte_pmd_i40e.c
 SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_tm.c
+SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_prep_ops.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_I40E_PMD)-include := rte_pmd_i40e.h
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..942a587 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -65,6 +65,7 @@
 #include "i40e_rxtx.h"
 #include "i40e_pf.h"
 #include "i40e_regs.h"
+#include "i40e_prep_ops.h"
 
 #define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
 #define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
@@ -1045,6 +1046,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	int ret;
 	uint32_t len;
 	uint8_t aq_fail = 0;
+	struct rte_port_representor_broker *rb;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1088,6 +1090,17 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	hw->bus.func = pci_dev->addr.function;
 	hw->adapter_stopped = 0;
 
+	/* init representor broker */
+	if (rte_representor_enabled()) {
+		rb = rte_representor_broker_init(dev, pci_dev->max_vfs,
+			rte_i40e_prep_ops);
+		if (rb == NULL) {
+			PMD_INIT_LOG(ERR, "Cannot allocate memory for "
+				"representor broker data\n");
+			return errno;
+		}
+	}
+
 	/* Make sure all is clean before doing PF reset */
 	i40e_clear_hw(hw);
 
@@ -2130,6 +2143,10 @@ i40e_dev_close(struct rte_eth_dev *dev)
 
 	PMD_INIT_FUNC_TRACE();
 
+	/* free port representor pmds */
+	if (rte_representor_enabled())
+		rte_representor_broker_free(dev->data->port_id);
+
 	i40e_dev_stop(dev);
 	i40e_dev_free_queues(dev);
 
diff --git a/drivers/net/i40e/i40e_prep_ops.c b/drivers/net/i40e/i40e_prep_ops.c
new file mode 100644
index 0000000..15aaeb3
--- /dev/null
+++ b/drivers/net/i40e/i40e_prep_ops.c
@@ -0,0 +1,402 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+
+#include "base/i40e_type.h"
+#include "base/virtchnl.h"
+#include "i40e_ethdev.h"
+#include "i40e_rxtx.h"
+#include "rte_pmd_i40e.h"
+
+#include "i40e_prep_ops.h"
+
+static int i40e_prep_link_update(
+	__rte_unused struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int wait_to_complete)
+{
+	struct rte_eth_dev *pfdev;
+
+	pfdev = prep->pdev;
+
+	return i40e_dev_link_update(pfdev, wait_to_complete);
+}
+
+static void i40e_prep_promiscuous_enable(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_unicast_promisc(pfid, vf_index, 1);
+	/* 1 for enable */
+}
+
+static void i40e_prep_promiscuous_disable(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_unicast_promisc(pfid, vf_index, 0);
+	/* 0 for disable */
+}
+
+static void i40e_prep_allmulticast_enable(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_multicast_promisc(pfid, vf_index, 1);
+	/* 1 for enable */
+}
+
+static void i40e_prep_allmulticast_disable(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_multicast_promisc(pfid, vf_index, 0);
+	/* 0 for disable*/
+}
+
+static void i40e_prep_mac_addr_remove(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint32_t index)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+	struct rte_eth_dev *vdev;
+	struct ether_addr mac_addr;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+	vdev = prep->vdev;
+	memcpy(&mac_addr, &vdev->data->mac_addrs[index], ETHER_ADDR_LEN);
+
+	rte_pmd_i40e_remove_vf_mac_addr(pfid, vf_index, &mac_addr);
+}
+
+/* for now, the VF can have only one mac addr, which can be set by
+ * i40e_prep_mac_addr_set(...) function
+ */
+static int i40e_prep_mac_addr_add(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused struct ether_addr *mac_addr, __rte_unused uint32_t index,
+	__rte_unused uint32_t vmdq)
+{
+	return -ENOTSUP;
+}
+
+static void i40e_prep_mac_addr_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, struct ether_addr *mac_addr)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_mac_addr(pfid, vf_index, mac_addr);
+}
+
+static int i40e_prep_stats_get(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, struct rte_eth_stats *stats)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	return rte_pmd_i40e_get_vf_stats(pfid, vf_index, stats);
+}
+
+static void i40e_prep_stats_reset(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_reset_vf_stats(pfid, vf_index);
+}
+
+static void i40e_prep_dev_infos_get(
+	__rte_unused struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, struct rte_eth_dev_info *dev_info)
+{
+	struct rte_eth_dev *pdev;
+	struct rte_eth_dev *vdev;
+	struct i40e_pf_vf *vf;
+	struct i40e_vsi *vsi;
+	struct i40e_pf *pf;
+	uint32_t vf_index;
+
+	pdev = prep->pdev;
+	vdev = prep->vdev;
+	vf_index = prep->vf_index;
+
+	if (!is_i40e_supported(pdev)) {
+		PMD_DRV_LOG(ERR, "Invalid PF dev.");
+		return;
+	}
+
+	pf = I40E_DEV_PRIVATE_TO_PF(pdev->data->dev_private);
+
+	if (vf_index >= pf->vf_num || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid VF ID.");
+		return;
+	}
+
+	vf = &pf->vfs[vf_index];
+	vsi = vf->vsi;
+	if (!vsi) {
+		PMD_DRV_LOG(ERR, "Invalid VSI.");
+		return;
+	}
+
+	/* get dev info for the vdev */
+	memset(dev_info, 0, sizeof(*dev_info));
+	dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(vdev);
+	dev_info->max_rx_queues = vsi->nb_qps;
+	dev_info->max_tx_queues = vsi->nb_qps;
+	dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
+	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
+	dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) *
+		sizeof(uint32_t);
+	dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
+	dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+	dev_info->max_mac_addrs = I40E_NUM_MACADDR_MAX;
+	dev_info->rx_offload_capa =
+		DEV_RX_OFFLOAD_VLAN_STRIP |
+		DEV_RX_OFFLOAD_QINQ_STRIP |
+		DEV_RX_OFFLOAD_IPV4_CKSUM |
+		DEV_RX_OFFLOAD_UDP_CKSUM |
+		DEV_RX_OFFLOAD_TCP_CKSUM;
+	dev_info->tx_offload_capa =
+		DEV_TX_OFFLOAD_VLAN_INSERT |
+		DEV_TX_OFFLOAD_QINQ_INSERT |
+		DEV_TX_OFFLOAD_IPV4_CKSUM |
+		DEV_TX_OFFLOAD_UDP_CKSUM |
+		DEV_TX_OFFLOAD_TCP_CKSUM |
+		DEV_TX_OFFLOAD_SCTP_CKSUM;
+
+	dev_info->default_rxconf = (struct rte_eth_rxconf) {
+		.rx_thresh = {
+			.pthresh = I40E_DEFAULT_RX_PTHRESH,
+			.hthresh = I40E_DEFAULT_RX_HTHRESH,
+			.wthresh = I40E_DEFAULT_RX_WTHRESH,
+		},
+		.rx_free_thresh = I40E_DEFAULT_RX_FREE_THRESH,
+		.rx_drop_en = 0,
+	};
+
+	dev_info->default_txconf = (struct rte_eth_txconf) {
+		.tx_thresh = {
+			.pthresh = I40E_DEFAULT_TX_PTHRESH,
+			.hthresh = I40E_DEFAULT_TX_HTHRESH,
+			.wthresh = I40E_DEFAULT_TX_WTHRESH,
+		},
+		.tx_free_thresh = I40E_DEFAULT_TX_FREE_THRESH,
+		.tx_rs_thresh = I40E_DEFAULT_TX_RSBIT_THRESH,
+		.txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
+				ETH_TXQ_FLAGS_NOOFFLOADS,
+	};
+
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = I40E_MAX_RING_DESC,
+		.nb_min = I40E_MIN_RING_DESC,
+		.nb_align = I40E_ALIGN_RING_DESC,
+	};
+
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = I40E_MAX_RING_DESC,
+		.nb_min = I40E_MIN_RING_DESC,
+		.nb_align = I40E_ALIGN_RING_DESC,
+	};
+}
+
+static int i40e_prep_vlan_filter_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint16_t vlan_id, int on)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+	uint64_t vf_mask;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+	vf_mask = 1ULL << vf_index;
+
+	return rte_pmd_i40e_set_vf_vlan_filter(pfid, vlan_id, vf_mask, on);
+}
+
+static int i40e_prep_vlan_tpid_set(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused enum rte_vlan_type type, __rte_unused uint16_t tpid)
+{
+	return -ENOTSUP;
+}
+
+static void i40e_prep_vlan_offload_set(
+	__rte_unused struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int mask)
+{
+	struct rte_eth_dev *pdev;
+	struct rte_eth_dev *vdev;
+	struct i40e_pf_vf *vf;
+	struct i40e_vsi *vsi;
+	struct i40e_pf *pf;
+	uint32_t vf_index;
+
+	pdev = prep->pdev;
+	vdev = prep->vdev;
+	vf_index = prep->vf_index;
+
+	if (!is_i40e_supported(pdev)) {
+		PMD_DRV_LOG(ERR, "Invalid PF dev.");
+		return;
+	}
+
+	pf = I40E_DEV_PRIVATE_TO_PF(pdev->data->dev_private);
+
+	if (vf_index >= pf->vf_num || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid VF ID.");
+		return;
+	}
+
+	vf = &pf->vfs[vf_index];
+	vsi = vf->vsi;
+	if (!vsi) {
+		PMD_DRV_LOG(ERR, "Invalid VSI.");
+		return;
+	}
+
+	/* Fixme: even though there 3 kinds of hw offloads, hw_vlan_filter,
+	 * hw_vlan_strip, and hw_vlan_extend.
+	 * currently the hw_vlan_extend offload by vsi is not implemented.
+	 */
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		/* Enable or disable VLAN filtering offload */
+		if (vdev->data->dev_conf.rxmode.hw_vlan_filter)
+			i40e_vsi_config_vlan_filter(vsi, TRUE);
+		else
+			i40e_vsi_config_vlan_filter(vsi, FALSE);
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		/* Enable or disable VLAN stripping offload */
+		if (vdev->data->dev_conf.rxmode.hw_vlan_strip)
+			i40e_vsi_config_vlan_stripping(vsi, TRUE);
+		else
+			i40e_vsi_config_vlan_stripping(vsi, FALSE);
+	}
+}
+
+static void i40e_prep_vlan_strip_queue_set(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int on)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_i40e_set_vf_vlan_stripq(pfid, vf_index, on);
+}
+
+static int i40e_prep_vlan_pvid_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint16_t vlan_id)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	return rte_pmd_i40e_set_vf_vlan_insert(pfid, vf_index, vlan_id);
+}
+
+struct representor_ops i40e_prep_ops = {
+	.link_update                  = i40e_prep_link_update,
+
+	.promiscuous_enable           = i40e_prep_promiscuous_enable,
+	.promiscuous_disable          = i40e_prep_promiscuous_disable,
+	.allmulticast_enable          = i40e_prep_allmulticast_enable,
+	.allmulticast_disable         = i40e_prep_allmulticast_disable,
+
+	.mac_addr_remove              = i40e_prep_mac_addr_remove,
+	.mac_addr_add                 = i40e_prep_mac_addr_add,
+	.mac_addr_set                 = i40e_prep_mac_addr_set,
+
+	.stats_get                    = i40e_prep_stats_get,
+	.stats_reset                  = i40e_prep_stats_reset,
+
+	.dev_infos_get                = i40e_prep_dev_infos_get,
+
+	.vlan_filter_set              = i40e_prep_vlan_filter_set,
+	.vlan_tpid_set                = i40e_prep_vlan_tpid_set,
+	.vlan_offload_set             = i40e_prep_vlan_offload_set,
+	.vlan_strip_queue_set         = i40e_prep_vlan_strip_queue_set,
+	.vlan_pvid_set                = i40e_prep_vlan_pvid_set,
+
+	.flow_validate                = NULL,
+	.flow_create                  = NULL,
+	.flow_destroy                 = NULL,
+	.flow_flush                   = NULL,
+};
+
+struct representor_ops *rte_i40e_prep_ops = &i40e_prep_ops;
diff --git a/drivers/net/i40e/i40e_prep_ops.h b/drivers/net/i40e/i40e_prep_ops.h
new file mode 100644
index 0000000..d756407
--- /dev/null
+++ b/drivers/net/i40e/i40e_prep_ops.h
@@ -0,0 +1,41 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _I40E_PREP_OPS_H_
+#define _I40E_PREP_OPS_H_
+
+#include <rte_port_representor.h>
+
+extern struct representor_ops *rte_i40e_prep_ops;
+
+#endif /* _I40E_PREP_OPS_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index f12b7f4..70d8f2e 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -596,6 +596,53 @@ rte_pmd_i40e_set_vf_mac_addr(uint8_t port, uint16_t vf_id,
 	return 0;
 }
 
+static const struct ether_addr null_mac_addr;
+
+int
+rte_pmd_i40e_remove_vf_mac_addr(uint8_t port, uint16_t vf_id,
+	struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_pf_vf *vf;
+	struct i40e_vsi *vsi;
+	struct i40e_pf *pf;
+
+	if (i40e_validate_mac_addr((u8 *)mac_addr) != I40E_SUCCESS)
+		return -EINVAL;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id >= pf->vf_num || !pf->vfs)
+		return -EINVAL;
+
+	vf = &pf->vfs[vf_id];
+	vsi = vf->vsi;
+	if (!vsi) {
+		PMD_DRV_LOG(ERR, "Invalid VSI.");
+		return -EINVAL;
+	}
+
+	if (!is_same_ether_addr(mac_addr, &vf->mac_addr)) {
+		PMD_DRV_LOG(ERR, "Mac address does not match.");
+		return -EINVAL;
+	}
+
+	/* reset the mac with null mac */
+	ether_addr_copy(&null_mac_addr, &vf->mac_addr);
+
+	/* Remove the mac */
+	i40e_vsi_delete_mac(vsi, mac_addr);
+
+	return 0;
+}
+
 /* Set vlan strip on/off for specific VF from host */
 int
 rte_pmd_i40e_set_vf_vlan_stripq(uint8_t port, uint16_t vf_id, uint8_t on)
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 356fa89..812d4dc 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -275,6 +275,24 @@ int rte_pmd_i40e_set_vf_mac_addr(uint8_t port, uint16_t vf_id,
 				 struct ether_addr *mac_addr);
 
 /**
+ * Remove the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf_id
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int
+rte_pmd_i40e_remove_vf_mac_addr(uint8_t port, uint16_t vf_id,
+	struct ether_addr *mac_addr);
+
+/**
  * Enable/Disable vf vlan strip for all queues in a pool
  *
  * @param port
-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [dpdk-dev] [RFC 5/5] Enable port representor PMD and broker for ixgbe PMD driver.
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
                   ` (3 preceding siblings ...)
  2017-09-07  8:35 ` [dpdk-dev] [RFC 4/5] Enable port representor PMD and broker for fortville PMD driver Mohammad Abdul Awal
@ 2017-09-07  8:35 ` Mohammad Abdul Awal
  2017-09-07 10:01 ` [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Alejandro Lucero
  5 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-09-07  8:35 UTC (permalink / raw)
  To: dev; +Cc: Mohammad Abdul Awal, Remy Horton, Declan Doherty

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
Signed-off-by: Remy Horton <remy.horton@intel.com>
Signed-off-by: Declan Doherty <declan.doherty@intel.com>
---
 drivers/net/ixgbe/Makefile         |   2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c   |  33 +++--
 drivers/net/ixgbe/ixgbe_ethdev.h   |  11 ++
 drivers/net/ixgbe/ixgbe_prep_ops.c | 279 +++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_prep_ops.h |  41 ++++++
 5 files changed, 353 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
 create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h

diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 5e57cb3..f216b97 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -1,7 +1,6 @@
 #   BSD LICENSE
 #
 #   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
-#   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
 #   modification, are permitted provided that the following conditions
@@ -125,6 +124,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.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 22171d8..80d5d34 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2,7 +2,6 @@
  *   BSD LICENSE
  *
  *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
- *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
@@ -72,6 +71,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
@@ -173,8 +173,6 @@ static void ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static void ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
-static int ixgbe_dev_link_update(struct rte_eth_dev *dev,
-				int wait_to_complete);
 static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
@@ -205,8 +203,6 @@ static int ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
 static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
-static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
-				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev,
@@ -267,9 +263,6 @@ static void ixgbevf_dev_stop(struct rte_eth_dev *dev);
 static void ixgbevf_dev_close(struct rte_eth_dev *dev);
 static void ixgbevf_intr_disable(struct ixgbe_hw *hw);
 static void ixgbevf_intr_enable(struct ixgbe_hw *hw);
-static void ixgbevf_dev_stats_get(struct rte_eth_dev *dev,
-		struct rte_eth_stats *stats);
-static void ixgbevf_dev_stats_reset(struct rte_eth_dev *dev);
 static int ixgbevf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static void ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev,
@@ -1131,6 +1124,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 	uint32_t ctrl_ext;
 	uint16_t csum;
 	int diag, i;
+	struct rte_port_representor_broker *rep_broker;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1248,6 +1242,17 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 		return -EIO;
 	}
 
+	/* Init port representor broker */
+	if (rte_representor_enabled()) {
+		rep_broker = rte_representor_broker_init(eth_dev,
+			pci_dev->max_vfs, rte_ixgbe_prep_ops);
+		if (rep_broker == NULL) {
+			PMD_INIT_LOG(ERR, "Cannot allocate memory for "
+				"representor broker data\n");
+			return errno;
+		}
+	}
+
 	/* Reset the hw statistics */
 	ixgbe_dev_stats_reset(eth_dev);
 
@@ -1362,6 +1367,10 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 
+	/* Deinit port representor broker */
+	if (rte_representor_enabled())
+		rte_representor_broker_free(eth_dev->data->port_id);
+
 	if (hw->adapter_stopped == 0)
 		ixgbe_dev_close(eth_dev);
 
@@ -3541,7 +3550,7 @@ ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	return IXGBEVF_NB_XSTATS;
 }
 
-static void
+void
 ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
@@ -3558,7 +3567,7 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->obytes = hw_stats->vfgotc;
 }
 
-static void
+void
 ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
 {
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
@@ -3746,7 +3755,7 @@ ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
 {
@@ -4004,7 +4013,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static int
+int
 ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 {
 	return ixgbe_dev_link_update_share(dev, wait_to_complete, 0);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index caa50c8..1534ab7 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -589,6 +589,17 @@ struct ixgbe_adapter {
 /*
  * RX/TX function prototypes
  */
+
+int ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+
+void ixgbevf_dev_stats_get(struct rte_eth_dev *dev,
+	struct rte_eth_stats *stats);
+
+void ixgbevf_dev_stats_reset(struct rte_eth_dev *dev);
+
+void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
+	struct rte_eth_dev_info *dev_info);
+
 void ixgbe_dev_clear_queues(struct rte_eth_dev *dev);
 
 void ixgbe_dev_free_queues(struct rte_eth_dev *dev);
diff --git a/drivers/net/ixgbe/ixgbe_prep_ops.c b/drivers/net/ixgbe/ixgbe_prep_ops.c
new file mode 100644
index 0000000..b2d099a
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_prep_ops.c
@@ -0,0 +1,279 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_pci.h>
+
+#include "base/ixgbe_type.h"
+#include "ixgbe_ethdev.h"
+#include "ixgbe_rxtx.h"
+#include "rte_pmd_ixgbe.h"
+
+#include "ixgbe_prep_ops.h"
+
+static int ixgbe_prep_link_update(
+	__rte_unused struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int wait_to_complete)
+{
+	return ixgbe_dev_link_update(prep->pdev, wait_to_complete);
+}
+
+static void ixgbe_prep_promiscuous_enable(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep)
+{
+}
+
+static void ixgbe_prep_promiscuous_disable(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep)
+{
+}
+
+static void ixgbe_prep_allmulticast_enable(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep)
+{
+}
+
+static void ixgbe_prep_allmulticast_disable(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep)
+{
+}
+
+static void ixgbe_prep_mac_addr_remove(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused uint32_t index)
+{
+}
+
+static int ixgbe_prep_mac_addr_add(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused struct ether_addr *mac_addr, __rte_unused uint32_t index,
+	__rte_unused uint32_t vmdq)
+{
+	return -ENOTSUP;
+}
+
+static void ixgbe_prep_mac_addr_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, struct ether_addr *mac_addr)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_ixgbe_set_vf_mac_addr(pfid, vf_index, mac_addr);
+}
+
+static int ixgbe_prep_stats_get(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused struct rte_eth_stats *stats)
+{
+	return -ENOTSUP;
+}
+
+static void ixgbe_prep_stats_reset(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep)
+{
+}
+
+/* From ixgbe_ethdev.c */
+#define IXGBE_DEFAULT_RX_FREE_THRESH  32
+#define IXGBE_DEFAULT_RX_PTHRESH      8
+#define IXGBE_DEFAULT_RX_HTHRESH      8
+#define IXGBE_DEFAULT_RX_WTHRESH      0
+#define IXGBE_DEFAULT_TX_FREE_THRESH  32
+#define IXGBE_DEFAULT_TX_PTHRESH      32
+#define IXGBE_DEFAULT_TX_HTHRESH      0
+#define IXGBE_DEFAULT_TX_WTHRESH      0
+#define IXGBE_DEFAULT_TX_RSBIT_THRESH 32
+#define IXGBE_VMDQ_NUM_UC_MAC         4096 /* Maximum nb. of UC MAC addr. */
+
+static void ixgbe_prep_dev_infos_get(
+	__rte_unused struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, struct rte_eth_dev_info *dev_info)
+{
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(prep->vdev);
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(
+		prep->pdev->data->dev_private);
+
+	/* Info pulled from HW MAC */
+	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
+	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		dev_info->max_vmdq_pools = ETH_16_POOLS;
+	else
+		dev_info->max_vmdq_pools = ETH_64_POOLS;
+	dev_info->max_mac_addrs = hw->mac.num_rar_entries;
+
+	dev_info->pci_dev = pci_dev;
+
+	/* Hard-coded info */
+	dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL reg */
+	dev_info->max_rx_pktlen = 9728; /* includes CRC, cf MAXFRS reg */
+	dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
+	dev_info->max_vfs = pci_dev->max_vfs;
+
+	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;
+	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_info->default_rxconf = (struct rte_eth_rxconf) {
+		.rx_thresh = {
+			.pthresh = IXGBE_DEFAULT_RX_PTHRESH,
+			.hthresh = IXGBE_DEFAULT_RX_HTHRESH,
+			.wthresh = IXGBE_DEFAULT_RX_WTHRESH,
+		},
+		.rx_free_thresh = IXGBE_DEFAULT_RX_FREE_THRESH,
+		.rx_drop_en = 0,
+	};
+
+	dev_info->default_txconf = (struct rte_eth_txconf) {
+		.tx_thresh = {
+			.pthresh = IXGBE_DEFAULT_TX_PTHRESH,
+			.hthresh = IXGBE_DEFAULT_TX_HTHRESH,
+			.wthresh = IXGBE_DEFAULT_TX_WTHRESH,
+		},
+		.tx_free_thresh = IXGBE_DEFAULT_TX_FREE_THRESH,
+		.tx_rs_thresh = IXGBE_DEFAULT_TX_RSBIT_THRESH,
+		.txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
+				ETH_TXQ_FLAGS_NOOFFLOADS,
+	};
+
+	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = IXGBE_MAX_RING_DESC,
+		.nb_min = IXGBE_MIN_RING_DESC,
+		.nb_align = IXGBE_RXD_ALIGN,
+	};
+
+	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+		.nb_max = IXGBE_MAX_RING_DESC,
+		.nb_min = IXGBE_MIN_RING_DESC,
+		.nb_align = IXGBE_TXD_ALIGN,
+		.nb_seg_max = IXGBE_TX_MAX_SEG,
+		.nb_mtu_seg_max = IXGBE_TX_MAX_SEG,
+	};
+}
+
+static int ixgbe_prep_vlan_filter_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, uint16_t vlan_id, int on)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+	uint64_t vf_mask;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+	vf_mask = 1ULL << vf_index;
+
+	return rte_pmd_ixgbe_set_vf_vlan_filter(pfid, vlan_id, vf_mask, on);
+}
+
+
+static int ixgbe_prep_vlan_tpid_set(struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep,
+	enum rte_vlan_type type, uint16_t tpid)
+{
+	RTE_SET_USED(rb);
+	RTE_SET_USED(prep);
+	RTE_SET_USED(type);
+	RTE_SET_USED(tpid);
+	return -ENOTSUP;
+}
+
+static void ixgbe_prep_vlan_offload_set(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep, __rte_unused int mask)
+{
+}
+
+static void ixgbe_prep_vlan_strip_queue_set(
+	struct rte_port_representor_broker *rb,
+	struct rte_port_representor *prep, int on)
+{
+	uint32_t pfid;
+	uint32_t vf_index;
+
+	pfid = rb->pfid;
+	vf_index = prep->vf_index;
+
+	rte_pmd_ixgbe_set_vf_vlan_stripq(pfid, vf_index, on);
+}
+
+static int ixgbe_prep_vlan_pvid_set(
+	__rte_unused struct rte_port_representor_broker *rb,
+	__rte_unused struct rte_port_representor *prep,
+	__rte_unused uint16_t vlan_id)
+{
+	return -ENOTSUP;
+}
+
+struct representor_ops ixgbe_prep_ops = {
+	.link_update                  = ixgbe_prep_link_update,
+
+	.promiscuous_enable           = ixgbe_prep_promiscuous_enable,
+	.promiscuous_disable          = ixgbe_prep_promiscuous_disable,
+	.allmulticast_enable          = ixgbe_prep_allmulticast_enable,
+	.allmulticast_disable         = ixgbe_prep_allmulticast_disable,
+
+	.mac_addr_remove              = ixgbe_prep_mac_addr_remove,
+	.mac_addr_add                 = ixgbe_prep_mac_addr_add,
+	.mac_addr_set                 = ixgbe_prep_mac_addr_set,
+
+	.stats_get                    = ixgbe_prep_stats_get,
+	.stats_reset                  = ixgbe_prep_stats_reset,
+
+	.dev_infos_get                = ixgbe_prep_dev_infos_get,
+
+	.vlan_filter_set              = ixgbe_prep_vlan_filter_set,
+	.vlan_tpid_set                = ixgbe_prep_vlan_tpid_set,
+	.vlan_offload_set             = ixgbe_prep_vlan_offload_set,
+	.vlan_strip_queue_set         = ixgbe_prep_vlan_strip_queue_set,
+	.vlan_pvid_set                = ixgbe_prep_vlan_pvid_set,
+};
+
+struct representor_ops *rte_ixgbe_prep_ops = &ixgbe_prep_ops;
+
diff --git a/drivers/net/ixgbe/ixgbe_prep_ops.h b/drivers/net/ixgbe/ixgbe_prep_ops.h
new file mode 100644
index 0000000..eb01bdd
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_prep_ops.h
@@ -0,0 +1,41 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _IXGBE_PREP_OPS_H_
+#define _IXGBE_PREP_OPS_H_
+
+#include <rte_port_representor.h>
+
+extern struct representor_ops *rte_ixgbe_prep_ops;
+
+#endif /* _IXGBE_PREP_OPS_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
                   ` (4 preceding siblings ...)
  2017-09-07  8:35 ` [dpdk-dev] [RFC 5/5] Enable port representor PMD and broker for ixgbe " Mohammad Abdul Awal
@ 2017-09-07 10:01 ` Alejandro Lucero
  2017-09-07 13:13   ` Declan Doherty
  5 siblings, 1 reply; 15+ messages in thread
From: Alejandro Lucero @ 2017-09-07 10:01 UTC (permalink / raw)
  To: Mohammad Abdul Awal; +Cc: dev, Remy Horton, Declan Doherty

I understand this is the representor idea suiting Intel cards but it does
not cover other possibilities.

At least, Netronome and Mellanox require a representor not just for
controlling a VF, but also for sending and receiving packets through the
representor PMD.

I sent an abstract for a presentation in next Dublin Users meeting, and
discussing the representor idea was in the agenda.

By the way, I remember there was reticence about adding control plane to
DPDK. What is the current official DPDK position in this regard?



On Thu, Sep 7, 2017 at 9:35 AM, Mohammad Abdul Awal <
mohammad.abdul.awal@intel.com> wrote:

> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> Signed-off-by: Remy Horton <remy.horton@intel.com>
> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
> ---
> This RFC introduces a port representor based model for the control,
> management
> and monitoring of SR-IOV virtual function (VF) devices for control plane
> applications which have bound the devices physical function.
>
> Port Representors are virtual poll mode drivers (PMD) which provide a
> logical
> representation in DPDK for VF ports for control and monitoring. Each port
> representor PMD 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.
>
>
> +-----------------------------+   +---------------+  +---------------+
> |        Control Plane        |   |   Data Plane  |  |   Data Plane  |
> |         Application         |   |   Application |  |   Application |
> +-----------------------------+   +---------------+  +---------------+
> |         eth dev api         |   |  eth dev api  |  |  eth dev api  |
> +-----------------------------+   +---------------+  +---------------+
> +-------+  +-------+  +-------+   +---------------+  +---------------+
> |  PF0  |  | Port  |  | Port  |   |    VF0 PMD    |  |    VF0 PMD    |
> |  PMD  <--+ Rep 0 |  | Rep 1 |   +---------------+  +------+--------+
> |       |  | PMD   |  | PMD   |                             |
> +---+--^+  +-------+  +-+-----+                             |
>     |  |                |  |                                |
>     |  +----------------+  |                                |
>     |                      |                                |
>     |                      |                                |
> +--------------------------------+                          |
> |   |  HW (logical view)   |     |                          |
> | --+------+ +-------+ +---+---+ |                          |
> | |   PF   | |  VF0  | |  VF1  | |                          |
> | |        | |       | |       +----------------------------+
> | +--------+ +-------+ +-------+ |
> | +----------------------------+ |
> | |        VEB                 | |
> | +----------------------------+ |
> | +--------+                     |
> | |  Port  |                     |
> | |   0    |                     |
> | +--------+                     |
> +--------------------------------+
>
> The figure above shows a deployment where the PF is bound to a DPDK control
> plane application which uses representor ports to manage the configuration
> and
> monitoring of it's VF ports. Each virtual function is represented in the
> application by a representor port PMD which enables control of the
> corresponding
> VF through eth dev APIs on the representor PMD such as:
>
> - void rte_eth_promiscuous_enable(uint8_t port_id);
> - void rte_eth_promiscuous_disable(uint8_t port_id);
> - void rte_eth_allmulticast_enable(uint8_t port_id);
> - void rte_eth_allmulticast_disable(uint8_t port_id);
> - int rte_eth_dev_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
>         uint32_t pool);
> - int rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask);
>
> as well as monitoring through API's like
>
> - void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *link);
> - int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats);
>
> The port representor infrastructure is enabled through a single common,
> device
> independent, virtual PMD whos context is initialized and enabled through a
> broker instance running within the context of the physical function device
> driver.
>
> +-------------------------+       +-------------------------+
> |        rte_ethdev       |       |       rte_ethdev        |
> +-------------------------+       +-------------------------+
> |  Physical Function PMD  |       |  Port Reperesentor PMD  |
> |         +-------------+ |       | +---------+ +---------+ |
> |         | Representor | |       | | dev_data| | dev_ops | |
> |         |    Broker   | |       | +----+----+ +----+----+ |
> |         | +---------+ | |       +------|-----------|------+
> |         | | VF Port | | |              |           |
> |         | | Context +------------------+           |
> |         | +---------+ | |                          |
> |         | +---------+ | |                          |
> |         | | Handler +------------------------------+
> |         | |   Ops   | | |
> |         | +---------+ | |
> |         +-------------+ |
> +-------------------------+
>
> Creation of representor ports can be achieved either through the --vdev EAL
> option or through the rte_vdev_init() API. Each port representor requires
> the
> BDF of it's parent PF and the Virtual Function ID of the port which the
> representor will support. During initialization of the representor PMD, it
> calls
> the broker API to register itself with the PF PMD and to get it's context
> configured which includes the setting up of it's context and ops function
> handlers.
>
>
> As the port representor model is based around the paradigm of using
> standard
> port based APIs, it will allow future expansion of functionality without
> the
> need to add new APIs. For example it should be possible to support
> configuration
> of egress QoS parameters using existing TM APIs by extending the port
> representor PMD/broker infrastructure.
>
> Mohammad Abdul Awal (5):
>   Implemented port representor broker infrastructure, created BDF to
>     port     function.
>   added --enable-representor command line argument in EAL to load
>     representor broker infrastructure.
>   Implement port representor PMD
>   Enable port representor PMD and broker for fortville PMD driver
>   Enable port representor PMD and broker for ixgbe PMD driver.
>
>  config/common_base                                 |   5 +
>  drivers/net/Makefile                               |   2 +
>  drivers/net/i40e/Makefile                          |   1 +
>  drivers/net/i40e/i40e_ethdev.c                     |  17 +
>  drivers/net/i40e/i40e_prep_ops.c                   | 402 +++++++++
>  drivers/net/i40e/i40e_prep_ops.h                   |  41 +
>  drivers/net/i40e/rte_pmd_i40e.c                    |  47 +
>  drivers/net/i40e/rte_pmd_i40e.h                    |  18 +
>  drivers/net/ixgbe/Makefile                         |   2 +-
>  drivers/net/ixgbe/ixgbe_ethdev.c                   |  33 +-
>  drivers/net/ixgbe/ixgbe_ethdev.h                   |  11 +
>  drivers/net/ixgbe/ixgbe_prep_ops.c                 | 279 ++++++
>  drivers/net/ixgbe/ixgbe_prep_ops.h                 |  41 +
>  drivers/net/representor/Makefile                   |  51 ++
>  drivers/net/representor/rte_eth_representor.c      | 973
> +++++++++++++++++++++
>  .../representor/rte_pmd_representor_version.map    |   4 +
>  lib/librte_eal/bsdapp/eal/eal.c                    |   6 +
>  lib/librte_eal/common/eal_common_options.c         |   1 +
>  lib/librte_eal/common/eal_internal_cfg.h           |   2 +
>  lib/librte_eal/common/eal_options.h                |   2 +
>  lib/librte_eal/common/include/rte_eal.h            |   8 +
>  lib/librte_eal/linuxapp/eal/eal.c                  |   9 +
>  lib/librte_ether/Makefile                          |   2 +
>  lib/librte_ether/rte_ethdev.c                      |  93 ++
>  lib/librte_ether/rte_ethdev.h                      |  26 +
>  lib/librte_ether/rte_ethdev_vdev.h                 |  37 +-
>  lib/librte_ether/rte_ether_version.map             |   9 +
>  lib/librte_ether/rte_port_representor.c            | 160 ++++
>  lib/librte_ether/rte_port_representor.h            | 289 ++++++
>  mk/rte.app.mk                                      |   1 +
>  30 files changed, 2556 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/net/i40e/i40e_prep_ops.c
>  create mode 100644 drivers/net/i40e/i40e_prep_ops.h
>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h
>  create mode 100644 drivers/net/representor/Makefile
>  create mode 100644 drivers/net/representor/rte_eth_representor.c
>  create mode 100644 drivers/net/representor/rte_
> pmd_representor_version.map
>  create mode 100644 lib/librte_ether/rte_port_representor.c
>  create mode 100644 lib/librte_ether/rte_port_representor.h
>
> --
> 2.7.4
>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-09-07 10:01 ` [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Alejandro Lucero
@ 2017-09-07 13:13   ` Declan Doherty
  2017-09-08 13:59     ` Alejandro Lucero
  0 siblings, 1 reply; 15+ messages in thread
From: Declan Doherty @ 2017-09-07 13:13 UTC (permalink / raw)
  To: Alejandro Lucero, Mohammad Abdul Awal; +Cc: dev, Remy Horton

On 07/09/2017 11:01 AM, Alejandro Lucero wrote:
> I understand this is the representor idea suiting Intel cards but it does
> not cover other possibilities.
>
> At least, Netronome and Mellanox require a representor not just for
> controlling a VF, but also for sending and receiving packets through the
> representor PMD.
>

Hey Alejandro,

What we've proposed here doesn't preclude the support of a data path on 
the representor pmd as the functionality which the PMD supports is 
dependent on how the parent device running the representor broker 
configures each representor instance. As you note in the case of our 
current generation of IO devices supporting a data path doesn't make 
sense, but I think this framework could support that functionality if 
required.

> I sent an abstract for a presentation in next Dublin Users meeting, and
> discussing the representor idea was in the agenda.
>

I've also submitted an presentation which I got notification was 
accepted this morning which is based on the RFC, so maybe we should 
collaborate on a presentation if there is a large overlap?

> By the way, I remember there was reticence about adding control plane to
> DPDK. What is the current official DPDK position in this regard?
>

I also remember there was concerns about adding control plane APIs to 
DPDK, hence the RFC, but I think the advantage of the representor port 
approach is that there are no new public API being introduced, with only 
back-end support in the PMDs which wish to support this functionality.

>
>
> On Thu, Sep 7, 2017 at 9:35 AM, Mohammad Abdul Awal <
> mohammad.abdul.awal@intel.com> wrote:
>
>> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
>> Signed-off-by: Remy Horton <remy.horton@intel.com>
>> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
>> ---
>> This RFC introduces a port representor based model for the control,
>> management
>> and monitoring of SR-IOV virtual function (VF) devices for control plane
>> applications which have bound the devices physical function.
>>
>> Port Representors are virtual poll mode drivers (PMD) which provide a
>> logical
>> representation in DPDK for VF ports for control and monitoring. Each port
>> representor PMD 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.
>>
>>
>> +-----------------------------+   +---------------+  +---------------+
>> |        Control Plane        |   |   Data Plane  |  |   Data Plane  |
>> |         Application         |   |   Application |  |   Application |
>> +-----------------------------+   +---------------+  +---------------+
>> |         eth dev api         |   |  eth dev api  |  |  eth dev api  |
>> +-----------------------------+   +---------------+  +---------------+
>> +-------+  +-------+  +-------+   +---------------+  +---------------+
>> |  PF0  |  | Port  |  | Port  |   |    VF0 PMD    |  |    VF0 PMD    |
>> |  PMD  <--+ Rep 0 |  | Rep 1 |   +---------------+  +------+--------+
>> |       |  | PMD   |  | PMD   |                             |
>> +---+--^+  +-------+  +-+-----+                             |
>>     |  |                |  |                                |
>>     |  +----------------+  |                                |
>>     |                      |                                |
>>     |                      |                                |
>> +--------------------------------+                          |
>> |   |  HW (logical view)   |     |                          |
>> | --+------+ +-------+ +---+---+ |                          |
>> | |   PF   | |  VF0  | |  VF1  | |                          |
>> | |        | |       | |       +----------------------------+
>> | +--------+ +-------+ +-------+ |
>> | +----------------------------+ |
>> | |        VEB                 | |
>> | +----------------------------+ |
>> | +--------+                     |
>> | |  Port  |                     |
>> | |   0    |                     |
>> | +--------+                     |
>> +--------------------------------+
>>
>> The figure above shows a deployment where the PF is bound to a DPDK control
>> plane application which uses representor ports to manage the configuration
>> and
>> monitoring of it's VF ports. Each virtual function is represented in the
>> application by a representor port PMD which enables control of the
>> corresponding
>> VF through eth dev APIs on the representor PMD such as:
>>
>> - void rte_eth_promiscuous_enable(uint8_t port_id);
>> - void rte_eth_promiscuous_disable(uint8_t port_id);
>> - void rte_eth_allmulticast_enable(uint8_t port_id);
>> - void rte_eth_allmulticast_disable(uint8_t port_id);
>> - int rte_eth_dev_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
>>         uint32_t pool);
>> - int rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask);
>>
>> as well as monitoring through API's like
>>
>> - void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *link);
>> - int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats);
>>
>> The port representor infrastructure is enabled through a single common,
>> device
>> independent, virtual PMD whos context is initialized and enabled through a
>> broker instance running within the context of the physical function device
>> driver.
>>
>> +-------------------------+       +-------------------------+
>> |        rte_ethdev       |       |       rte_ethdev        |
>> +-------------------------+       +-------------------------+
>> |  Physical Function PMD  |       |  Port Reperesentor PMD  |
>> |         +-------------+ |       | +---------+ +---------+ |
>> |         | Representor | |       | | dev_data| | dev_ops | |
>> |         |    Broker   | |       | +----+----+ +----+----+ |
>> |         | +---------+ | |       +------|-----------|------+
>> |         | | VF Port | | |              |           |
>> |         | | Context +------------------+           |
>> |         | +---------+ | |                          |
>> |         | +---------+ | |                          |
>> |         | | Handler +------------------------------+
>> |         | |   Ops   | | |
>> |         | +---------+ | |
>> |         +-------------+ |
>> +-------------------------+
>>
>> Creation of representor ports can be achieved either through the --vdev EAL
>> option or through the rte_vdev_init() API. Each port representor requires
>> the
>> BDF of it's parent PF and the Virtual Function ID of the port which the
>> representor will support. During initialization of the representor PMD, it
>> calls
>> the broker API to register itself with the PF PMD and to get it's context
>> configured which includes the setting up of it's context and ops function
>> handlers.
>>
>>
>> As the port representor model is based around the paradigm of using
>> standard
>> port based APIs, it will allow future expansion of functionality without
>> the
>> need to add new APIs. For example it should be possible to support
>> configuration
>> of egress QoS parameters using existing TM APIs by extending the port
>> representor PMD/broker infrastructure.
>>
>> Mohammad Abdul Awal (5):
>>   Implemented port representor broker infrastructure, created BDF to
>>     port     function.
>>   added --enable-representor command line argument in EAL to load
>>     representor broker infrastructure.
>>   Implement port representor PMD
>>   Enable port representor PMD and broker for fortville PMD driver
>>   Enable port representor PMD and broker for ixgbe PMD driver.
>>
>>  config/common_base                                 |   5 +
>>  drivers/net/Makefile                               |   2 +
>>  drivers/net/i40e/Makefile                          |   1 +
>>  drivers/net/i40e/i40e_ethdev.c                     |  17 +
>>  drivers/net/i40e/i40e_prep_ops.c                   | 402 +++++++++
>>  drivers/net/i40e/i40e_prep_ops.h                   |  41 +
>>  drivers/net/i40e/rte_pmd_i40e.c                    |  47 +
>>  drivers/net/i40e/rte_pmd_i40e.h                    |  18 +
>>  drivers/net/ixgbe/Makefile                         |   2 +-
>>  drivers/net/ixgbe/ixgbe_ethdev.c                   |  33 +-
>>  drivers/net/ixgbe/ixgbe_ethdev.h                   |  11 +
>>  drivers/net/ixgbe/ixgbe_prep_ops.c                 | 279 ++++++
>>  drivers/net/ixgbe/ixgbe_prep_ops.h                 |  41 +
>>  drivers/net/representor/Makefile                   |  51 ++
>>  drivers/net/representor/rte_eth_representor.c      | 973
>> +++++++++++++++++++++
>>  .../representor/rte_pmd_representor_version.map    |   4 +
>>  lib/librte_eal/bsdapp/eal/eal.c                    |   6 +
>>  lib/librte_eal/common/eal_common_options.c         |   1 +
>>  lib/librte_eal/common/eal_internal_cfg.h           |   2 +
>>  lib/librte_eal/common/eal_options.h                |   2 +
>>  lib/librte_eal/common/include/rte_eal.h            |   8 +
>>  lib/librte_eal/linuxapp/eal/eal.c                  |   9 +
>>  lib/librte_ether/Makefile                          |   2 +
>>  lib/librte_ether/rte_ethdev.c                      |  93 ++
>>  lib/librte_ether/rte_ethdev.h                      |  26 +
>>  lib/librte_ether/rte_ethdev_vdev.h                 |  37 +-
>>  lib/librte_ether/rte_ether_version.map             |   9 +
>>  lib/librte_ether/rte_port_representor.c            | 160 ++++
>>  lib/librte_ether/rte_port_representor.h            | 289 ++++++
>>  mk/rte.app.mk                                      |   1 +
>>  30 files changed, 2556 insertions(+), 16 deletions(-)
>>  create mode 100644 drivers/net/i40e/i40e_prep_ops.c
>>  create mode 100644 drivers/net/i40e/i40e_prep_ops.h
>>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
>>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h
>>  create mode 100644 drivers/net/representor/Makefile
>>  create mode 100644 drivers/net/representor/rte_eth_representor.c
>>  create mode 100644 drivers/net/representor/rte_
>> pmd_representor_version.map
>>  create mode 100644 lib/librte_ether/rte_port_representor.c
>>  create mode 100644 lib/librte_ether/rte_port_representor.h
>>
>> --
>> 2.7.4
>>
>>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-09-07 13:13   ` Declan Doherty
@ 2017-09-08 13:59     ` Alejandro Lucero
  2017-12-21 14:51       ` Alex Rosenbaum
  0 siblings, 1 reply; 15+ messages in thread
From: Alejandro Lucero @ 2017-09-08 13:59 UTC (permalink / raw)
  To: Declan Doherty; +Cc: Mohammad Abdul Awal, dev, Remy Horton

On Thu, Sep 7, 2017 at 2:13 PM, Declan Doherty <declan.doherty@intel.com>
wrote:

> On 07/09/2017 11:01 AM, Alejandro Lucero wrote:
>
>> I understand this is the representor idea suiting Intel cards but it does
>> not cover other possibilities.
>>
>> At least, Netronome and Mellanox require a representor not just for
>> controlling a VF, but also for sending and receiving packets through the
>> representor PMD.
>>
>>
> Hey Alejandro,
>
> What we've proposed here doesn't preclude the support of a data path on
> the representor pmd as the functionality which the PMD supports is
> dependent on how the parent device running the representor broker
> configures each representor instance. As you note in the case of our
> current generation of IO devices supporting a data path doesn't make sense,
> but I think this framework could support that functionality if required.
>
>
Hi Declan,

Tell me if I'm wrong, but this looks to me like kernel netdev ndo_set_vf_*
functions, maybe with the idea of having more possibilities than those
currently available with the kernel. The representor idea I refer to is
completely different, and it is related to using SRIOV with OVS offload. It
has other possibilities but this is the current main reason. Some
references:


https://www.slideshare.net/Netronome/using-agilio-smartnics-for-openstack-networking-acceleration


https://netdevconf.org/1.2/slides/oct6/04_gerlitz_efraim_introduction_to_switchdev_sriov_offloads.pdf

I sent an abstract for a presentation in next Dublin Users meeting, and
>> discussing the representor idea was in the agenda.
>>
>>
> I've also submitted an presentation which I got notification was accepted
> this morning which is based on the RFC, so maybe we should collaborate on a
> presentation if there is a large overlap?


Unfortunately, I did not get my abstract approved. Maybe you could add some
slide about this other view for the shake of discussion.


>
>
> By the way, I remember there was reticence about adding control plane to
>> DPDK. What is the current official DPDK position in this regard?
>>
>>
> I also remember there was concerns about adding control plane APIs to
> DPDK, hence the RFC, but I think the advantage of the representor port
> approach is that there are no new public API being introduced, with only
> back-end support in the PMDs which wish to support this functionality.
>
>
I'd like to know what is the opinion of the DPDK community regarding the
control path.


>
>
>>
>> On Thu, Sep 7, 2017 at 9:35 AM, Mohammad Abdul Awal <
>> mohammad.abdul.awal@intel.com> wrote:
>>
>> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
>>> Signed-off-by: Remy Horton <remy.horton@intel.com>
>>> Signed-off-by: Declan Doherty <declan.doherty@intel.com>
>>> ---
>>> This RFC introduces a port representor based model for the control,
>>> management
>>> and monitoring of SR-IOV virtual function (VF) devices for control plane
>>> applications which have bound the devices physical function.
>>>
>>> Port Representors are virtual poll mode drivers (PMD) which provide a
>>> logical
>>> representation in DPDK for VF ports for control and monitoring. Each port
>>> representor PMD 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.
>>>
>>>
>>> +-----------------------------+   +---------------+  +---------------+
>>> |        Control Plane        |   |   Data Plane  |  |   Data Plane  |
>>> |         Application         |   |   Application |  |   Application |
>>> +-----------------------------+   +---------------+  +---------------+
>>> |         eth dev api         |   |  eth dev api  |  |  eth dev api  |
>>> +-----------------------------+   +---------------+  +---------------+
>>> +-------+  +-------+  +-------+   +---------------+  +---------------+
>>> |  PF0  |  | Port  |  | Port  |   |    VF0 PMD    |  |    VF0 PMD    |
>>> |  PMD  <--+ Rep 0 |  | Rep 1 |   +---------------+  +------+--------+
>>> |       |  | PMD   |  | PMD   |                             |
>>> +---+--^+  +-------+  +-+-----+                             |
>>>     |  |                |  |                                |
>>>     |  +----------------+  |                                |
>>>     |                      |                                |
>>>     |                      |                                |
>>> +--------------------------------+                          |
>>> |   |  HW (logical view)   |     |                          |
>>> | --+------+ +-------+ +---+---+ |                          |
>>> | |   PF   | |  VF0  | |  VF1  | |                          |
>>> | |        | |       | |       +----------------------------+
>>> | +--------+ +-------+ +-------+ |
>>> | +----------------------------+ |
>>> | |        VEB                 | |
>>> | +----------------------------+ |
>>> | +--------+                     |
>>> | |  Port  |                     |
>>> | |   0    |                     |
>>> | +--------+                     |
>>> +--------------------------------+
>>>
>>> The figure above shows a deployment where the PF is bound to a DPDK
>>> control
>>> plane application which uses representor ports to manage the
>>> configuration
>>> and
>>> monitoring of it's VF ports. Each virtual function is represented in the
>>> application by a representor port PMD which enables control of the
>>> corresponding
>>> VF through eth dev APIs on the representor PMD such as:
>>>
>>> - void rte_eth_promiscuous_enable(uint8_t port_id);
>>> - void rte_eth_promiscuous_disable(uint8_t port_id);
>>> - void rte_eth_allmulticast_enable(uint8_t port_id);
>>> - void rte_eth_allmulticast_disable(uint8_t port_id);
>>> - int rte_eth_dev_mac_addr_add(uint8_t port, struct ether_addr
>>> *mac_addr,
>>>         uint32_t pool);
>>> - int rte_eth_dev_set_vlan_offload(uint8_t port_id, int offload_mask);
>>>
>>> as well as monitoring through API's like
>>>
>>> - void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *link);
>>> - int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats);
>>>
>>> The port representor infrastructure is enabled through a single common,
>>> device
>>> independent, virtual PMD whos context is initialized and enabled through
>>> a
>>> broker instance running within the context of the physical function
>>> device
>>> driver.
>>>
>>> +-------------------------+       +-------------------------+
>>> |        rte_ethdev       |       |       rte_ethdev        |
>>> +-------------------------+       +-------------------------+
>>> |  Physical Function PMD  |       |  Port Reperesentor PMD  |
>>> |         +-------------+ |       | +---------+ +---------+ |
>>> |         | Representor | |       | | dev_data| | dev_ops | |
>>> |         |    Broker   | |       | +----+----+ +----+----+ |
>>> |         | +---------+ | |       +------|-----------|------+
>>> |         | | VF Port | | |              |           |
>>> |         | | Context +------------------+           |
>>> |         | +---------+ | |                          |
>>> |         | +---------+ | |                          |
>>> |         | | Handler +------------------------------+
>>> |         | |   Ops   | | |
>>> |         | +---------+ | |
>>> |         +-------------+ |
>>> +-------------------------+
>>>
>>> Creation of representor ports can be achieved either through the --vdev
>>> EAL
>>> option or through the rte_vdev_init() API. Each port representor requires
>>> the
>>> BDF of it's parent PF and the Virtual Function ID of the port which the
>>> representor will support. During initialization of the representor PMD,
>>> it
>>> calls
>>> the broker API to register itself with the PF PMD and to get it's context
>>> configured which includes the setting up of it's context and ops function
>>> handlers.
>>>
>>>
>>> As the port representor model is based around the paradigm of using
>>> standard
>>> port based APIs, it will allow future expansion of functionality without
>>> the
>>> need to add new APIs. For example it should be possible to support
>>> configuration
>>> of egress QoS parameters using existing TM APIs by extending the port
>>> representor PMD/broker infrastructure.
>>>
>>> Mohammad Abdul Awal (5):
>>>   Implemented port representor broker infrastructure, created BDF to
>>>     port     function.
>>>   added --enable-representor command line argument in EAL to load
>>>     representor broker infrastructure.
>>>   Implement port representor PMD
>>>   Enable port representor PMD and broker for fortville PMD driver
>>>   Enable port representor PMD and broker for ixgbe PMD driver.
>>>
>>>  config/common_base                                 |   5 +
>>>  drivers/net/Makefile                               |   2 +
>>>  drivers/net/i40e/Makefile                          |   1 +
>>>  drivers/net/i40e/i40e_ethdev.c                     |  17 +
>>>  drivers/net/i40e/i40e_prep_ops.c                   | 402 +++++++++
>>>  drivers/net/i40e/i40e_prep_ops.h                   |  41 +
>>>  drivers/net/i40e/rte_pmd_i40e.c                    |  47 +
>>>  drivers/net/i40e/rte_pmd_i40e.h                    |  18 +
>>>  drivers/net/ixgbe/Makefile                         |   2 +-
>>>  drivers/net/ixgbe/ixgbe_ethdev.c                   |  33 +-
>>>  drivers/net/ixgbe/ixgbe_ethdev.h                   |  11 +
>>>  drivers/net/ixgbe/ixgbe_prep_ops.c                 | 279 ++++++
>>>  drivers/net/ixgbe/ixgbe_prep_ops.h                 |  41 +
>>>  drivers/net/representor/Makefile                   |  51 ++
>>>  drivers/net/representor/rte_eth_representor.c      | 973
>>> +++++++++++++++++++++
>>>  .../representor/rte_pmd_representor_version.map    |   4 +
>>>  lib/librte_eal/bsdapp/eal/eal.c                    |   6 +
>>>  lib/librte_eal/common/eal_common_options.c         |   1 +
>>>  lib/librte_eal/common/eal_internal_cfg.h           |   2 +
>>>  lib/librte_eal/common/eal_options.h                |   2 +
>>>  lib/librte_eal/common/include/rte_eal.h            |   8 +
>>>  lib/librte_eal/linuxapp/eal/eal.c                  |   9 +
>>>  lib/librte_ether/Makefile                          |   2 +
>>>  lib/librte_ether/rte_ethdev.c                      |  93 ++
>>>  lib/librte_ether/rte_ethdev.h                      |  26 +
>>>  lib/librte_ether/rte_ethdev_vdev.h                 |  37 +-
>>>  lib/librte_ether/rte_ether_version.map             |   9 +
>>>  lib/librte_ether/rte_port_representor.c            | 160 ++++
>>>  lib/librte_ether/rte_port_representor.h            | 289 ++++++
>>>  mk/rte.app.mk                                      |   1 +
>>>  30 files changed, 2556 insertions(+), 16 deletions(-)
>>>  create mode 100644 drivers/net/i40e/i40e_prep_ops.c
>>>  create mode 100644 drivers/net/i40e/i40e_prep_ops.h
>>>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.c
>>>  create mode 100644 drivers/net/ixgbe/ixgbe_prep_ops.h
>>>  create mode 100644 drivers/net/representor/Makefile
>>>  create mode 100644 drivers/net/representor/rte_eth_representor.c
>>>  create mode 100644 drivers/net/representor/rte_
>>> pmd_representor_version.map
>>>  create mode 100644 lib/librte_ether/rte_port_representor.c
>>>  create mode 100644 lib/librte_ether/rte_port_representor.h
>>>
>>> --
>>> 2.7.4
>>>
>>>
>>>
>>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-09-08 13:59     ` Alejandro Lucero
@ 2017-12-21 14:51       ` Alex Rosenbaum
  2017-12-22 14:31         ` Mohammad Abdul Awal
  0 siblings, 1 reply; 15+ messages in thread
From: Alex Rosenbaum @ 2017-12-21 14:51 UTC (permalink / raw)
  To: Declan Doherty, Mohammad Abdul Awal
  Cc: dev, Remy Horton, Rony Efraim, Alejandro Lucero

Declan, Mohammad,

The submission [1] of steering action between switch ports clearly
requires a switch model in DPDK.
The Port Representor based on a virtual PMD broker on NIC ops
(rte_dev_ops) does not provide the required functionality. Using NIC
terminology and not Switch API's will lead to a dead-end. Moreover, it
does not fit the Kernel design. We need to be careful from this ending
up as two different deployment models for users, which is very bad.
There was a long discussion about this in netdev ML [2], including the
VEPA mode support.

As described in the links Alejandro referenced earlier, each of the
switch ports should be a real PMD, and switch operations should be
applied on these PMD ports.
This includes the steering redirection of traffic between switch ports
[1], port ACL's to block/allow traffic, VST/VGT modes and anti
spoofing, link trust mode [3] for promiscuous configuration, mirroring
of switch port traffic, and Tx and Rx of switch port traffic to/from
VF's port.

More over, building this as real PMD ports of a switch device removes
the need to add a new broker framework all together.
Each vendor just needs to map additional PMD ports during the probing
stage. By adding a switchdev_id we can define these are ports
associated to the same switching device, and can allow new port and
inter-port actions.

[1] http://dpdk.org/dev/patchwork/patch/32550/
[2] https://www.spinics.net/lists/netdev/msg467375.html
[2] https://www.systutorials.com/docs/linux/man/8-ip-link/

Alex

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-12-21 14:51       ` Alex Rosenbaum
@ 2017-12-22 14:31         ` Mohammad Abdul Awal
  2017-12-22 22:33           ` Alex Rosenbaum
  0 siblings, 1 reply; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-12-22 14:31 UTC (permalink / raw)
  To: Alex Rosenbaum, Declan Doherty
  Cc: dev, Remy Horton, Rony Efraim, Alejandro Lucero

Hi ALex,


On 21/12/2017 14:51, Alex Rosenbaum wrote:
> Declan, Mohammad,
>
> The submission [1] of steering action between switch ports clearly
> requires a switch model in DPDK.
> The Port Representor based on a virtual PMD broker on NIC ops
> (rte_dev_ops) does not provide the required functionality. Using NIC
> terminology and not Switch API's will lead to a dead-end. Moreover, it
> does not fit the Kernel design. We need to be careful from this ending
> up as two different deployment models for users, which is very bad.
> There was a long discussion about this in netdev ML [2], including the
> VEPA mode support.
>
> As described in the links Alejandro referenced earlier, each of the
> switch ports should be a real PMD, and switch operations should be
> applied on these PMD ports.
> This includes the steering redirection of traffic between switch ports
> [1], port ACL's to block/allow traffic, VST/VGT modes and anti
> spoofing, link trust mode [3] for promiscuous configuration, mirroring
> of switch port traffic, and Tx and Rx of switch port traffic to/from
> VF's port.
I agree that we need a switch_domain parameter. At the moment we do not 
have APIs implemented for all the switch operations you have mentioned 
above. So, we are planning separate RFC with switch _domain and related 
APIs.

>
> More over, building this as real PMD ports of a switch device removes
> the need to add a new broker framework all together.
> Each vendor just needs to map additional PMD ports during the probing
> stage.
That is very much possible as well. If we agree to probe all the ports 
during the initialization phase, we can have all the representors ready 
without any interaction from application and broker. On the other hand, 
we may require a broker structure to enable hotplug support.

> By adding a switchdev_id we can define these are ports
> associated to the same switching device, and can allow new port and
> inter-port actions.
>
> [1] http://dpdk.org/dev/patchwork/patch/32550/
> [2] https://www.spinics.net/lists/netdev/msg467375.html
> [2] https://www.systutorials.com/docs/linux/man/8-ip-link/
>
> Alex

Regards,
Awal.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-12-22 14:31         ` Mohammad Abdul Awal
@ 2017-12-22 22:33           ` Alex Rosenbaum
  2017-12-27  9:40             ` Mohammad Abdul Awal
  0 siblings, 1 reply; 15+ messages in thread
From: Alex Rosenbaum @ 2017-12-22 22:33 UTC (permalink / raw)
  To: Mohammad Abdul Awal
  Cc: Declan Doherty, dev, Remy Horton, Rony Efraim, Alejandro Lucero

On Fri, Dec 22, 2017 at 4:31 PM, Mohammad Abdul Awal
<mohammad.abdul.awal@intel.com> wrote:
> On 21/12/2017 14:51, Alex Rosenbaum wrote:
>> As described in the links Alejandro referenced earlier, each of the
>> switch ports should be a real PMD, and switch operations should be
>> applied on these PMD ports.
>> This includes the steering redirection of traffic between switch ports
>> [1], port ACL's to block/allow traffic, VST/VGT modes and anti
>> spoofing, link trust mode [3] for promiscuous configuration, mirroring
>> of switch port traffic, and Tx and Rx of switch port traffic to/from
>> VF's port.
>
> I agree that we need a switch_domain parameter. At the moment we do not have
> APIs implemented for all the switch operations you have mentioned above. So,
> we are planning separate RFC with switch _domain and related APIs.

Sure, we can extend these switch ops in a separate step.


>> More over, building this as real PMD ports of a switch device removes
>> the need to add a new broker framework all together.
>> Each vendor just needs to map additional PMD ports during the probing
>> stage.
>
> That is very much possible as well. If we agree to probe all the ports
> during the initialization phase, we can have all the representors ready
> without any interaction from application and broker. On the other hand, we
> may require a broker structure to enable hotplug support.

hotplug should be supported for any PMD ports, and any BDF type.
I don't understand why do you need the broker framework in order to
support hotplug?

Alex

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-12-22 22:33           ` Alex Rosenbaum
@ 2017-12-27  9:40             ` Mohammad Abdul Awal
  2017-12-27 15:50               ` Alex Rosenbaum
  0 siblings, 1 reply; 15+ messages in thread
From: Mohammad Abdul Awal @ 2017-12-27  9:40 UTC (permalink / raw)
  To: Alex Rosenbaum
  Cc: Declan Doherty, dev, Remy Horton, Rony Efraim, Alejandro Lucero



On 22/12/2017 22:33, Alex Rosenbaum wrote:
> On Fri, Dec 22, 2017 at 4:31 PM, Mohammad Abdul Awal
> <mohammad.abdul.awal@intel.com> wrote:
>> On 21/12/2017 14:51, Alex Rosenbaum wrote:
>>> As described in the links Alejandro referenced earlier, each of the
>>> switch ports should be a real PMD, and switch operations should be
>>> applied on these PMD ports.
>>> This includes the steering redirection of traffic between switch ports
>>> [1], port ACL's to block/allow traffic, VST/VGT modes and anti
>>> spoofing, link trust mode [3] for promiscuous configuration, mirroring
>>> of switch port traffic, and Tx and Rx of switch port traffic to/from
>>> VF's port.
>> I agree that we need a switch_domain parameter. At the moment we do not have
>> APIs implemented for all the switch operations you have mentioned above. So,
>> we are planning separate RFC with switch _domain and related APIs.
> Sure, we can extend these switch ops in a separate step.
>
>
>>> More over, building this as real PMD ports of a switch device removes
>>> the need to add a new broker framework all together.
>>> Each vendor just needs to map additional PMD ports during the probing
>>> stage.
>> That is very much possible as well. If we agree to probe all the ports
>> during the initialization phase, we can have all the representors ready
>> without any interaction from application and broker. On the other hand, we
>> may require a broker structure to enable hotplug support.
> hotplug should be supported for any PMD ports, and any BDF type.
> I don't understand why do you need the broker framework in order to
> support hotplug?
By hotplug I did not mean HW hotplug, rather I meant the software 
hotplug of port representor so that an application can add/delete 
representor at run time.

Regards,
Awal.

>
> Alex

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-12-27  9:40             ` Mohammad Abdul Awal
@ 2017-12-27 15:50               ` Alex Rosenbaum
  2018-01-02 15:19                 ` Mohammad Abdul Awal
  0 siblings, 1 reply; 15+ messages in thread
From: Alex Rosenbaum @ 2017-12-27 15:50 UTC (permalink / raw)
  To: Mohammad Abdul Awal
  Cc: Declan Doherty, dev, Remy Horton, Rony Efraim, Alejandro Lucero

On Wed, Dec 27, 2017 at 11:40 AM, Mohammad Abdul Awal
<mohammad.abdul.awal@intel.com> wrote:
> On 22/12/2017 22:33, Alex Rosenbaum wrote:
>> On Fri, Dec 22, 2017 at 4:31 PM, Mohammad Abdul Awal
>>> On 21/12/2017 14:51, Alex Rosenbaum wrote:
> By hotplug I did not mean HW hotplug, rather I meant the software hotplug of
> port representor so that an application can add/delete representor at run
> time.

What is the expect results if application adds/deletes a representor
at run time?

I would expect the VF hotplug to be depended on the PF configuration.
So that new/removed VF's would trigger a representor state or existance.

Alex

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices
  2017-12-27 15:50               ` Alex Rosenbaum
@ 2018-01-02 15:19                 ` Mohammad Abdul Awal
  0 siblings, 0 replies; 15+ messages in thread
From: Mohammad Abdul Awal @ 2018-01-02 15:19 UTC (permalink / raw)
  To: Alex Rosenbaum
  Cc: Declan Doherty, dev, Remy Horton, Rony Efraim, Alejandro Lucero



On 27/12/2017 15:50, Alex Rosenbaum wrote:
> On Wed, Dec 27, 2017 at 11:40 AM, Mohammad Abdul Awal
> <mohammad.abdul.awal@intel.com> wrote:
>> On 22/12/2017 22:33, Alex Rosenbaum wrote:
>>> On Fri, Dec 22, 2017 at 4:31 PM, Mohammad Abdul Awal
>>>> On 21/12/2017 14:51, Alex Rosenbaum wrote:
>> By hotplug I did not mean HW hotplug, rather I meant the software hotplug of
>> port representor so that an application can add/delete representor at run
>> time.
> What is the expect results if application adds/deletes a representor
> at run time?
 From my understanding, for OVS, it would make much sense to enumerate 
the representors during the startup time and only 'state' 
active/inactive would enough to imply the state of a VF.

On the other hand, for a system with varieties of NICs/FPGAs/SmartNics 
having capacities of hundreds (if not thousands) of max VFs and 
different capabilities, we may not want to allocate them if not being 
using, and we may not be able to control this way if no broker.

This is definitely a matter of design discussion for now where ultimate 
outcome is same, i.e. having a representor to control a VF.

>
> I would expect the VF hotplug to be depended on the PF configuration.
> So that new/removed VF's would trigger a representor state or existance.
I agree and as I have just said above that it is different ways of doing 
same thing with limited/flexible ability.

> Alex
Regards,
Awal

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-01-02 15:19 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-07  8:35 [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Mohammad Abdul Awal
2017-09-07  8:35 ` [dpdk-dev] [RFC 1/5] Implemented port representor broker infrastructure, created BDF to port function Mohammad Abdul Awal
2017-09-07  8:35 ` [dpdk-dev] [RFC 2/5] added --enable-representor command line argument in EAL to load representor broker infrastructure Mohammad Abdul Awal
2017-09-07  8:35 ` [dpdk-dev] [RFC 3/5] Implement port representor PMD Mohammad Abdul Awal
2017-09-07  8:35 ` [dpdk-dev] [RFC 4/5] Enable port representor PMD and broker for fortville PMD driver Mohammad Abdul Awal
2017-09-07  8:35 ` [dpdk-dev] [RFC 5/5] Enable port representor PMD and broker for ixgbe " Mohammad Abdul Awal
2017-09-07 10:01 ` [dpdk-dev] [RFC 0/5] Port Representor for control and monitoring of VF devices Alejandro Lucero
2017-09-07 13:13   ` Declan Doherty
2017-09-08 13:59     ` Alejandro Lucero
2017-12-21 14:51       ` Alex Rosenbaum
2017-12-22 14:31         ` Mohammad Abdul Awal
2017-12-22 22:33           ` Alex Rosenbaum
2017-12-27  9:40             ` Mohammad Abdul Awal
2017-12-27 15:50               ` Alex Rosenbaum
2018-01-02 15:19                 ` Mohammad Abdul Awal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).