All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/5] add API's for VF management
@ 2016-08-18 13:48 Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 1/5] librte_ether: add internal callback functions Bernard Iremonger
                   ` (5 more replies)
  0 siblings, 6 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger

This RFC patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This RFC proposes to add the following API extensions to DPDK:
  mailbox communication callback support
  VF configuration

Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Niantic NIC.

Two new callback functions have been added.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the callback functions.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.

Bernard Iremonger (5):
  librte_ether: add internal callback functions
  net/ixgbe: add callback to user app on VF to PF mbox msg
  librte_ether: add API's for VF management
  net/ixgbe: add functions for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 700 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  68 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 179 +++++++
 drivers/net/ixgbe/ixgbe_pf.c                |  39 +-
 lib/librte_ether/rte_ethdev.c               | 176 +++++++
 lib/librte_ether/rte_ethdev.h               | 284 +++++++++++
 lib/librte_ether/rte_ether_version.map      |  16 +
 7 files changed, 1455 insertions(+), 7 deletions(-)

-- 
2.9.0

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

* [RFC PATCH 1/5] librte_ether: add internal callback functions
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
@ 2016-08-18 13:48 ` Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

add _rte_eth_dev_callback_process_vf function.
add _rte_eth_dev_callback_process_generic function

Adding a callback to the user application on VF to PF mailbox message,
allows passing information to the application controlling the PF
when a VF mailbox event message is received, such as VF reset.

Signed-off-by: azelezniak <alexz@att.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
 lib/librte_ether/rte_ethdev.h          | 61 ++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  7 ++++
 3 files changed, 85 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f62a9ec..1388ea3 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2690,6 +2690,20 @@ void
 _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	enum rte_eth_event_type event)
 {
+	return _rte_eth_dev_callback_process_generic(dev, event, NULL);
+}
+
+void
+_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
+	enum rte_eth_event_type event, void *param)
+{
+	return _rte_eth_dev_callback_process_generic(dev, event, param);
+}
+
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+	enum rte_eth_event_type event, void *param)
+{
 	struct rte_eth_dev_callback *cb_lst;
 	struct rte_eth_dev_callback dev_cb;
 
@@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 			continue;
 		dev_cb = *cb_lst;
 		cb_lst->active = 1;
+		if (param != NULL)
+			dev_cb.cb_arg = (void *) param;
+
 		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
 						dev_cb.cb_arg);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b0fe033..4fb0b9c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
 				/**< queue state event (enabled/disabled) */
 	RTE_ETH_EVENT_INTR_RESET,
 			/**< reset interrupt event, sent to VF on PF reset */
+	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing callback */
 	RTE_ETH_EVENT_MAX       /**< max value of this enum */
 };
 
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_eth_mb_event_rsp {
+	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+struct rte_eth_mb_event_param {
+	uint16_t vfid;
+	uint16_t msg_type;
+	uint16_t retval;
+	void *userdata;
+};
+
 typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
 		enum rte_eth_event_type event, void *cb_arg);
 /**< user application callback to be registered for interrupts */
@@ -3114,6 +3132,49 @@ void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 				enum rte_eth_event_type event);
 
 /**
+ * @internal Executes all the user application registered callbacks for
+ * the specific device where parameter have to be passed to user application.
+ * It is for DPDK internal user only. User application should not call it
+ * directly.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param event
+ *  Eth device interrupt event type.
+ *
+ * @param param
+ *  parameters to pass back to user application.
+ *
+ * @return
+ *  void
+ */
+
+void
+_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
+				enum rte_eth_event_type event, void *param);
+
+/**
+ * @internal Executes all the user application registered callbacks. Used by:
+ * _rte_eth_dev_callback_process and _rte_eth_dev_callback_process_vf
+ * It is for DPDK internal user only. User application should not call it
+ * directly.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param event
+ *  Eth device interrupt event type.
+ *
+ * @param param
+ *  parameters to pass back to user application.
+ *
+ * @return
+ *  void
+ */
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+				enum rte_eth_event_type event, void *param);
+
+/**
  * When there is no rx packet coming in Rx Queue for a long time, we can
  * sleep lcore related to RX Queue for power saving, and enable rx interrupt
  * to be triggered when rx packect arrives.
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..cb7ef15 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,10 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	_rte_eth_dev_callback_process_generic;
+	_rte_eth_dev_callback_process_vf;
+} DPDK_16.07;
-- 
2.9.0

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

* [RFC PATCH 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 1/5] librte_ether: add internal callback functions Bernard Iremonger
@ 2016-08-18 13:48 ` Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 3/5] librte_ether: add API's for VF management Bernard Iremonger
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

call _rte_eth_dev_callback_process_vf from ixgbe_rcv_msg_from_vf function.

The callback asks the user application if it is allowed to perform
the function.
If the cb_param.retval is RTE_ETH_MB_EVENT_PROCEED then continue,
if 0, do nothing and send ACK to VF
if > 1, do nothing and send NAK to VF.

Signed-off-by: azelezniak <alexz@att.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_pf.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..bb14106 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -660,6 +660,7 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+	struct rte_eth_mb_event_param cb_param;
 
 	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
 	if (retval) {
@@ -674,27 +675,54 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 	/* flush the ack before we write any messages back */
 	IXGBE_WRITE_FLUSH(hw);
 
+	/**
+	 * initialise structure to send to user application
+	 * will return response from user in retval field
+	 */
+	cb_param.retval = RTE_ETH_MB_EVENT_PROCEED;
+	cb_param.vfid = vf;
+	cb_param.msg_type = msgbuf[0] & 0xFFFF;
+	cb_param.userdata = (void *)msgbuf;
+
 	/* perform VF reset */
 	if (msgbuf[0] == IXGBE_VF_RESET) {
 		int ret = ixgbe_vf_reset(dev, vf, msgbuf);
 
 		vfinfo[vf].clear_to_send = true;
+
+		/* notify application about VF reset */
+		_rte_eth_dev_callback_process_vf(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
 		return ret;
 	}
 
+	/**
+	 * ask user application if we allowed to perform those functions
+	 * if we get cb_param.retval == RTE_ETH_MB_EVENT_PROCEED then business
+	 * as usual,
+	 * if 0, do nothing and send ACK to VF
+	 * if cb_param.retval > 1, do nothing and send NAK to VF
+	 */
+	_rte_eth_dev_callback_process_vf(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+
+	retval = cb_param.retval;
+
 	/* check & process VF to PF mailbox message */
 	switch ((msgbuf[0] & 0xFFFF)) {
 	case IXGBE_VF_SET_MAC_ADDR:
-		retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_MULTICAST:
-		retval = ixgbe_vf_set_multicast(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_multicast(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_LPE:
-		retval = ixgbe_set_vf_lpe(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_set_vf_lpe(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_VLAN:
-		retval = ixgbe_vf_set_vlan(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_vlan(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_API_NEGOTIATE:
 		retval = ixgbe_negotiate_vf_api(dev, vf, msgbuf);
@@ -704,7 +732,8 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 		msg_size = IXGBE_VF_GET_QUEUE_MSG_SIZE;
 		break;
 	case IXGBE_VF_UPDATE_XCAST_MODE:
-		retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf);
 		break;
 	default:
 		PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]);
-- 
2.9.0

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

* [RFC PATCH 3/5] librte_ether: add API's for VF management
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 1/5] librte_ether: add internal callback functions Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
@ 2016-08-18 13:48 ` Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 4/5] net/ixgbe: add functions " Bernard Iremonger
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

Add new API functions to configure and manage VF's on a NIC.

add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.
increment LIBABIVER to 5.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 159 +++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 223 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |   9 ++
 3 files changed, 391 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1388ea3..2a3d2ae 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2306,6 +2306,22 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
 }
 
 int
+rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (!is_valid_assigned_ether_addr(addr))
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
+
+	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
+}
+
+int
 rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
 				uint16_t rx_mode, uint8_t on)
 {
@@ -2490,6 +2506,149 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF VLAN anti spoof:VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF MAC anti spoof:VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_mac_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_vf_ping(uint8_t port_id, int32_t vf)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF ping: VF %d > 64\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vf_ping, -ENOTSUP);
+	return (*dev->dev_ops->vf_ping)(dev, vf);
+}
+
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF vlan strip set VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_strip, -ENOTSUP);
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	(*dev->dev_ops->set_vf_vlan_strip)(dev, on, queues_per_pool);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF vlan insert set VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_insert, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_vlan_insert)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_tx_loopback(uint8_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_tx_loopback, -ENOTSUP);
+
+	(*dev->dev_ops->set_tx_loopback)(dev, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port_id, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_all_queues_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_all_queues_drop_en)(dev, state);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port_id, uint16_t vf, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_split_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_split_drop_en)(dev, vf, state);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 4fb0b9c..ed3d61b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1230,6 +1230,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
+typedef int (*eth_set_vf_mac_addr_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  struct ether_addr *mac_addr);
+/**< @internal Set VF address into Receive Address Address Register */
+
 typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr,
 				  uint8_t on);
@@ -1261,6 +1266,43 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
 				  uint8_t vlan_on);
 /**< @internal Set VF VLAN pool filter */
 
+typedef void (*eth_set_vf_vlan_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF VLAN anti spoof */
+
+typedef void (*eth_set_vf_mac_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF MAC anti spoof */
+
+typedef int (*eth_vf_ping_t)(struct rte_eth_dev *dev,
+				int32_t vf);
+/**< @internal ping one or all vf's */
+
+typedef void (*eth_set_vf_vlan_strip_t)(struct rte_eth_dev *dev,
+				  int on,
+				  uint16_t queues_per_pool);
+/**< @internal Set VF vlan strip */
+
+typedef void (*eth_set_vf_vlan_insert_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int vlan);
+/**< @internal Set VF vlan insert */
+
+typedef void (*eth_set_tx_loopback_t)(struct rte_eth_dev *dev,
+				  int on);
+/**< @internal Set tx loopback */
+
+typedef void (*eth_set_all_queues_drop_en_t)(struct rte_eth_dev *dev,
+				  int state);
+/**< @internal Set all queues drop */
+
+typedef void (*eth_set_vf_split_drop_en_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int state);
+/**< @internal Set the enable drop bit in the VF split rx control register */
+
 typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
 				uint16_t queue_idx,
 				uint16_t tx_rate);
@@ -1465,6 +1507,7 @@ struct eth_dev_ops {
 	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address */
 	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address */
 	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address */
+	eth_set_vf_mac_addr_t      set_vf_mac_addr;  /**< Set a VF MAC address */
 	eth_uc_hash_table_set_t    uc_hash_table_set;  /**< Set Unicast Table Array */
 	eth_uc_all_hash_table_set_t uc_all_hash_table_set;  /**< Set Unicast hash bitmap */
 	eth_mirror_rule_set_t	   mirror_rule_set;  /**< Add a traffic mirror rule.*/
@@ -1473,6 +1516,14 @@ struct eth_dev_ops {
 	eth_set_vf_rx_t            set_vf_rx;  /**< enable/disable a VF receive */
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
+	eth_set_vf_vlan_anti_spoof_t  set_vf_vlan_anti_spoof; /**< Set VF VLAN anti spoof */
+	eth_set_vf_mac_anti_spoof_t   set_vf_mac_anti_spoof;  /**< Set VF MAC anti spoof */
+	eth_vf_ping_t             vf_ping;  /**< Ping one or all VF's */
+	eth_set_vf_vlan_strip_t   set_vf_vlan_strip; /** <Set VF VLAN strip */
+	eth_set_vf_vlan_insert_t  set_vf_vlan_insert; /** <Set VF VLAN insert */
+	eth_set_tx_loopback_t  set_tx_loopback; /** <Set tx loopback */
+	eth_set_all_queues_drop_en_t  set_all_queues_drop_en; /** <Set queue drop enable bit */
+	eth_set_vf_split_drop_en_t  set_vf_split_drop_en; /** <Set split drop enable bit.*/
 	/** Add UDP tunnel port. */
 	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
 	/** Del UDP tunnel port. */
@@ -3389,7 +3440,25 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
  */
 int rte_eth_dev_default_mac_addr_set(uint8_t port, struct ether_addr *mac_addr);
 
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
 
+ * @return
+ *   - (0) if successful, or *mac_addr* didn't exist.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if MAC address is invalid.
+ */
+
+int rte_eth_dev_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr);
 /**
  * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
  *
@@ -3556,6 +3625,160 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Ping all or specified VF
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   specify VF to ping or all if -1.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_vf_ping(uint8_t port, int32_t vf);
+
+/**
+ * Enable/Disable vf vlan strip
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip.
+ *    0 - Disable VF's vlan strip
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_tx_loopback(uint8_t port, int on);
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param state
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port, int state);
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param state
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port, uint16_t vf, int state);
+/**
  * Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index cb7ef15..c9649ee 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -145,4 +145,13 @@ DPDK_16.11 {
 
 	_rte_eth_dev_callback_process_generic;
 	_rte_eth_dev_callback_process_vf;
+	rte_eth_dev_set_all_queues_drop_en;
+	rte_eth_dev_set_tx_loopback;
+	rte_eth_dev_set_vf_mac_addr;
+	rte_eth_dev_set_vf_mac_anti_spoof;
+	rte_eth_dev_set_vf_split_drop_en;
+	rte_eth_dev_set_vf_vlan_anti_spoof;
+	rte_eth_dev_set_vf_vlan_insert;
+	rte_eth_dev_set_vf_vlan_strip;
+	rte_eth_dev_vf_ping;
 } DPDK_16.07;
-- 
2.9.0

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

* [RFC PATCH 4/5] net/ixgbe: add functions for VF management
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
                   ` (2 preceding siblings ...)
  2016-08-18 13:48 ` [RFC PATCH 3/5] librte_ether: add API's for VF management Bernard Iremonger
@ 2016-08-18 13:48 ` Bernard Iremonger
  2016-08-18 13:48 ` [RFC PATCH 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
  5 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

Add new functions to configure and manage VF's on a Niantic NIC.

add ixgbe_vf_ping function.
add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_strip function
add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index d478a15..3b0ee82 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,19 @@ static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static int ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf);
+static void ixgbe_set_vf_vlan_strip(struct rte_eth_dev *dev,
+		int on, uint16_t queues_per_pool);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -505,6 +520,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -513,6 +529,14 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.vf_ping              = ixgbe_vf_ping,
+	.set_vf_vlan_strip    = ixgbe_set_vf_vlan_strip,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4012,6 +4036,22 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4315,6 +4355,16 @@ ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 }
 
 static void
+ixgbe_set_vf_vlan_strip(struct rte_eth_dev *dev, int on,
+		uint16_t queues_per_pool)
+{
+	uint16_t q;
+
+	for (q = 0; q < queues_per_pool; q++)
+		ixgbevf_vlan_strip_queue_set(dev, q, on);
+}
+
+static void
 ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
 	struct ixgbe_hw *hw =
@@ -4604,6 +4654,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static int
+ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf)
+{
+	int ret = 0;
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_vf_info *vfinfo =
+		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+
+	u32 ping;
+	int i;
+
+	for (i = 0; i < dev->pci_dev->max_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+
+		/* ping every VF or only one specified */
+		if (vf < 0 || vf == i)
+			ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+
+	return ret;
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
-- 
2.9.0

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

* [RFC PATCH 5/5] app/test_pmd: add tests for new API's
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
                   ` (3 preceding siblings ...)
  2016-08-18 13:48 ` [RFC PATCH 4/5] net/ixgbe: add functions " Bernard Iremonger
@ 2016-08-18 13:48 ` Bernard Iremonger
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
  5 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-18 13:48 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger

add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 700 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  68 ++-
 2 files changed, 766 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f90befc..12e89c3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10585,6 +10585,697 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+	ret = rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan anti spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan anti spoof",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_anti_spoof(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan mac spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf mac anti spoof",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on,
+		NULL,
+	},
+};
+
+/* vf ping configuration */
+
+/* Common result structure for vf ping */
+struct cmd_vf_ping_result {
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t ping;
+	uint8_t port_id;
+	int32_t vf_id;
+};
+
+/* Common CLI fields for ping vfs */
+cmdline_parse_token_string_t cmd_vf_ping_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_ping_ping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 ping, "ping");
+cmdline_parse_token_num_t cmd_vf_ping_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_ping_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf_id, INT32);
+
+static void
+cmd_vf_ping_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_ping_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_vf_ping(res->port_id, res->vf_id);
+	if (ret < 0)
+		printf("ping vfs programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_vf_ping = {
+	.f = cmd_vf_ping_parsed,
+	.data = NULL,
+	.help_str = "ping all or specified vf",
+	.tokens = {
+		(void *)&cmd_vf_ping_vf,
+		(void *)&cmd_vf_ping_ping,
+		(void *)&cmd_vf_ping_port_id,
+		(void *)&cmd_vf_ping_vf_id,
+		NULL,
+	},
+};
+
+/* vf vlan strip configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_strip_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t strip;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_strip_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_strip =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 strip, "strip");
+cmdline_parse_token_num_t cmd_vf_vlan_strip_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_strip_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_strip_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_strip_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_strip_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_strip(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan strip programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_strip = {
+	.f = cmd_set_vf_vlan_strip_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan strip",
+	.tokens = {
+		(void *)&cmd_vf_vlan_strip_set,
+		(void *)&cmd_vf_vlan_strip_vf,
+		(void *)&cmd_vf_vlan_strip_vlan,
+		(void *)&cmd_vf_vlan_strip_strip,
+		(void *)&cmd_vf_vlan_strip_port_id,
+		(void *)&cmd_vf_vlan_strip_vf_id,
+		(void *)&cmd_vf_vlan_strip_on,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_insert(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan insert programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan insert",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on, UINT8);
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_tx_loopback(res->port_id, res->on);
+	if (ret < 0)
+		printf("tx loopback programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan insert",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on, UINT8);
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_all_queues_drop_en(res->port_id, res->on);
+	if (ret < 0)
+		printf("all queues drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "enable/disable all queues drop enable bits",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_split_drop_en(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf split drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf split drop enable",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	if (ret < 0)
+		printf("set vf mac addr programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac address",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11430,15 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_vf_ping,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_strip,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..c26d901 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -473,6 +473,41 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
+ping VF
+~~~~~~~
+
+Ping VF or all VF's from PF::
+
+   testpmd> vf ping (port_id) (vf_id | -1)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set strip (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for a VF from the PF::
+
+   testpmd> set vf vlan strip (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert  (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof  (port_id) (vf_id) (on|off)
+
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +784,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* [RFC PATCH v2 0/5] add API's for VF management
  2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
                   ` (4 preceding siblings ...)
  2016-08-18 13:48 ` [RFC PATCH 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
@ 2016-08-26  9:10 ` Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 1/5] librte_ether: add internal callback functions Bernard Iremonger
                     ` (14 more replies)
  5 siblings, 15 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger

This RFC patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This RFC proposes to add the following API extensions to DPDK:
  mailbox communication callback support
  VF configuration

Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Niantic NIC.

Two new callback functions have been added.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the callback functions.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (5):
  librte_ether: add internal callback functions
  net/ixgbe: add callback to user app on VF to PF mbox msg
  librte_ether: add API's for VF management
  net/ixgbe: add functions for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 700 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  68 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 179 +++++++
 drivers/net/ixgbe/ixgbe_pf.c                |  39 +-
 lib/librte_ether/rte_ethdev.c               | 176 +++++++
 lib/librte_ether/rte_ethdev.h               | 284 +++++++++++
 lib/librte_ether/rte_ether_version.map      |  16 +
 7 files changed, 1455 insertions(+), 7 deletions(-)

-- 
2.9.0

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

* [RFC PATCH v2 1/5] librte_ether: add internal callback functions
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
@ 2016-08-26  9:10   ` Bernard Iremonger
  2016-09-09 14:10     ` Jerin Jacob
  2016-08-26  9:10   ` [RFC PATCH v2 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
                     ` (13 subsequent siblings)
  14 siblings, 1 reply; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

add _rte_eth_dev_callback_process_vf function.
add _rte_eth_dev_callback_process_generic function

Adding a callback to the user application on VF to PF mailbox message,
allows passing information to the application controlling the PF
when a VF mailbox event message is received, such as VF reset.

Signed-off-by: azelezniak <alexz@att.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
 lib/librte_ether/rte_ethdev.h          | 61 ++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  7 ++++
 3 files changed, 85 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f62a9ec..1388ea3 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2690,6 +2690,20 @@ void
 _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	enum rte_eth_event_type event)
 {
+	return _rte_eth_dev_callback_process_generic(dev, event, NULL);
+}
+
+void
+_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
+	enum rte_eth_event_type event, void *param)
+{
+	return _rte_eth_dev_callback_process_generic(dev, event, param);
+}
+
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+	enum rte_eth_event_type event, void *param)
+{
 	struct rte_eth_dev_callback *cb_lst;
 	struct rte_eth_dev_callback dev_cb;
 
@@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 			continue;
 		dev_cb = *cb_lst;
 		cb_lst->active = 1;
+		if (param != NULL)
+			dev_cb.cb_arg = (void *) param;
+
 		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
 		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
 						dev_cb.cb_arg);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b0fe033..4fb0b9c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
 				/**< queue state event (enabled/disabled) */
 	RTE_ETH_EVENT_INTR_RESET,
 			/**< reset interrupt event, sent to VF on PF reset */
+	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing callback */
 	RTE_ETH_EVENT_MAX       /**< max value of this enum */
 };
 
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_eth_mb_event_rsp {
+	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+struct rte_eth_mb_event_param {
+	uint16_t vfid;
+	uint16_t msg_type;
+	uint16_t retval;
+	void *userdata;
+};
+
 typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
 		enum rte_eth_event_type event, void *cb_arg);
 /**< user application callback to be registered for interrupts */
@@ -3114,6 +3132,49 @@ void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 				enum rte_eth_event_type event);
 
 /**
+ * @internal Executes all the user application registered callbacks for
+ * the specific device where parameter have to be passed to user application.
+ * It is for DPDK internal user only. User application should not call it
+ * directly.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param event
+ *  Eth device interrupt event type.
+ *
+ * @param param
+ *  parameters to pass back to user application.
+ *
+ * @return
+ *  void
+ */
+
+void
+_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
+				enum rte_eth_event_type event, void *param);
+
+/**
+ * @internal Executes all the user application registered callbacks. Used by:
+ * _rte_eth_dev_callback_process and _rte_eth_dev_callback_process_vf
+ * It is for DPDK internal user only. User application should not call it
+ * directly.
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param event
+ *  Eth device interrupt event type.
+ *
+ * @param param
+ *  parameters to pass back to user application.
+ *
+ * @return
+ *  void
+ */
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+				enum rte_eth_event_type event, void *param);
+
+/**
  * When there is no rx packet coming in Rx Queue for a long time, we can
  * sleep lcore related to RX Queue for power saving, and enable rx interrupt
  * to be triggered when rx packect arrives.
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..cb7ef15 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,10 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	_rte_eth_dev_callback_process_generic;
+	_rte_eth_dev_callback_process_vf;
+} DPDK_16.07;
-- 
2.9.0

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

* [RFC PATCH v2 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 1/5] librte_ether: add internal callback functions Bernard Iremonger
@ 2016-08-26  9:10   ` Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 3/5] librte_ether: add API's for VF management Bernard Iremonger
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

call _rte_eth_dev_callback_process_vf from ixgbe_rcv_msg_from_vf function.

The callback asks the user application if it is allowed to perform
the function.
If the cb_param.retval is RTE_ETH_MB_EVENT_PROCEED then continue,
if 0, do nothing and send ACK to VF
if > 1, do nothing and send NAK to VF.

Signed-off-by: azelezniak <alexz@att.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_pf.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..bb14106 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -660,6 +660,7 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+	struct rte_eth_mb_event_param cb_param;
 
 	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
 	if (retval) {
@@ -674,27 +675,54 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 	/* flush the ack before we write any messages back */
 	IXGBE_WRITE_FLUSH(hw);
 
+	/**
+	 * initialise structure to send to user application
+	 * will return response from user in retval field
+	 */
+	cb_param.retval = RTE_ETH_MB_EVENT_PROCEED;
+	cb_param.vfid = vf;
+	cb_param.msg_type = msgbuf[0] & 0xFFFF;
+	cb_param.userdata = (void *)msgbuf;
+
 	/* perform VF reset */
 	if (msgbuf[0] == IXGBE_VF_RESET) {
 		int ret = ixgbe_vf_reset(dev, vf, msgbuf);
 
 		vfinfo[vf].clear_to_send = true;
+
+		/* notify application about VF reset */
+		_rte_eth_dev_callback_process_vf(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
 		return ret;
 	}
 
+	/**
+	 * ask user application if we allowed to perform those functions
+	 * if we get cb_param.retval == RTE_ETH_MB_EVENT_PROCEED then business
+	 * as usual,
+	 * if 0, do nothing and send ACK to VF
+	 * if cb_param.retval > 1, do nothing and send NAK to VF
+	 */
+	_rte_eth_dev_callback_process_vf(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+
+	retval = cb_param.retval;
+
 	/* check & process VF to PF mailbox message */
 	switch ((msgbuf[0] & 0xFFFF)) {
 	case IXGBE_VF_SET_MAC_ADDR:
-		retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_MULTICAST:
-		retval = ixgbe_vf_set_multicast(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_multicast(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_LPE:
-		retval = ixgbe_set_vf_lpe(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_set_vf_lpe(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_SET_VLAN:
-		retval = ixgbe_vf_set_vlan(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_vf_set_vlan(dev, vf, msgbuf);
 		break;
 	case IXGBE_VF_API_NEGOTIATE:
 		retval = ixgbe_negotiate_vf_api(dev, vf, msgbuf);
@@ -704,7 +732,8 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 		msg_size = IXGBE_VF_GET_QUEUE_MSG_SIZE;
 		break;
 	case IXGBE_VF_UPDATE_XCAST_MODE:
-		retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf);
+		if (retval == RTE_ETH_MB_EVENT_PROCEED)
+			retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf);
 		break;
 	default:
 		PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]);
-- 
2.9.0

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

* [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 1/5] librte_ether: add internal callback functions Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
@ 2016-08-26  9:10   ` Bernard Iremonger
  2016-09-09 14:22     ` Jerin Jacob
  2016-08-26  9:10   ` [RFC PATCH v2 4/5] net/ixgbe: add functions " Bernard Iremonger
                     ` (11 subsequent siblings)
  14 siblings, 1 reply; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

Add new API functions to configure and manage VF's on a NIC.

add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_eth_dev_set_vf_vlan_strip function.
add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.
increment LIBABIVER to 5.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 159 +++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 223 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |   9 ++
 3 files changed, 391 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1388ea3..2a3d2ae 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2306,6 +2306,22 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
 }
 
 int
+rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (!is_valid_assigned_ether_addr(addr))
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
+
+	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
+}
+
+int
 rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
 				uint16_t rx_mode, uint8_t on)
 {
@@ -2490,6 +2506,149 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF VLAN anti spoof:VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF MAC anti spoof:VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_mac_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_vf_ping(uint8_t port_id, int32_t vf)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF ping: VF %d > 64\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vf_ping, -ENOTSUP);
+	return (*dev->dev_ops->vf_ping)(dev, vf);
+}
+
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF vlan strip set VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_strip, -ENOTSUP);
+
+	rte_eth_dev_info_get(port_id, &dev_info);
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	(*dev->dev_ops->set_vf_vlan_strip)(dev, on, queues_per_pool);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	if (vf > 63) {
+		RTE_PMD_DEBUG_TRACE("VF vlan insert set VF %d > 63\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_insert, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_vlan_insert)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_tx_loopback(uint8_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_tx_loopback, -ENOTSUP);
+
+	(*dev->dev_ops->set_tx_loopback)(dev, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port_id, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_all_queues_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_all_queues_drop_en)(dev, state);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port_id, uint16_t vf, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_split_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_split_drop_en)(dev, vf, state);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 4fb0b9c..ed3d61b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1230,6 +1230,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
+typedef int (*eth_set_vf_mac_addr_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  struct ether_addr *mac_addr);
+/**< @internal Set VF address into Receive Address Address Register */
+
 typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr,
 				  uint8_t on);
@@ -1261,6 +1266,43 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
 				  uint8_t vlan_on);
 /**< @internal Set VF VLAN pool filter */
 
+typedef void (*eth_set_vf_vlan_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF VLAN anti spoof */
+
+typedef void (*eth_set_vf_mac_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF MAC anti spoof */
+
+typedef int (*eth_vf_ping_t)(struct rte_eth_dev *dev,
+				int32_t vf);
+/**< @internal ping one or all vf's */
+
+typedef void (*eth_set_vf_vlan_strip_t)(struct rte_eth_dev *dev,
+				  int on,
+				  uint16_t queues_per_pool);
+/**< @internal Set VF vlan strip */
+
+typedef void (*eth_set_vf_vlan_insert_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int vlan);
+/**< @internal Set VF vlan insert */
+
+typedef void (*eth_set_tx_loopback_t)(struct rte_eth_dev *dev,
+				  int on);
+/**< @internal Set tx loopback */
+
+typedef void (*eth_set_all_queues_drop_en_t)(struct rte_eth_dev *dev,
+				  int state);
+/**< @internal Set all queues drop */
+
+typedef void (*eth_set_vf_split_drop_en_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int state);
+/**< @internal Set the enable drop bit in the VF split rx control register */
+
 typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
 				uint16_t queue_idx,
 				uint16_t tx_rate);
@@ -1465,6 +1507,7 @@ struct eth_dev_ops {
 	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address */
 	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address */
 	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address */
+	eth_set_vf_mac_addr_t      set_vf_mac_addr;  /**< Set a VF MAC address */
 	eth_uc_hash_table_set_t    uc_hash_table_set;  /**< Set Unicast Table Array */
 	eth_uc_all_hash_table_set_t uc_all_hash_table_set;  /**< Set Unicast hash bitmap */
 	eth_mirror_rule_set_t	   mirror_rule_set;  /**< Add a traffic mirror rule.*/
@@ -1473,6 +1516,14 @@ struct eth_dev_ops {
 	eth_set_vf_rx_t            set_vf_rx;  /**< enable/disable a VF receive */
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
+	eth_set_vf_vlan_anti_spoof_t  set_vf_vlan_anti_spoof; /**< Set VF VLAN anti spoof */
+	eth_set_vf_mac_anti_spoof_t   set_vf_mac_anti_spoof;  /**< Set VF MAC anti spoof */
+	eth_vf_ping_t             vf_ping;  /**< Ping one or all VF's */
+	eth_set_vf_vlan_strip_t   set_vf_vlan_strip; /** <Set VF VLAN strip */
+	eth_set_vf_vlan_insert_t  set_vf_vlan_insert; /** <Set VF VLAN insert */
+	eth_set_tx_loopback_t  set_tx_loopback; /** <Set tx loopback */
+	eth_set_all_queues_drop_en_t  set_all_queues_drop_en; /** <Set queue drop enable bit */
+	eth_set_vf_split_drop_en_t  set_vf_split_drop_en; /** <Set split drop enable bit.*/
 	/** Add UDP tunnel port. */
 	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
 	/** Del UDP tunnel port. */
@@ -3389,7 +3440,25 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
  */
 int rte_eth_dev_default_mac_addr_set(uint8_t port, struct ether_addr *mac_addr);
 
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
 
+ * @return
+ *   - (0) if successful, or *mac_addr* didn't exist.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if MAC address is invalid.
+ */
+
+int rte_eth_dev_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr);
 /**
  * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
  *
@@ -3556,6 +3625,160 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Ping all or specified VF
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   specify VF to ping or all if -1.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_vf_ping(uint8_t port, int32_t vf);
+
+/**
+ * Enable/Disable vf vlan strip
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip.
+ *    0 - Disable VF's vlan strip
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_tx_loopback(uint8_t port, int on);
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param state
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port, int state);
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param state
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port, uint16_t vf, int state);
+/**
  * Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index cb7ef15..c9649ee 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -145,4 +145,13 @@ DPDK_16.11 {
 
 	_rte_eth_dev_callback_process_generic;
 	_rte_eth_dev_callback_process_vf;
+	rte_eth_dev_set_all_queues_drop_en;
+	rte_eth_dev_set_tx_loopback;
+	rte_eth_dev_set_vf_mac_addr;
+	rte_eth_dev_set_vf_mac_anti_spoof;
+	rte_eth_dev_set_vf_split_drop_en;
+	rte_eth_dev_set_vf_vlan_anti_spoof;
+	rte_eth_dev_set_vf_vlan_insert;
+	rte_eth_dev_set_vf_vlan_strip;
+	rte_eth_dev_vf_ping;
 } DPDK_16.07;
-- 
2.9.0

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

* [RFC PATCH v2 4/5] net/ixgbe: add functions for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (2 preceding siblings ...)
  2016-08-26  9:10   ` [RFC PATCH v2 3/5] librte_ether: add API's for VF management Bernard Iremonger
@ 2016-08-26  9:10   ` Bernard Iremonger
  2016-08-26  9:10   ` [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger, azelezniak

Add new functions to configure and manage VF's on a Niantic NIC.

add ixgbe_vf_ping function.
add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_strip function
add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 179 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fb618ef..e8220ba 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,19 @@ static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static int ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf);
+static void ixgbe_set_vf_vlan_strip(struct rte_eth_dev *dev,
+		int on, uint16_t queues_per_pool);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -562,6 +577,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -570,6 +586,14 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.vf_ping              = ixgbe_vf_ping,
+	.set_vf_vlan_strip    = ixgbe_set_vf_vlan_strip,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4069,6 +4093,22 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4372,6 +4412,16 @@ ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 }
 
 static void
+ixgbe_set_vf_vlan_strip(struct rte_eth_dev *dev, int on,
+		uint16_t queues_per_pool)
+{
+	uint16_t q;
+
+	for (q = 0; q < queues_per_pool; q++)
+		ixgbevf_vlan_strip_queue_set(dev, q, on);
+}
+
+static void
 ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
 	struct ixgbe_hw *hw =
@@ -4661,6 +4711,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static int
+ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf)
+{
+	int ret = 0;
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_vf_info *vfinfo =
+		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+
+	u32 ping;
+	int i;
+
+	for (i = 0; i < dev->pci_dev->max_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+
+		/* ping every VF or only one specified */
+		if (vf < 0 || vf == i)
+			ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+
+	return ret;
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
-- 
2.9.0

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

* [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (3 preceding siblings ...)
  2016-08-26  9:10   ` [RFC PATCH v2 4/5] net/ixgbe: add functions " Bernard Iremonger
@ 2016-08-26  9:10   ` Bernard Iremonger
  2016-09-11 12:35     ` Yuanhan Liu
  2016-09-07  9:18   ` [RFC PATCH v2 0/5] add API's for VF management Pattan, Reshma
                     ` (9 subsequent siblings)
  14 siblings, 1 reply; 94+ messages in thread
From: Bernard Iremonger @ 2016-08-26  9:10 UTC (permalink / raw)
  To: rahul.r.shah, wenzhuo.lu, dev; +Cc: Bernard Iremonger

add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 700 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  68 ++-
 2 files changed, 766 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f90befc..fb29c0a 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10585,6 +10585,697 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+	ret = rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan anti spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan anti spoof",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_anti_spoof(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan mac spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf mac anti spoof",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on,
+		NULL,
+	},
+};
+
+/* vf ping configuration */
+
+/* Common result structure for vf ping */
+struct cmd_vf_ping_result {
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t ping;
+	uint8_t port_id;
+	int32_t vf_id;
+};
+
+/* Common CLI fields for ping vfs */
+cmdline_parse_token_string_t cmd_vf_ping_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_ping_ping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 ping, "ping");
+cmdline_parse_token_num_t cmd_vf_ping_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_ping_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf_id, INT32);
+
+static void
+cmd_vf_ping_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_ping_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_vf_ping(res->port_id, res->vf_id);
+	if (ret < 0)
+		printf("ping vfs programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_vf_ping = {
+	.f = cmd_vf_ping_parsed,
+	.data = NULL,
+	.help_str = "ping all or specified vf",
+	.tokens = {
+		(void *)&cmd_vf_ping_vf,
+		(void *)&cmd_vf_ping_ping,
+		(void *)&cmd_vf_ping_port_id,
+		(void *)&cmd_vf_ping_vf_id,
+		NULL,
+	},
+};
+
+/* vf vlan strip configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_strip_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t strip;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_strip_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_strip =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 strip, "strip");
+cmdline_parse_token_num_t cmd_vf_vlan_strip_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_strip_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf_id, UINT16);
+cmdline_parse_token_num_t cmd_vf_vlan_strip_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_strip_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_strip_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_strip(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan strip programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_strip = {
+	.f = cmd_set_vf_vlan_strip_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan strip",
+	.tokens = {
+		(void *)&cmd_vf_vlan_strip_set,
+		(void *)&cmd_vf_vlan_strip_vf,
+		(void *)&cmd_vf_vlan_strip_vlan,
+		(void *)&cmd_vf_vlan_strip_strip,
+		(void *)&cmd_vf_vlan_strip_port_id,
+		(void *)&cmd_vf_vlan_strip_vf_id,
+		(void *)&cmd_vf_vlan_strip_on,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_insert(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf vlan insert programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan insert",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_loopback_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on, UINT8);
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_tx_loopback(res->port_id, res->on);
+	if (ret < 0)
+		printf("tx loopback programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf vlan insert",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_all_queues_drop_en_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on, UINT8);
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_all_queues_drop_en(res->port_id, res->on);
+	if (ret < 0)
+		printf("all queues drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "enable/disable all queues drop enable bits",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	uint8_t on;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_on =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on, UINT8);
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_split_drop_en(res->port_id, res->vf_id, res->on);
+	if (ret < 0)
+		printf("vf split drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "enable/disable vf split drop enable",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	if (ret < 0)
+		printf("set vf mac addr programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac address",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11430,15 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_vf_ping,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_strip,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..c26d901 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -473,6 +473,41 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
+ping VF
+~~~~~~~
+
+Ping VF or all VF's from PF::
+
+   testpmd> vf ping (port_id) (vf_id | -1)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set strip (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for a VF from the PF::
+
+   testpmd> set vf vlan strip (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert  (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof  (port_id) (vf_id) (on|off)
+
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +784,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* Re: [RFC PATCH v2 0/5] add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (4 preceding siblings ...)
  2016-08-26  9:10   ` [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
@ 2016-09-07  9:18   ` Pattan, Reshma
  2016-09-09  8:49   ` Pattan, Reshma
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Pattan, Reshma @ 2016-09-07  9:18 UTC (permalink / raw)
  To: dev, Lu, Wenzhuo, Shah, Rahul R; +Cc: Iremonger, Bernard, Iremonger, Bernard

Hi,

Ping for comments on this patch series.

Thanks,
Reshma

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard Iremonger
> Sent: Friday, August 26, 2016 10:10 AM
> To: Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; dev@dpdk.org
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> Subject: [dpdk-dev] [RFC PATCH v2 0/5] add API's for VF management
> 

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

* Re: [RFC PATCH v2 0/5] add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (5 preceding siblings ...)
  2016-09-07  9:18   ` [RFC PATCH v2 0/5] add API's for VF management Pattan, Reshma
@ 2016-09-09  8:49   ` Pattan, Reshma
  2016-09-09 13:02     ` Thomas Monjalon
  2016-09-16 11:05   ` [PATCH v3 0/3] " Bernard Iremonger
                     ` (7 subsequent siblings)
  14 siblings, 1 reply; 94+ messages in thread
From: Pattan, Reshma @ 2016-09-09  8:49 UTC (permalink / raw)
  To: Thomas Monjalon, Yigit, Ferruh
  Cc: Iremonger, Bernard, Shah, Rahul R, Lu, Wenzhuo, dev

Hi Thomas and Ferruh,

Can you take a look and  provide comments on ixgbe driver and ethdev changes.

Thanks,
Reshma

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard Iremonger
> Sent: Friday, August 26, 2016 10:10 AM
> To: Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; dev@dpdk.org
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>
> Subject: [dpdk-dev] [RFC PATCH v2 0/5] add API's for VF management
> 
> This RFC patchset contains new DPDK API's requested by AT&T for use with the
> Virtual Function Daemon (VFD).
> 
> The need to configure and manage VF's on a NIC has grown to the point where
> AT&T have devloped a DPDK based tool, VFD, to do this.
> 
> This RFC proposes to add the following API extensions to DPDK:
>   mailbox communication callback support
>   VF configuration
> 
> Nine new functions have been added to the eth_dev_ops structure.
> Corresponding functions have been added to the ixgbe PMD for the Niantic NIC.
> 
> Two new callback functions have been added.
> Changes have been made to the ixgbe_rcv_msg_from_vf function to use the
> callback functions.
> 
> Changes have been made to testpmd to facilitate testing of the new API's.
> The testpmd documentation has been updated to document the testpmd
> changes.
> 
> Note:
> Adding new functions to the eth_dev_ops structure will cause an ABI breakage.
> 
> Changes in V2:
> rebase to latest master branch.
> fix compile  error with clang.
> 
> Bernard Iremonger (5):
>   librte_ether: add internal callback functions
>   net/ixgbe: add callback to user app on VF to PF mbox msg
>   librte_ether: add API's for VF management
>   net/ixgbe: add functions for VF management
>   app/test_pmd: add tests for new API's
> 
>  app/test-pmd/cmdline.c                      | 700 ++++++++++++++++++++++++++++
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  68 ++-
>  drivers/net/ixgbe/ixgbe_ethdev.c            | 179 +++++++
>  drivers/net/ixgbe/ixgbe_pf.c                |  39 +-
>  lib/librte_ether/rte_ethdev.c               | 176 +++++++
>  lib/librte_ether/rte_ethdev.h               | 284 +++++++++++
>  lib/librte_ether/rte_ether_version.map      |  16 +
>  7 files changed, 1455 insertions(+), 7 deletions(-)
> 
> --
> 2.9.0

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

* Re: [RFC PATCH v2 0/5] add API's for VF management
  2016-09-09  8:49   ` Pattan, Reshma
@ 2016-09-09 13:02     ` Thomas Monjalon
  0 siblings, 0 replies; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-09 13:02 UTC (permalink / raw)
  To: Pattan, Reshma
  Cc: Yigit, Ferruh, Iremonger, Bernard, Shah, Rahul R, Lu, Wenzhuo, dev

2016-09-09 08:49, Pattan, Reshma:
> Hi Thomas and Ferruh,
> 
> Can you take a look and  provide comments on ixgbe driver and ethdev changes.

We could try.
But honestly we have a lot of work to do for DPDK, except reviews.
So I would appreciate to see more reviewers on ethdev stuff.

Volunteers are more than welcome!

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

* Re: [RFC PATCH v2 1/5] librte_ether: add internal callback functions
  2016-08-26  9:10   ` [RFC PATCH v2 1/5] librte_ether: add internal callback functions Bernard Iremonger
@ 2016-09-09 14:10     ` Jerin Jacob
       [not found]       ` <3C0218D8B3DD114D8DBFE6B68141FBE3185F9FE7@MISOUT7MSGUSRDI.ITServices.sbc.com>
  0 siblings, 1 reply; 94+ messages in thread
From: Jerin Jacob @ 2016-09-09 14:10 UTC (permalink / raw)
  To: Bernard Iremonger; +Cc: rahul.r.shah, wenzhuo.lu, dev, azelezniak

On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
> add _rte_eth_dev_callback_process_vf function.
> add _rte_eth_dev_callback_process_generic function
> 
> Adding a callback to the user application on VF to PF mailbox message,
> allows passing information to the application controlling the PF
> when a VF mailbox event message is received, such as VF reset.
> 
> Signed-off-by: azelezniak <alexz@att.com>
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
>  lib/librte_ether/rte_ethdev.h          | 61 ++++++++++++++++++++++++++++++++++
>  lib/librte_ether/rte_ether_version.map |  7 ++++
>  3 files changed, 85 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f62a9ec..1388ea3 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -2690,6 +2690,20 @@ void
>  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
>  	enum rte_eth_event_type event)
>  {
> +	return _rte_eth_dev_callback_process_generic(dev, event, NULL);
> +}
> +
> +void
> +_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
> +	enum rte_eth_event_type event, void *param)
> +{
> +	return _rte_eth_dev_callback_process_generic(dev, event, param);
> +}
> +
> +void
> +_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
> +	enum rte_eth_event_type event, void *param)
> +{
>  	struct rte_eth_dev_callback *cb_lst;
>  	struct rte_eth_dev_callback dev_cb;
>  
> @@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
>  			continue;
>  		dev_cb = *cb_lst;
>  		cb_lst->active = 1;
> +		if (param != NULL)
> +			dev_cb.cb_arg = (void *) param;
> +
>  		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
>  		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
>  						dev_cb.cb_arg);
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index b0fe033..4fb0b9c 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
>  				/**< queue state event (enabled/disabled) */
>  	RTE_ETH_EVENT_INTR_RESET,
>  			/**< reset interrupt event, sent to VF on PF reset */
> +	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing callback */
>  	RTE_ETH_EVENT_MAX       /**< max value of this enum */
>  };
>  
> +/**
> + * Response sent back to ixgbe driver from user app after callback
> + */
> +enum rte_eth_mb_event_rsp {
> +	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
> +	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
> +	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
> +	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum */
> +};

Do we really need to define the specifics of PF to VF MBOX communication
in normative ethdev specification?
Each drivers may have different PF to VF MBOX definitions so it may not be
very portable.
What is the use-case here? If its for VF configuration, I think we can
do it as separate 'sync' functions for each functionality so that
PMDs will have room hiding the specifics on MBOX definitions.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-08-26  9:10   ` [RFC PATCH v2 3/5] librte_ether: add API's for VF management Bernard Iremonger
@ 2016-09-09 14:22     ` Jerin Jacob
  2016-09-12 16:28       ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Jerin Jacob @ 2016-09-09 14:22 UTC (permalink / raw)
  To: Bernard Iremonger; +Cc: rahul.r.shah, wenzhuo.lu, dev, azelezniak

On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
> Add new API functions to configure and manage VF's on a NIC.
> 
> add rte_eth_dev_vf_ping function.
> add rte_eth_dev_set_vf_vlan_anti_spoof function.
> add rte_eth_dev_set_vf_mac_anti_spoof function.
> 
> Signed-off-by: azelezniak <alexz@att.com>
> 
> add rte_eth_dev_set_vf_vlan_strip function.
> add rte_eth_dev_set_vf_vlan_insert function.
> add rte_eth_dev_set_loopback function.
> add rte_eth_dev_set_all_queues_drop function.
> add rte_eth_dev_set_vf_split_drop_en function
> add rte_eth_dev_set_vf_mac_addr function.

Do we really need to expose VF specific functions here?
It can be generic(PF/VF) function indexed only through port_id.
(example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
For instance, In Thunderx PMD, We are not exposing a separate port_id
for PF. We only enumerate 0..N VFs as 0..N ethdev port_id

> increment LIBABIVER to 5.
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c          | 159 +++++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.h          | 223 +++++++++++++++++++++++++++++++++
>  lib/librte_ether/rte_ether_version.map |   9 ++
>  3 files changed, 391 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 1388ea3..2a3d2ae 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -2306,6 +2306,22 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
>  }
>  
>  int
> +rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
> +{
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	if (!is_valid_assigned_ether_addr(addr))
> +		return -EINVAL;
> +
> +	dev = &rte_eth_devices[port_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
> +
> +	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
> +}
> +
> +int
>  rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
>  				uint16_t rx_mode, uint8_t on)
>  {
> @@ -2490,6 +2506,149 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
>  						   vf_mask, vlan_on);
>  }
>  
> +int
> +rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
> +			       uint16_t vf, uint8_t on)
> +{
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +
> +	dev = &rte_eth_devices[port_id];
> +	if (vf > 63) {

PMD may have more than 64 VFs.


> +		RTE_PMD_DEBUG_TRACE("VF VLAN anti spoof:VF %d > 63\n", vf);
> +		return -EINVAL;
> +	}
> +
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
> +	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
> +	return 0;
> +}
> +

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

* Re: [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-08-26  9:10   ` [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
@ 2016-09-11 12:35     ` Yuanhan Liu
  2016-09-12 15:57       ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Yuanhan Liu @ 2016-09-11 12:35 UTC (permalink / raw)
  To: Bernard Iremonger; +Cc: rahul.r.shah, wenzhuo.lu, dev, Thomas Monjalon

On Fri, Aug 26, 2016 at 10:10:20AM +0100, Bernard Iremonger wrote:
> add test for vf vlan anti spoof
> add test for vf mac anti spoof
> add test for vf ping
> add test for vf vlan strip
> add test for vf vlan insert
> add test for tx loopback
> add test for all queues drop enable bit
> add test for vf split drop enable bit
> add test for vf mac address
> add new API's to the testpmd guide
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>

Hi,

FYI, my testrobot caught some errors when this patch is applied.
(BTW, gcc builds fine)

        --yliu

---

x86_64-native-linuxapp-clang
============================
/root/dpdk/app/test-pmd/cmdline.c:10629:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10710:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10856:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:10938:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11010:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11080:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
/root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which evaluates to zero treated as a null pointer constant of type 'const char *' [-Werror,-Wnon-literal-null-conversion]
                 on, UINT8);
                     ^~~~~
/root/dpdk/x86_64-native-linuxapp-clang/include/cmdline_parse_num.h:107:3: note: expanded from macro 'TOKEN_NUM_INITIALIZER'
                numtype,                        /* type */          \
                ^~~~~~~
7 errors generated.
make[5]: *** [cmdline.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [test-pmd] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [app] Error 2
make[2]: *** [all] Error 2
make[1]: *** [pre_install] Error 2
make: *** [install] Error 2
error: build failed

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

* Re: [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-09-11 12:35     ` Yuanhan Liu
@ 2016-09-12 15:57       ` Iremonger, Bernard
  2016-09-13  4:34         ` Yuanhan Liu
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-12 15:57 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, Thomas Monjalon

Hi Yuanhan,

<snip>

> Subject: Re: [dpdk-dev] [RFC PATCH v2 5/5] app/test_pmd: add tests for
> new API's
> 
> On Fri, Aug 26, 2016 at 10:10:20AM +0100, Bernard Iremonger wrote:
> > add test for vf vlan anti spoof
> > add test for vf mac anti spoof
> > add test for vf ping
> > add test for vf vlan strip
> > add test for vf vlan insert
> > add test for tx loopback
> > add test for all queues drop enable bit add test for vf split drop
> > enable bit add test for vf mac address add new API's to the testpmd
> > guide
> >
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> 
> Hi,
> 
> FYI, my testrobot caught some errors when this patch is applied.
> (BTW, gcc builds fine)
> 
>         --yliu
> 
> ---
> 
> x86_64-native-linuxapp-clang
> ============================
> /root/dpdk/app/test-pmd/cmdline.c:10629:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:10710:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:10856:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:10938:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:11010:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:11080:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> /root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
> evaluates to zero treated as a null pointer constant of type 'const char *' [-
> Werror,-Wnon-literal-null-conversion]
>                  on, UINT8);
>                      ^~~~~
> /root/dpdk/x86_64-native-linuxapp-
> clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> 'TOKEN_NUM_INITIALIZER'
>                 numtype,                        /* type */          \
>                 ^~~~~~~
> 7 errors generated.
> make[5]: *** [cmdline.o] Error 1
> make[5]: *** Waiting for unfinished jobs....
> make[4]: *** [test-pmd] Error 2
> make[4]: *** Waiting for unfinished jobs....
> make[3]: *** [app] Error 2
> make[2]: *** [all] Error 2
> make[1]: *** [pre_install] Error 2
> make: *** [install] Error 2
> error: build failed

I am not seeing the above errors when I build with the following commands:

make config T=x86_64-native-linuxapp-clang
make install T=x86_64-native-linuxapp-clang -j

Are you using a different clang config file?

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-09 14:22     ` Jerin Jacob
@ 2016-09-12 16:28       ` Iremonger, Bernard
  2016-09-13  9:24         ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-12 16:28 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, azelezniak

Hi Jerin,

<snip>

> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
> > Add new API functions to configure and manage VF's on a NIC.
> >
> > add rte_eth_dev_vf_ping function.
> > add rte_eth_dev_set_vf_vlan_anti_spoof function.
> > add rte_eth_dev_set_vf_mac_anti_spoof function.
> >
> > Signed-off-by: azelezniak <alexz@att.com>
> >
> > add rte_eth_dev_set_vf_vlan_strip function.
> > add rte_eth_dev_set_vf_vlan_insert function.
> > add rte_eth_dev_set_loopback function.
> > add rte_eth_dev_set_all_queues_drop function.
> > add rte_eth_dev_set_vf_split_drop_en function add
> > rte_eth_dev_set_vf_mac_addr function.
> 
> Do we really need to expose VF specific functions here?
> It can be generic(PF/VF) function indexed only through port_id.
> (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
> For instance, In Thunderx PMD, We are not exposing a separate port_id for
> PF. We only enumerate 0..N VFs as 0..N ethdev port_id

Our intention with this patch is to control the VF from the PF.

The following librte_ether functions already work in a similar way:

rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t rx_mode, uint8_t on)

rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)

rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)

int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate, uint64_t q_msk)

> 
> > increment LIBABIVER to 5.
> >
> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev.c          | 159 +++++++++++++++++++++++
> >  lib/librte_ether/rte_ethdev.h          | 223
> +++++++++++++++++++++++++++++++++
> >  lib/librte_ether/rte_ether_version.map |   9 ++
> >  3 files changed, 391 insertions(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c
> > b/lib/librte_ether/rte_ethdev.c index 1388ea3..2a3d2ae 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -2306,6 +2306,22 @@ rte_eth_dev_default_mac_addr_set(uint8_t
> > port_id, struct ether_addr *addr)  }
> >
> >  int
> > +rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct
> > +ether_addr *addr) {
> > +	struct rte_eth_dev *dev;
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > +
> > +	if (!is_valid_assigned_ether_addr(addr))
> > +		return -EINVAL;
> > +
> > +	dev = &rte_eth_devices[port_id];
> > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -
> ENOTSUP);
> > +
> > +	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr); }
> > +
> > +int
> >  rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
> >  				uint16_t rx_mode, uint8_t on)
> >  {
> > @@ -2490,6 +2506,149 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t
> port_id, uint16_t vlan_id,
> >  						   vf_mask, vlan_on);
> >  }
> >
> > +int
> > +rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
> > +			       uint16_t vf, uint8_t on)
> > +{
> > +	struct rte_eth_dev *dev;
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > +
> > +	dev = &rte_eth_devices[port_id];
> > +	if (vf > 63) {
> 
> PMD may have more than 64 VFs.

Yes, it would be better to check on max_vfs,  the same way as the already implemented functions mentioned above.
 
> 
> 
> > +		RTE_PMD_DEBUG_TRACE("VF VLAN anti spoof:VF %d >
> 63\n", vf);
> > +		return -EINVAL;
> > +	}
> > +
> > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >set_vf_vlan_anti_spoof, -ENOTSUP);
> > +	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
> > +	return 0;
> > +}
> > +

Thanks for reviewing.
Regards,

Bernard.

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

* Re: [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-09-12 15:57       ` Iremonger, Bernard
@ 2016-09-13  4:34         ` Yuanhan Liu
  2016-09-13  8:38           ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Yuanhan Liu @ 2016-09-13  4:34 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, Thomas Monjalon

On Mon, Sep 12, 2016 at 03:57:19PM +0000, Iremonger, Bernard wrote:
> > /root/dpdk/x86_64-native-linuxapp-
> > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > 'TOKEN_NUM_INITIALIZER'
> >                 numtype,                        /* type */          \
> >                 ^~~~~~~
> > /root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
> > evaluates to zero treated as a null pointer constant of type 'const char *' [-
> > Werror,-Wnon-literal-null-conversion]
> >                  on, UINT8);
> >                      ^~~~~
> > /root/dpdk/x86_64-native-linuxapp-
> > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > 'TOKEN_NUM_INITIALIZER'
> >                 numtype,                        /* type */          \
> >                 ^~~~~~~
> > 7 errors generated.
> > make[5]: *** [cmdline.o] Error 1
> > make[5]: *** Waiting for unfinished jobs....
> > make[4]: *** [test-pmd] Error 2
> > make[4]: *** Waiting for unfinished jobs....
> > make[3]: *** [app] Error 2
> > make[2]: *** [all] Error 2
> > make[1]: *** [pre_install] Error 2
> > make: *** [install] Error 2
> > error: build failed
> 
> I am not seeing the above errors when I build with the following commands:
> 
> make config T=x86_64-native-linuxapp-clang
> make install T=x86_64-native-linuxapp-clang -j
> 
> Are you using a different clang config file?

Not really (well, I disabled KNI and UIO stuff). FYI, I'm using the
default clang compiler from ubuntu 16.04-x86_64.

	--yliu

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

* Re: [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-09-13  4:34         ` Yuanhan Liu
@ 2016-09-13  8:38           ` Iremonger, Bernard
  2016-09-13  8:42             ` Yuanhan Liu
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-13  8:38 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, Thomas Monjalon

Hi Yuanhan,

<snip)
> Subject: Re: [dpdk-dev] [RFC PATCH v2 5/5] app/test_pmd: add tests for
> new API's
> 
> On Mon, Sep 12, 2016 at 03:57:19PM +0000, Iremonger, Bernard wrote:
> > > /root/dpdk/x86_64-native-linuxapp-
> > > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > > 'TOKEN_NUM_INITIALIZER'
> > >                 numtype,                        /* type */          \
> > >                 ^~~~~~~
> > > /root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
> > > evaluates to zero treated as a null pointer constant of type 'const
> > > char *' [- Werror,-Wnon-literal-null-conversion]
> > >                  on, UINT8);
> > >                      ^~~~~
> > > /root/dpdk/x86_64-native-linuxapp-
> > > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > > 'TOKEN_NUM_INITIALIZER'
> > >                 numtype,                        /* type */          \
> > >                 ^~~~~~~
> > > 7 errors generated.
> > > make[5]: *** [cmdline.o] Error 1
> > > make[5]: *** Waiting for unfinished jobs....
> > > make[4]: *** [test-pmd] Error 2
> > > make[4]: *** Waiting for unfinished jobs....
> > > make[3]: *** [app] Error 2
> > > make[2]: *** [all] Error 2
> > > make[1]: *** [pre_install] Error 2
> > > make: *** [install] Error 2
> > > error: build failed
> >
> > I am not seeing the above errors when I build with the following
> commands:
> >
> > make config T=x86_64-native-linuxapp-clang make install
> > T=x86_64-native-linuxapp-clang -j
> >
> > Are you using a different clang config file?
> 
> Not really (well, I disabled KNI and UIO stuff). FYI, I'm using the default clang
> compiler from ubuntu 16.04-x86_64.
> 
> 	--yliu

The clang I am using is version 3.4-1, what is your clang version?

Regards,

Bernard.

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

* Re: [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's
  2016-09-13  8:38           ` Iremonger, Bernard
@ 2016-09-13  8:42             ` Yuanhan Liu
  0 siblings, 0 replies; 94+ messages in thread
From: Yuanhan Liu @ 2016-09-13  8:42 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, Thomas Monjalon

On Tue, Sep 13, 2016 at 08:38:08AM +0000, Iremonger, Bernard wrote:
> Hi Yuanhan,
> 
> <snip)
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 5/5] app/test_pmd: add tests for
> > new API's
> > 
> > On Mon, Sep 12, 2016 at 03:57:19PM +0000, Iremonger, Bernard wrote:
> > > > /root/dpdk/x86_64-native-linuxapp-
> > > > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > > > 'TOKEN_NUM_INITIALIZER'
> > > >                 numtype,                        /* type */          \
> > > >                 ^~~~~~~
> > > > /root/dpdk/app/test-pmd/cmdline.c:11156:8: error: expression which
> > > > evaluates to zero treated as a null pointer constant of type 'const
> > > > char *' [- Werror,-Wnon-literal-null-conversion]
> > > >                  on, UINT8);
> > > >                      ^~~~~
> > > > /root/dpdk/x86_64-native-linuxapp-
> > > > clang/include/cmdline_parse_num.h:107:3: note: expanded from macro
> > > > 'TOKEN_NUM_INITIALIZER'
> > > >                 numtype,                        /* type */          \
> > > >                 ^~~~~~~
> > > > 7 errors generated.
> > > > make[5]: *** [cmdline.o] Error 1
> > > > make[5]: *** Waiting for unfinished jobs....
> > > > make[4]: *** [test-pmd] Error 2
> > > > make[4]: *** Waiting for unfinished jobs....
> > > > make[3]: *** [app] Error 2
> > > > make[2]: *** [all] Error 2
> > > > make[1]: *** [pre_install] Error 2
> > > > make: *** [install] Error 2
> > > > error: build failed
> > >
> > > I am not seeing the above errors when I build with the following
> > commands:
> > >
> > > make config T=x86_64-native-linuxapp-clang make install
> > > T=x86_64-native-linuxapp-clang -j
> > >
> > > Are you using a different clang config file?
> > 
> > Not really (well, I disabled KNI and UIO stuff). FYI, I'm using the default clang
> > compiler from ubuntu 16.04-x86_64.
> > 
> > 	--yliu
> 
> The clang I am using is version 3.4-1, what is your clang version?

The clang shipped with ubuntu 16.04 is v3.8:

# clang --version
clang version 3.8.0-2ubuntu1 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

	--yliu

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

* Re: [RFC PATCH v2 1/5] librte_ether: add internal callback functions
       [not found]       ` <3C0218D8B3DD114D8DBFE6B68141FBE3185F9FE7@MISOUT7MSGUSRDI.ITServices.sbc.com>
@ 2016-09-13  8:45         ` Jerin Jacob
       [not found]           ` <3C0218D8B3DD114D8DBFE6B68141FBE3185FDCDC@MISOUT7MSGUSRDI.ITServices.sbc.com>
  0 siblings, 1 reply; 94+ messages in thread
From: Jerin Jacob @ 2016-09-13  8:45 UTC (permalink / raw)
  To: ZELEZNIAK, ALEX; +Cc: Bernard Iremonger, rahul.r.shah, wenzhuo.lu, dev

On Fri, Sep 09, 2016 at 04:32:07PM +0000, ZELEZNIAK, ALEX wrote:
> Use case could be to inform application managing SRIOV about VM's intention
> to modify parameters like add VLAN which might not be the one which is 
> assigned to VF or inform about VF reset and reapply settings like strip/insert
> VLAN id based on policy.

Is there any other way(more portable way) where we can realize the same
use case?

Something like,

1) The assigned VM operates/control the VF
2) A centralized entity post messages through UNIX socket or
something(like vhost user communicates with VM).
On message receive, VM can take necessary action on assigned VF.

This will avoid the need of defining specifics of PF to VF mailbox
communication in normative ethdev specification.

And I guess it will work almost the PMD drivers as their is no
PMD specific work here.

Just a thought.

> 
> > -----Original Message-----
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > Sent: Friday, September 09, 2016 10:11 AM
> > To: Bernard Iremonger <bernard.iremonger@intel.com>
> > Cc: rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org;
> > ZELEZNIAK, ALEX <az5157@att.com>
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add internal
> > callback functions
> > 
> > On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
> > > add _rte_eth_dev_callback_process_vf function.
> > > add _rte_eth_dev_callback_process_generic function
> > >
> > > Adding a callback to the user application on VF to PF mailbox message,
> > > allows passing information to the application controlling the PF
> > > when a VF mailbox event message is received, such as VF reset.
> > >
> > > Signed-off-by: azelezniak <alexz@att.com>
> > > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > > ---
> > >  lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
> > >  lib/librte_ether/rte_ethdev.h          | 61
> > ++++++++++++++++++++++++++++++++++
> > >  lib/librte_ether/rte_ether_version.map |  7 ++++
> > >  3 files changed, 85 insertions(+)
> > >
> > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > > index f62a9ec..1388ea3 100644
> > > --- a/lib/librte_ether/rte_ethdev.c
> > > +++ b/lib/librte_ether/rte_ethdev.c
> > > @@ -2690,6 +2690,20 @@ void
> > >  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
> > >  	enum rte_eth_event_type event)
> > >  {
> > > +	return _rte_eth_dev_callback_process_generic(dev, event, NULL);
> > > +}
> > > +
> > > +void
> > > +_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
> > > +	enum rte_eth_event_type event, void *param)
> > > +{
> > > +	return _rte_eth_dev_callback_process_generic(dev, event, param);
> > > +}
> > > +
> > > +void
> > > +_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
> > > +	enum rte_eth_event_type event, void *param)
> > > +{
> > >  	struct rte_eth_dev_callback *cb_lst;
> > >  	struct rte_eth_dev_callback dev_cb;
> > >
> > > @@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct
> > rte_eth_dev *dev,
> > >  			continue;
> > >  		dev_cb = *cb_lst;
> > >  		cb_lst->active = 1;
> > > +		if (param != NULL)
> > > +			dev_cb.cb_arg = (void *) param;
> > > +
> > >  		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
> > >  		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
> > >  						dev_cb.cb_arg);
> > > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > > index b0fe033..4fb0b9c 100644
> > > --- a/lib/librte_ether/rte_ethdev.h
> > > +++ b/lib/librte_ether/rte_ethdev.h
> > > @@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
> > >  				/**< queue state event (enabled/disabled)
> > */
> > >  	RTE_ETH_EVENT_INTR_RESET,
> > >  			/**< reset interrupt event, sent to VF on PF reset */
> > > +	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing callback */
> > >  	RTE_ETH_EVENT_MAX       /**< max value of this enum */
> > >  };
> > >
> > > +/**
> > > + * Response sent back to ixgbe driver from user app after callback
> > > + */
> > > +enum rte_eth_mb_event_rsp {
> > > +	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK
> > */
> > > +	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request and
> > NACK */
> > > +	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox request
> > */
> > > +	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum */
> > > +};
> > 
> > Do we really need to define the specifics of PF to VF MBOX communication
> > in normative ethdev specification?
> > Each drivers may have different PF to VF MBOX definitions so it may not be
> > very portable.
> > What is the use-case here? If its for VF configuration, I think we can
> > do it as separate 'sync' functions for each functionality so that
> > PMDs will have room hiding the specifics on MBOX definitions.
> 

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-12 16:28       ` Iremonger, Bernard
@ 2016-09-13  9:24         ` Thomas Monjalon
  2016-09-15 16:46           ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-13  9:24 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo, azelezniak

2016-09-12 16:28, Iremonger, Bernard:
> > On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
> > > Add new API functions to configure and manage VF's on a NIC.
> > >
> > > add rte_eth_dev_vf_ping function.
> > > add rte_eth_dev_set_vf_vlan_anti_spoof function.
> > > add rte_eth_dev_set_vf_mac_anti_spoof function.
> > >
> > > Signed-off-by: azelezniak <alexz@att.com>
> > >
> > > add rte_eth_dev_set_vf_vlan_strip function.
> > > add rte_eth_dev_set_vf_vlan_insert function.
> > > add rte_eth_dev_set_loopback function.
> > > add rte_eth_dev_set_all_queues_drop function.
> > > add rte_eth_dev_set_vf_split_drop_en function add
> > > rte_eth_dev_set_vf_mac_addr function.
> > 
> > Do we really need to expose VF specific functions here?
> > It can be generic(PF/VF) function indexed only through port_id.
> > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id, uint8_t on))
> > For instance, In Thunderx PMD, We are not exposing a separate port_id for
> > PF. We only enumerate 0..N VFs as 0..N ethdev port_id
> 
> Our intention with this patch is to control the VF from the PF.
> 
> The following librte_ether functions already work in a similar way:
> 
> rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t rx_mode, uint8_t on)
> 
> rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> 
> rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> 
> int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate, uint64_t q_msk)

I have a bad feeling with these functions dedicated to VF from PF.
Are we sure there is no other way?
I mean we just need to know the VF with a port ID.

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

* Re: [RFC PATCH v2 1/5] librte_ether: add internal callback functions
       [not found]           ` <3C0218D8B3DD114D8DBFE6B68141FBE3185FDCDC@MISOUT7MSGUSRDI.ITServices.sbc.com>
@ 2016-09-14 11:28             ` Jerin Jacob
  2016-09-22 11:25               ` Iremonger, Bernard
  2016-10-03  8:58               ` Iremonger, Bernard
  0 siblings, 2 replies; 94+ messages in thread
From: Jerin Jacob @ 2016-09-14 11:28 UTC (permalink / raw)
  To: ZELEZNIAK, ALEX; +Cc: Bernard Iremonger, rahul.r.shah, wenzhuo.lu, dev

On Tue, Sep 13, 2016 at 02:05:49PM +0000, ZELEZNIAK, ALEX wrote:
> Idea here is not to allow VM to control policies assigned to it for security
> and other reasons. PF is controlled by host and dictates what VM can and 
> can't do in regards of setting VF parameters.

I think the proposed scheme, The VM does not take any action on its own.
The VM will just follow what the centralized entity to do so.
I think if you are planning to support different varieties of PMD then
this could be an option.However, if you wish to support only a subset of
PMDs then PF MBOX based scheme may be enough.
In any case, I think exposing the fine details of PF/VF MBOX scheme
in the ethdev spec is not a good idea.

> 
> 
> > -----Original Message-----
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > Sent: Tuesday, September 13, 2016 4:46 AM
> > To: ZELEZNIAK, ALEX <az5157@att.com>
> > Cc: Bernard Iremonger <bernard.iremonger@intel.com>;
> > rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add internal
> > callback functions
> > 
> > On Fri, Sep 09, 2016 at 04:32:07PM +0000, ZELEZNIAK, ALEX wrote:
> > > Use case could be to inform application managing SRIOV about VM's
> > intention
> > > to modify parameters like add VLAN which might not be the one which is
> > > assigned to VF or inform about VF reset and reapply settings like
> > strip/insert
> > > VLAN id based on policy.
> > 
> > Is there any other way(more portable way) where we can realize the same
> > use case?
> > 
> > Something like,
> > 
> > 1) The assigned VM operates/control the VF
> > 2) A centralized entity post messages through UNIX socket or
> > something(like vhost user communicates with VM).
> > On message receive, VM can take necessary action on assigned VF.
> > 
> > This will avoid the need of defining specifics of PF to VF mailbox
> > communication in normative ethdev specification.
> > 
> > And I guess it will work almost the PMD drivers as their is no
> > PMD specific work here.
> > 
> > Just a thought.
> > 
> > >
> > > > -----Original Message-----
> > > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > > Sent: Friday, September 09, 2016 10:11 AM
> > > > To: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > Cc: rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org;
> > > > ZELEZNIAK, ALEX <az5157@att.com>
> > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add internal
> > > > callback functions
> > > >
> > > > On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
> > > > > add _rte_eth_dev_callback_process_vf function.
> > > > > add _rte_eth_dev_callback_process_generic function
> > > > >
> > > > > Adding a callback to the user application on VF to PF mailbox message,
> > > > > allows passing information to the application controlling the PF
> > > > > when a VF mailbox event message is received, such as VF reset.
> > > > >
> > > > > Signed-off-by: azelezniak <alexz@att.com>
> > > > > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > ---
> > > > >  lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
> > > > >  lib/librte_ether/rte_ethdev.h          | 61
> > > > ++++++++++++++++++++++++++++++++++
> > > > >  lib/librte_ether/rte_ether_version.map |  7 ++++
> > > > >  3 files changed, 85 insertions(+)
> > > > >
> > > > > diff --git a/lib/librte_ether/rte_ethdev.c
> > b/lib/librte_ether/rte_ethdev.c
> > > > > index f62a9ec..1388ea3 100644
> > > > > --- a/lib/librte_ether/rte_ethdev.c
> > > > > +++ b/lib/librte_ether/rte_ethdev.c
> > > > > @@ -2690,6 +2690,20 @@ void
> > > > >  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
> > > > >  	enum rte_eth_event_type event)
> > > > >  {
> > > > > +	return _rte_eth_dev_callback_process_generic(dev, event, NULL);
> > > > > +}
> > > > > +
> > > > > +void
> > > > > +_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
> > > > > +	enum rte_eth_event_type event, void *param)
> > > > > +{
> > > > > +	return _rte_eth_dev_callback_process_generic(dev, event, param);
> > > > > +}
> > > > > +
> > > > > +void
> > > > > +_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
> > > > > +	enum rte_eth_event_type event, void *param)
> > > > > +{
> > > > >  	struct rte_eth_dev_callback *cb_lst;
> > > > >  	struct rte_eth_dev_callback dev_cb;
> > > > >
> > > > > @@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct
> > > > rte_eth_dev *dev,
> > > > >  			continue;
> > > > >  		dev_cb = *cb_lst;
> > > > >  		cb_lst->active = 1;
> > > > > +		if (param != NULL)
> > > > > +			dev_cb.cb_arg = (void *) param;
> > > > > +
> > > > >  		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
> > > > >  		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
> > > > >  						dev_cb.cb_arg);
> > > > > diff --git a/lib/librte_ether/rte_ethdev.h
> > b/lib/librte_ether/rte_ethdev.h
> > > > > index b0fe033..4fb0b9c 100644
> > > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > > @@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
> > > > >  				/**< queue state event (enabled/disabled)
> > > > */
> > > > >  	RTE_ETH_EVENT_INTR_RESET,
> > > > >  			/**< reset interrupt event, sent to VF on PF reset */
> > > > > +	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing callback */
> > > > >  	RTE_ETH_EVENT_MAX       /**< max value of this enum */
> > > > >  };
> > > > >
> > > > > +/**
> > > > > + * Response sent back to ixgbe driver from user app after callback
> > > > > + */
> > > > > +enum rte_eth_mb_event_rsp {
> > > > > +	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK
> > > > */
> > > > > +	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request and
> > > > NACK */
> > > > > +	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox request
> > > > */
> > > > > +	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum */
> > > > > +};
> > > >
> > > > Do we really need to define the specifics of PF to VF MBOX
> > communication
> > > > in normative ethdev specification?
> > > > Each drivers may have different PF to VF MBOX definitions so it may not
> > be
> > > > very portable.
> > > > What is the use-case here? If its for VF configuration, I think we can
> > > > do it as separate 'sync' functions for each functionality so that
> > > > PMDs will have room hiding the specifics on MBOX definitions.
> > >

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-13  9:24         ` Thomas Monjalon
@ 2016-09-15 16:46           ` Iremonger, Bernard
  2016-09-22 17:04             ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-15 16:46 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo, azelezniak

Hi Thomas,

<snip>

> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-12 16:28, Iremonger, Bernard:
> > > On Fri, Aug 26, 2016 at 10:10:18AM +0100, Bernard Iremonger wrote:
> > > > Add new API functions to configure and manage VF's on a NIC.
> > > >
> > > > add rte_eth_dev_vf_ping function.
> > > > add rte_eth_dev_set_vf_vlan_anti_spoof function.
> > > > add rte_eth_dev_set_vf_mac_anti_spoof function.
> > > >
> > > > Signed-off-by: azelezniak <alexz@att.com>
> > > >
> > > > add rte_eth_dev_set_vf_vlan_strip function.
> > > > add rte_eth_dev_set_vf_vlan_insert function.
> > > > add rte_eth_dev_set_loopback function.
> > > > add rte_eth_dev_set_all_queues_drop function.
> > > > add rte_eth_dev_set_vf_split_drop_en function add
> > > > rte_eth_dev_set_vf_mac_addr function.
> > >
> > > Do we really need to expose VF specific functions here?
> > > It can be generic(PF/VF) function indexed only through port_id.
> > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
> > > uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
> > > separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
> > > port_id
> >
> > Our intention with this patch is to control the VF from the PF.
> >
> > The following librte_ether functions already work in a similar way:
> >
> > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t
> > rx_mode, uint8_t on)
> >
> > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> >
> > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> >
> > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
> > tx_rate, uint64_t q_msk)
> 
> I have a bad feeling with these functions dedicated to VF from PF.
> Are we sure there is no other way?
> I mean we just need to know the VF with a port ID.

When the VF is used in a VM the port ID of the VF is not visible to the PF.
I don't think there is another way to do this.

Regards,

Bernard.

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

* [PATCH v3 0/3] add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (6 preceding siblings ...)
  2016-09-09  8:49   ` Pattan, Reshma
@ 2016-09-16 11:05   ` Bernard Iremonger
  2016-09-16 11:05   ` [PATCH v3 1/3] librte_ether: " Bernard Iremonger
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 11:05 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This patch set adds API extensions to DPDK VF configuration.

Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (3):
  librte_ether: add API's for VF management
  net/ixgbe: add functions for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 707 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  70 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 166 +++++++
 lib/librte_ether/rte_ethdev.c               | 192 ++++++++
 lib/librte_ether/rte_ethdev.h               | 217 ++++++++-
 lib/librte_ether/rte_ether_version.map      |  14 +
 6 files changed, 1362 insertions(+), 4 deletions(-)

-- 
2.9.0

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

* [PATCH v3 1/3] librte_ether: add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (7 preceding siblings ...)
  2016-09-16 11:05   ` [PATCH v3 0/3] " Bernard Iremonger
@ 2016-09-16 11:05   ` Bernard Iremonger
  2016-09-16 11:05   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 11:05 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new API functions to configure and manage VF's on a NIC.

add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
add rte_eth_dev_set_vf_vlan_strip function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 192 +++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 217 ++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map |  14 +++
 3 files changed, 422 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..4f83c29 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2305,6 +2305,30 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
 }
 
 int
+rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (!is_valid_assigned_ether_addr(addr))
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF mac addr: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
+
+	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
+}
+
+int
 rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
 				uint16_t rx_mode, uint8_t on)
 {
@@ -2489,6 +2513,174 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF VLAN anti spoof: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF MAC anti spoof:invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_mac_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_vf_ping(uint8_t port_id, int32_t vf)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("VF ping: invalid VF %d\n", vf);
+		return -EINVAL;
+	} else if (vf < -1) {
+			RTE_PMD_DEBUG_TRACE("VF ping: invalid value %d\n", vf);
+			return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vf_ping, -ENOTSUP);
+	return (*dev->dev_ops->vf_ping)(dev, vf);
+}
+
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan strip: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan insert: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_insert, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_vlan_insert)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_tx_loopback(uint8_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_tx_loopback, -ENOTSUP);
+
+	(*dev->dev_ops->set_tx_loopback)(dev, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port_id, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_all_queues_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_all_queues_drop_en)(dev, state);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port_id, uint16_t vf, int state)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF split drop enable: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_split_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_split_drop_en)(dev, vf, state);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 96575e8..68b477f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
+typedef int (*eth_set_vf_mac_addr_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  struct ether_addr *mac_addr);
+/**< @internal Set VF address into Receive Address Address Register */
+
 typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr,
 				  uint8_t on);
@@ -1264,6 +1269,38 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
 				  uint8_t vlan_on);
 /**< @internal Set VF VLAN pool filter */
 
+typedef void (*eth_set_vf_vlan_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF VLAN anti spoof */
+
+typedef void (*eth_set_vf_mac_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF MAC anti spoof */
+
+typedef int (*eth_vf_ping_t)(struct rte_eth_dev *dev,
+				int32_t vf);
+/**< @internal ping one or all vf's */
+
+typedef void (*eth_set_vf_vlan_insert_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int vlan);
+/**< @internal Set VF vlan insert */
+
+typedef void (*eth_set_tx_loopback_t)(struct rte_eth_dev *dev,
+				  int on);
+/**< @internal Set tx loopback */
+
+typedef void (*eth_set_all_queues_drop_en_t)(struct rte_eth_dev *dev,
+				  int state);
+/**< @internal Set all queues drop */
+
+typedef void (*eth_set_vf_split_drop_en_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int state);
+/**< @internal Set the enable drop bit in the VF split rx control register */
+
 typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
 				uint16_t queue_idx,
 				uint16_t tx_rate);
@@ -1468,6 +1505,7 @@ struct eth_dev_ops {
 	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address */
 	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address */
 	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address */
+	eth_set_vf_mac_addr_t      set_vf_mac_addr;  /**< Set a VF MAC address */
 	eth_uc_hash_table_set_t    uc_hash_table_set;  /**< Set Unicast Table Array */
 	eth_uc_all_hash_table_set_t uc_all_hash_table_set;  /**< Set Unicast hash bitmap */
 	eth_mirror_rule_set_t	   mirror_rule_set;  /**< Add a traffic mirror rule.*/
@@ -1476,6 +1514,13 @@ struct eth_dev_ops {
 	eth_set_vf_rx_t            set_vf_rx;  /**< enable/disable a VF receive */
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
+	eth_set_vf_vlan_anti_spoof_t  set_vf_vlan_anti_spoof; /**< Set VF VLAN anti spoof */
+	eth_set_vf_mac_anti_spoof_t   set_vf_mac_anti_spoof;  /**< Set VF MAC anti spoof */
+	eth_vf_ping_t             vf_ping;  /**< Ping one or all VF's */
+	eth_set_vf_vlan_insert_t  set_vf_vlan_insert; /** <Set VF VLAN insert */
+	eth_set_tx_loopback_t  set_tx_loopback; /** <Set tx loopback */
+	eth_set_all_queues_drop_en_t  set_all_queues_drop_en; /** <Set queue drop enable bit */
+	eth_set_vf_split_drop_en_t  set_vf_split_drop_en; /** <Set split drop enable bit.*/
 	/** Add UDP tunnel port. */
 	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
 	/** Del UDP tunnel port. */
@@ -3332,7 +3377,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
  */
 int rte_eth_dev_default_mac_addr_set(uint8_t port, struct ether_addr *mac_addr);
 
-
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful, or *mac_addr* didn't exist.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if MAC address is invalid.
+ */
+int rte_eth_dev_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr);
 /**
  * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
  *
@@ -3499,6 +3560,160 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Ping all or specified VF
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   specify VF to ping or all if -1.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_vf_ping(uint8_t port, int32_t vf);
+
+/**
+ * Enable/Disable vf vlan strip
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip.
+ *    0 - Disable VF's vlan strip
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_tx_loopback(uint8_t port, int on);
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param state
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port, int state);
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param state
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port, uint16_t vf, int state);
+/**
  * Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..3fe149f 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,17 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_eth_dev_set_all_queues_drop_en;
+	rte_eth_dev_set_tx_loopback;
+	rte_eth_dev_set_vf_mac_addr;
+	rte_eth_dev_set_vf_mac_anti_spoof;
+	rte_eth_dev_set_vf_split_drop_en;
+	rte_eth_dev_set_vf_vlan_anti_spoof;
+	rte_eth_dev_set_vf_vlan_insert;
+	rte_eth_dev_set_vf_vlan_strip;
+	rte_eth_dev_vf_ping;
+} DPDK_16.07;
-- 
2.9.0

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

* [PATCH v3 2/3] net/ixgbe: add functions for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (8 preceding siblings ...)
  2016-09-16 11:05   ` [PATCH v3 1/3] librte_ether: " Bernard Iremonger
@ 2016-09-16 11:05   ` Bernard Iremonger
  2016-09-16 11:05   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 11:05 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new functions to configure and manage VF's on an Intel 82559 NIC.

add ixgbe_vf_ping function.
add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fb618ef..9875290 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,17 @@ static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static int ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -562,6 +575,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -570,6 +584,13 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.vf_ping              = ixgbe_vf_ping,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4069,6 +4090,22 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4661,6 +4698,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static int
+ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf)
+{
+	int ret = 0;
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_vf_info *vfinfo =
+		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+
+	u32 ping;
+	int i;
+
+	for (i = 0; i < dev->pci_dev->max_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+
+		/* ping every VF or only one specified */
+		if (vf < 0 || vf == i)
+			ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+
+	return ret;
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
-- 
2.9.0

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

* [PATCH v3 3/3] app/test_pmd: add tests for new API's
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (9 preceding siblings ...)
  2016-09-16 11:05   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
@ 2016-09-16 11:05   ` Bernard Iremonger
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 11:05 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 707 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  70 ++-
 2 files changed, 774 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f90befc..264aa90 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10585,6 +10585,704 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+	ret = rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan anti spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan mac spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf ping configuration */
+
+/* Common result structure for vf ping */
+struct cmd_vf_ping_result {
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t ping;
+	uint8_t port_id;
+	int32_t vf_id;
+};
+
+/* Common CLI fields for ping vfs */
+cmdline_parse_token_string_t cmd_vf_ping_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_ping_ping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 ping, "ping");
+cmdline_parse_token_num_t cmd_vf_ping_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_ping_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf_id, INT32);
+
+static void
+cmd_vf_ping_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_ping_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_vf_ping(res->port_id, res->vf_id);
+	if (ret < 0)
+		printf("ping vfs programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_vf_ping = {
+	.f = cmd_vf_ping_parsed,
+	.data = NULL,
+	.help_str = "vf ping port_id vf_id|-1",
+	.tokens = {
+		(void *)&cmd_vf_ping_vf,
+		(void *)&cmd_vf_ping_ping,
+		(void *)&cmd_vf_ping_port_id,
+		(void *)&cmd_vf_ping_vf_id,
+		NULL,
+	},
+};
+
+/* vf vlan strip configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_strip_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t strip;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_strip_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_strip =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 strip, "strip");
+cmdline_parse_token_num_t cmd_vf_vlan_strip_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_strip_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_strip_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_strip_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_strip_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_strip(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan strip programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_strip = {
+	.f = cmd_set_vf_vlan_strip_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan strip port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_strip_set,
+		(void *)&cmd_vf_vlan_strip_vf,
+		(void *)&cmd_vf_vlan_strip_vlan,
+		(void *)&cmd_vf_vlan_strip_strip,
+		(void *)&cmd_vf_vlan_strip_port_id,
+		(void *)&cmd_vf_vlan_strip_vf_id,
+		(void *)&cmd_vf_vlan_strip_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan insert programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_tx_loopback(res->port_id, is_on);
+	if (ret < 0)
+		printf("tx loopback programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_all_queues_drop_en(res->port_id, is_on);
+	if (ret < 0)
+		printf("all queues drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf split drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	if (ret < 0)
+		printf("set vf mac addr programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11437,15 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_vf_ping,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_strip,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..c84d5e2 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,41 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
+ping VF
+~~~~~~~
+
+Ping VF or all VF's from PF::
+
+   testpmd> vf ping (port_id) (vf_id | -1)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set strip (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for a VF from the PF::
+
+   testpmd> set vf vlan strip (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert  (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof  (port_id) (vf_id) (on|off)
+
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +784,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* [PATCH v3 0/3] add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (10 preceding siblings ...)
  2016-09-16 11:05   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
@ 2016-09-16 14:15   ` Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
                       ` (3 more replies)
  2016-09-16 14:15   ` [PATCH v3 1/3] librte_ether: add API's for VF management Bernard Iremonger
                     ` (2 subsequent siblings)
  14 siblings, 4 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 14:15 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This patch set adds API extensions to DPDK VF configuration.

Nine new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (3):
  librte_ether: add API's for VF management
  net/ixgbe: add functions for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 707 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  70 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 166 +++++++
 lib/librte_ether/rte_ethdev.c               | 192 ++++++++
 lib/librte_ether/rte_ethdev.h               | 217 ++++++++-
 lib/librte_ether/rte_ether_version.map      |  14 +
 6 files changed, 1362 insertions(+), 4 deletions(-)

-- 
2.9.0

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

* [PATCH v3 1/3] librte_ether: add API's for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (11 preceding siblings ...)
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
@ 2016-09-16 14:15   ` Bernard Iremonger
  2016-09-16 14:15   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
  2016-09-16 14:15   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 14:15 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new API functions to configure and manage VF's on a NIC.

add rte_eth_dev_vf_ping function.
add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
add rte_eth_dev_set_vf_vlan_strip function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 192 +++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 217 ++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map |  14 +++
 3 files changed, 422 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..4f83c29 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2305,6 +2305,30 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
 }
 
 int
+rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (!is_valid_assigned_ether_addr(addr))
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF mac addr: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
+
+	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
+}
+
+int
 rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
 				uint16_t rx_mode, uint8_t on)
 {
@@ -2489,6 +2513,174 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF VLAN anti spoof: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF MAC anti spoof:invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_mac_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_vf_ping(uint8_t port_id, int32_t vf)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("VF ping: invalid VF %d\n", vf);
+		return -EINVAL;
+	} else if (vf < -1) {
+			RTE_PMD_DEBUG_TRACE("VF ping: invalid value %d\n", vf);
+			return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vf_ping, -ENOTSUP);
+	return (*dev->dev_ops->vf_ping)(dev, vf);
+}
+
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan strip: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan insert: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_insert, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_vlan_insert)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_tx_loopback(uint8_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_tx_loopback, -ENOTSUP);
+
+	(*dev->dev_ops->set_tx_loopback)(dev, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port_id, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_all_queues_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_all_queues_drop_en)(dev, state);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port_id, uint16_t vf, int state)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF split drop enable: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_split_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_split_drop_en)(dev, vf, state);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 96575e8..68b477f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
+typedef int (*eth_set_vf_mac_addr_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  struct ether_addr *mac_addr);
+/**< @internal Set VF address into Receive Address Address Register */
+
 typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr,
 				  uint8_t on);
@@ -1264,6 +1269,38 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
 				  uint8_t vlan_on);
 /**< @internal Set VF VLAN pool filter */
 
+typedef void (*eth_set_vf_vlan_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF VLAN anti spoof */
+
+typedef void (*eth_set_vf_mac_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF MAC anti spoof */
+
+typedef int (*eth_vf_ping_t)(struct rte_eth_dev *dev,
+				int32_t vf);
+/**< @internal ping one or all vf's */
+
+typedef void (*eth_set_vf_vlan_insert_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int vlan);
+/**< @internal Set VF vlan insert */
+
+typedef void (*eth_set_tx_loopback_t)(struct rte_eth_dev *dev,
+				  int on);
+/**< @internal Set tx loopback */
+
+typedef void (*eth_set_all_queues_drop_en_t)(struct rte_eth_dev *dev,
+				  int state);
+/**< @internal Set all queues drop */
+
+typedef void (*eth_set_vf_split_drop_en_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int state);
+/**< @internal Set the enable drop bit in the VF split rx control register */
+
 typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
 				uint16_t queue_idx,
 				uint16_t tx_rate);
@@ -1468,6 +1505,7 @@ struct eth_dev_ops {
 	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address */
 	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address */
 	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address */
+	eth_set_vf_mac_addr_t      set_vf_mac_addr;  /**< Set a VF MAC address */
 	eth_uc_hash_table_set_t    uc_hash_table_set;  /**< Set Unicast Table Array */
 	eth_uc_all_hash_table_set_t uc_all_hash_table_set;  /**< Set Unicast hash bitmap */
 	eth_mirror_rule_set_t	   mirror_rule_set;  /**< Add a traffic mirror rule.*/
@@ -1476,6 +1514,13 @@ struct eth_dev_ops {
 	eth_set_vf_rx_t            set_vf_rx;  /**< enable/disable a VF receive */
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
+	eth_set_vf_vlan_anti_spoof_t  set_vf_vlan_anti_spoof; /**< Set VF VLAN anti spoof */
+	eth_set_vf_mac_anti_spoof_t   set_vf_mac_anti_spoof;  /**< Set VF MAC anti spoof */
+	eth_vf_ping_t             vf_ping;  /**< Ping one or all VF's */
+	eth_set_vf_vlan_insert_t  set_vf_vlan_insert; /** <Set VF VLAN insert */
+	eth_set_tx_loopback_t  set_tx_loopback; /** <Set tx loopback */
+	eth_set_all_queues_drop_en_t  set_all_queues_drop_en; /** <Set queue drop enable bit */
+	eth_set_vf_split_drop_en_t  set_vf_split_drop_en; /** <Set split drop enable bit.*/
 	/** Add UDP tunnel port. */
 	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
 	/** Del UDP tunnel port. */
@@ -3332,7 +3377,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
  */
 int rte_eth_dev_default_mac_addr_set(uint8_t port, struct ether_addr *mac_addr);
 
-
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful, or *mac_addr* didn't exist.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if MAC address is invalid.
+ */
+int rte_eth_dev_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr);
 /**
  * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
  *
@@ -3499,6 +3560,160 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Ping all or specified VF
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   specify VF to ping or all if -1.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_vf_ping(uint8_t port, int32_t vf);
+
+/**
+ * Enable/Disable vf vlan strip
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip.
+ *    0 - Disable VF's vlan strip
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_strip(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_tx_loopback(uint8_t port, int on);
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param state
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port, int state);
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param state
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port, uint16_t vf, int state);
+/**
  * Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..3fe149f 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,17 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_eth_dev_set_all_queues_drop_en;
+	rte_eth_dev_set_tx_loopback;
+	rte_eth_dev_set_vf_mac_addr;
+	rte_eth_dev_set_vf_mac_anti_spoof;
+	rte_eth_dev_set_vf_split_drop_en;
+	rte_eth_dev_set_vf_vlan_anti_spoof;
+	rte_eth_dev_set_vf_vlan_insert;
+	rte_eth_dev_set_vf_vlan_strip;
+	rte_eth_dev_vf_ping;
+} DPDK_16.07;
-- 
2.9.0

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

* [PATCH v3 2/3] net/ixgbe: add functions for VF management
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (12 preceding siblings ...)
  2016-09-16 14:15   ` [PATCH v3 1/3] librte_ether: add API's for VF management Bernard Iremonger
@ 2016-09-16 14:15   ` Bernard Iremonger
  2016-09-16 14:15   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 14:15 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new functions to configure and manage VF's on an Intel 82559 NIC.

add ixgbe_vf_ping function.
add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 166 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fb618ef..9875290 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,17 @@ static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static int ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -562,6 +575,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -570,6 +584,13 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.vf_ping              = ixgbe_vf_ping,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4069,6 +4090,22 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4661,6 +4698,135 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static int
+ixgbe_vf_ping(struct rte_eth_dev *dev, int32_t vf)
+{
+	int ret = 0;
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_vf_info *vfinfo =
+		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+
+	u32 ping;
+	int i;
+
+	for (i = 0; i < dev->pci_dev->max_vfs; i++) {
+		ping = IXGBE_PF_CONTROL_MSG;
+		if (vfinfo[i].clear_to_send)
+			ping |= IXGBE_VT_MSGTYPE_CTS;
+
+		/* ping every VF or only one specified */
+		if (vf < 0 || vf == i)
+			ixgbe_write_mbx(hw, &ping, 1, i);
+	}
+
+	return ret;
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
-- 
2.9.0

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

* [PATCH v3 3/3] app/test_pmd: add tests for new API's
  2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
                     ` (13 preceding siblings ...)
  2016-09-16 14:15   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
@ 2016-09-16 14:15   ` Bernard Iremonger
  14 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-16 14:15 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf ping
add test for vf vlan strip
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 707 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  70 ++-
 2 files changed, 774 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f90befc..264aa90 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10585,6 +10585,704 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+	ret = rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan anti spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan mac spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf ping configuration */
+
+/* Common result structure for vf ping */
+struct cmd_vf_ping_result {
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t ping;
+	uint8_t port_id;
+	int32_t vf_id;
+};
+
+/* Common CLI fields for ping vfs */
+cmdline_parse_token_string_t cmd_vf_ping_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_ping_ping =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 ping, "ping");
+cmdline_parse_token_num_t cmd_vf_ping_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_ping_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_ping_result,
+		 vf_id, INT32);
+
+static void
+cmd_vf_ping_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_ping_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_vf_ping(res->port_id, res->vf_id);
+	if (ret < 0)
+		printf("ping vfs programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_vf_ping = {
+	.f = cmd_vf_ping_parsed,
+	.data = NULL,
+	.help_str = "vf ping port_id vf_id|-1",
+	.tokens = {
+		(void *)&cmd_vf_ping_vf,
+		(void *)&cmd_vf_ping_ping,
+		(void *)&cmd_vf_ping_port_id,
+		(void *)&cmd_vf_ping_vf_id,
+		NULL,
+	},
+};
+
+/* vf vlan strip configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_strip_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t strip;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_strip_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_strip_strip =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 strip, "strip");
+cmdline_parse_token_num_t cmd_vf_vlan_strip_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_strip_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_strip_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_strip_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_strip_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_strip_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_strip(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan strip programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_strip = {
+	.f = cmd_set_vf_vlan_strip_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan strip port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_strip_set,
+		(void *)&cmd_vf_vlan_strip_vf,
+		(void *)&cmd_vf_vlan_strip_vlan,
+		(void *)&cmd_vf_vlan_strip_strip,
+		(void *)&cmd_vf_vlan_strip_port_id,
+		(void *)&cmd_vf_vlan_strip_vf_id,
+		(void *)&cmd_vf_vlan_strip_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan insert programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_tx_loopback(res->port_id, is_on);
+	if (ret < 0)
+		printf("tx loopback programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_all_queues_drop_en(res->port_id, is_on);
+	if (ret < 0)
+		printf("all queues drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf split drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	if (ret < 0)
+		printf("set vf mac addr programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11437,15 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_vf_ping,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_strip,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..c84d5e2 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,41 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
+ping VF
+~~~~~~~
+
+Ping VF or all VF's from PF::
+
+   testpmd> vf ping (port_id) (vf_id | -1)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +522,28 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set strip (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for a VF from the PF::
+
+   testpmd> set vf vlan strip (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert  (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof  (port_id) (vf_id) (on|off)
+
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +784,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* [PATCH v4 0/3] add API's for VF management
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
@ 2016-09-21 10:20     ` Bernard Iremonger
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
                         ` (3 more replies)
  2016-09-21 10:20     ` [PATCH v4 1/3] librte_ether: add API's for VF management Bernard Iremonger
                       ` (2 subsequent siblings)
  3 siblings, 4 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-21 10:20 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This patch set adds API extensions to DPDK VF configuration.

Eight new functions have been added to the eth_dev_ops structure.
Corresponding functions have been added to the ixgbe PMD for the
Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Note:
Adding new functions to the eth_dev_ops structure will cause an
ABI breakage.

Changes in v4:
rebase to latest master branch.
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (3):
  librte_ether: add API's for VF management
  net/ixgbe: add functions for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 644 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 138 ++++++
 lib/librte_ether/rte_ethdev.c               | 169 ++++++++
 lib/librte_ether/rte_ethdev.h               | 195 ++++++++-
 lib/librte_ether/rte_ether_version.map      |  13 +
 6 files changed, 1217 insertions(+), 4 deletions(-)

-- 
2.9.0

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

* [PATCH v4 1/3] librte_ether: add API's for VF management
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
@ 2016-09-21 10:20     ` Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 2/3] net/ixgbe: add functions " Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  3 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-21 10:20 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new API functions to configure and manage VF's on a NIC.

add rte_eth_dev_set_vf_vlan_anti_spoof function.
add rte_eth_dev_set_vf_mac_anti_spoof function.
add rte_eth_dev_set_vf_vlan_stripq function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_eth_dev_set_vf_vlan_insert function.
add rte_eth_dev_set_loopback function.
add rte_eth_dev_set_all_queues_drop function.
add rte_eth_dev_set_vf_split_drop_en function
add rte_eth_dev_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 169 ++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 195 ++++++++++++++++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map |  13 +++
 3 files changed, 376 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..41d25c7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2305,6 +2305,30 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
 }
 
 int
+rte_eth_dev_set_vf_mac_addr(uint8_t port_id, uint16_t vf, struct ether_addr *addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	if (!is_valid_assigned_ether_addr(addr))
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF mac addr: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_addr, -ENOTSUP);
+
+	return (*dev->dev_ops->set_vf_mac_addr)(dev, vf, addr);
+}
+
+int
 rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
 				uint16_t rx_mode, uint8_t on)
 {
@@ -2489,6 +2513,151 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF VLAN anti spoof: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_vlan_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port_id,
+			       uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF MAC anti spoof:invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_mac_anti_spoof, -ENOTSUP);
+	(*dev->dev_ops->set_vf_mac_anti_spoof)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan stripq: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan insert: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_insert, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_vlan_insert)(dev, vf, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_tx_loopback(uint8_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_tx_loopback, -ENOTSUP);
+
+	(*dev->dev_ops->set_tx_loopback)(dev, on);
+	return 0;
+}
+
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port_id, int state)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_all_queues_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_all_queues_drop_en)(dev, state);
+	return 0;
+}
+
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port_id, uint16_t vf, int state)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF split drop enable: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_split_drop_en, -ENOTSUP);
+
+	(*dev->dev_ops->set_vf_split_drop_en)(dev, vf, state);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 96575e8..4be4bc7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1233,6 +1233,11 @@ typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
+typedef int (*eth_set_vf_mac_addr_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  struct ether_addr *mac_addr);
+/**< @internal Set VF address into Receive Address Address Register */
+
 typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr,
 				  uint8_t on);
@@ -1264,6 +1269,34 @@ typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
 				  uint8_t vlan_on);
 /**< @internal Set VF VLAN pool filter */
 
+typedef void (*eth_set_vf_vlan_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF VLAN anti spoof */
+
+typedef void (*eth_set_vf_mac_anti_spoof_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  uint8_t on);
+/**< @internal Set VF MAC anti spoof */
+
+typedef void (*eth_set_vf_vlan_insert_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int vlan);
+/**< @internal Set VF vlan insert */
+
+typedef void (*eth_set_tx_loopback_t)(struct rte_eth_dev *dev,
+				  int on);
+/**< @internal Set tx loopback */
+
+typedef void (*eth_set_all_queues_drop_en_t)(struct rte_eth_dev *dev,
+				  int state);
+/**< @internal Set all queues drop */
+
+typedef void (*eth_set_vf_split_drop_en_t)(struct rte_eth_dev *dev,
+				  uint16_t vf,
+				  int state);
+/**< @internal Set the enable drop bit in the VF split rx control register */
+
 typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
 				uint16_t queue_idx,
 				uint16_t tx_rate);
@@ -1468,6 +1501,7 @@ struct eth_dev_ops {
 	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address */
 	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address */
 	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address */
+	eth_set_vf_mac_addr_t      set_vf_mac_addr;  /**< Set a VF MAC address */
 	eth_uc_hash_table_set_t    uc_hash_table_set;  /**< Set Unicast Table Array */
 	eth_uc_all_hash_table_set_t uc_all_hash_table_set;  /**< Set Unicast hash bitmap */
 	eth_mirror_rule_set_t	   mirror_rule_set;  /**< Add a traffic mirror rule.*/
@@ -1476,6 +1510,12 @@ struct eth_dev_ops {
 	eth_set_vf_rx_t            set_vf_rx;  /**< enable/disable a VF receive */
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
+	eth_set_vf_vlan_anti_spoof_t  set_vf_vlan_anti_spoof; /**< Set VF VLAN anti spoof */
+	eth_set_vf_mac_anti_spoof_t   set_vf_mac_anti_spoof;  /**< Set VF MAC anti spoof */
+	eth_set_vf_vlan_insert_t   set_vf_vlan_insert; /** <Set VF VLAN insert */
+	eth_set_tx_loopback_t      set_tx_loopback; /** <Set tx loopback */
+	eth_set_all_queues_drop_en_t set_all_queues_drop_en; /** <Set queue drop enable bit */
+	eth_set_vf_split_drop_en_t  set_vf_split_drop_en; /** <Set split drop enable bit.*/
 	/** Add UDP tunnel port. */
 	eth_udp_tunnel_port_add_t udp_tunnel_port_add;
 	/** Del UDP tunnel port. */
@@ -3332,7 +3372,23 @@ int rte_eth_dev_mac_addr_remove(uint8_t port, struct ether_addr *mac_addr);
  */
 int rte_eth_dev_default_mac_addr_set(uint8_t port, struct ether_addr *mac_addr);
 
-
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful, or *mac_addr* didn't exist.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if MAC address is invalid.
+ */
+int rte_eth_dev_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr);
 /**
  * Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device.
  *
@@ -3499,6 +3555,143 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param vlan_on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_mac_anti_spoof(uint8_t port,
+				uint16_t vf,
+				uint8_t on);
+
+/**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_insert(uint8_t port, uint16_t vf, int on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_tx_loopback(uint8_t port, int on);
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param state
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_all_queues_drop_en(uint8_t port, int state);
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param state
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_split_drop_en(uint8_t port, uint16_t vf, int state);
+/**
  * Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..4a1c1c7 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,16 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_eth_dev_set_all_queues_drop_en;
+	rte_eth_dev_set_tx_loopback;
+	rte_eth_dev_set_vf_mac_addr;
+	rte_eth_dev_set_vf_mac_anti_spoof;
+	rte_eth_dev_set_vf_split_drop_en;
+	rte_eth_dev_set_vf_vlan_anti_spoof;
+	rte_eth_dev_set_vf_vlan_insert;
+	rte_eth_dev_set_vf_vlan_stripq;
+} DPDK_16.07;
-- 
2.9.0

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

* [PATCH v4 2/3] net/ixgbe: add functions for VF management
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 1/3] librte_ether: add API's for VF management Bernard Iremonger
@ 2016-09-21 10:20     ` Bernard Iremonger
  2016-09-21 10:20     ` [PATCH v4 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  3 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-21 10:20 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new functions to configure and manage VF's on an Intel 82559 NIC.

add ixgbe_set_vf_vlan_anti_spoof function.
add ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add ixgbe_set_vf_vlan_insert function.
add ixgbe_set_tx_loopback function.
add ixgbe_set_all_queues_drop function.
add ixgbe_set_vf_split_drop_en function.
add ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 138 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 73a406b..38bb52c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -240,6 +240,8 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
+static int ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf,
+				  struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -280,6 +282,16 @@ static int ixgbe_set_pool_rx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on)
 static int ixgbe_set_pool_tx(struct rte_eth_dev *dev, uint16_t pool, uint8_t on);
 static int ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 		uint64_t pool_mask, uint8_t vlan_on);
+static void ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+		uint16_t vf, uint8_t on);
+static void ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf,
+		int vlan);
+static void ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on);
+static void ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state);
+static void ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf,
+		int state);
 static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
 		struct rte_eth_mirror_conf *mirror_conf,
 		uint8_t rule_id, uint8_t on);
@@ -562,6 +574,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.mac_addr_add         = ixgbe_add_rar,
 	.mac_addr_remove      = ixgbe_remove_rar,
 	.mac_addr_set         = ixgbe_set_default_mac_addr,
+	.set_vf_mac_addr      = ixgbe_set_vf_mac_addr,
 	.uc_hash_table_set    = ixgbe_uc_hash_table_set,
 	.uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
 	.mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -570,6 +583,12 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.set_vf_vlan_anti_spoof  = ixgbe_set_vf_vlan_anti_spoof,
+	.set_vf_mac_anti_spoof   = ixgbe_set_vf_mac_anti_spoof,
+	.set_vf_vlan_insert   = ixgbe_set_vf_vlan_insert,
+	.set_tx_loopback      = ixgbe_set_tx_loopback,
+	.set_all_queues_drop_en = ixgbe_set_all_queues_drop_en,
+	.set_vf_split_drop_en = ixgbe_set_vf_split_drop_en,
 	.set_queue_rate_limit = ixgbe_set_queue_rate_limit,
 	.set_vf_rate_limit    = ixgbe_set_vf_rate_limit,
 	.reta_update          = ixgbe_dev_rss_reta_update,
@@ -4069,6 +4088,22 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
+ixgbe_set_vf_mac_addr(struct rte_eth_dev *dev, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_vf_info *vfinfo =
+		*(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -1;
+}
+
+static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	uint32_t hlreg0;
@@ -4661,6 +4696,109 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+static void
+ixgbe_set_vf_vlan_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+			IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_mac_anti_spoof(struct rte_eth_dev *dev,
+			uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_mac_info *mac = &hw->mac;
+
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+}
+
+static void
+ixgbe_set_vf_vlan_insert(struct rte_eth_dev *dev, uint16_t vf, int vlan)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (vlan) {
+		ctrl = vlan;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+}
+
+static void
+ixgbe_set_tx_loopback(struct rte_eth_dev *dev, int on)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t ctrl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+}
+
+static void
+ixgbe_set_all_queues_drop_en(struct rte_eth_dev *dev, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(state & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+}
+
+static void
+ixgbe_set_vf_split_drop_en(struct rte_eth_dev *dev, uint16_t vf, int state)
+{
+	struct ixgbe_hw *hw =
+		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t reg_value;
+
+	PMD_INIT_FUNC_TRACE();
+
+	/* only support VF's 0 to 63 */
+	if (vf > 63)
+		return;
+
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (state)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
-- 
2.9.0

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

* [PATCH v4 3/3] app/test_pmd: add tests for new API's
  2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
                       ` (2 preceding siblings ...)
  2016-09-21 10:20     ` [PATCH v4 2/3] net/ixgbe: add functions " Bernard Iremonger
@ 2016-09-21 10:20     ` Bernard Iremonger
  3 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-21 10:20 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for vf vlan anti spoof
add test for vf mac anti spoof
add test for vf vlan stripq
add test for vf vlan insert
add test for tx loopback
add test for all queues drop enable bit
add test for vf split drop enable bit
add test for vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 644 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 2 files changed, 703 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f90befc..982bf88 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10585,6 +10585,642 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+	ret = rte_eth_dev_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan anti spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan mac spoofing programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+
+
+/* vf vlan strip queue configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_stripq_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t stripq;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 stripq, "stripq");
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_stripq_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_stripq_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan strip programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
+	.f = cmd_set_vf_vlan_stripq_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan stripq port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_stripq_set,
+		(void *)&cmd_vf_vlan_stripq_vf,
+		(void *)&cmd_vf_vlan_stripq_vlan,
+		(void *)&cmd_vf_vlan_stripq_stripq,
+		(void *)&cmd_vf_vlan_stripq_port_id,
+		(void *)&cmd_vf_vlan_stripq_vf_id,
+		(void *)&cmd_vf_vlan_stripq_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf vlan insert programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_tx_loopback(res->port_id, is_on);
+	if (ret < 0)
+		printf("tx loopback programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	ret = rte_eth_dev_set_all_queues_drop_en(res->port_id, is_on);
+	if (ret < 0)
+		printf("all queues drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	if (ret < 0)
+		printf("vf split drop enable programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret = 0;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+
+	if (res->vf_id > 63) {
+		printf("vf_id must be less than 64.\n");
+		return;
+	}
+
+	ret = rte_eth_dev_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	if (ret < 0)
+		printf("set vf mac addr programming error: (%s)\n",
+		       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11375,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..145c425 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set stripq (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for all queues in a pool for a VF from the PF::
+
+   testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +776,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* Re: [RFC PATCH v2 1/5] librte_ether: add internal callback functions
  2016-09-14 11:28             ` Jerin Jacob
@ 2016-09-22 11:25               ` Iremonger, Bernard
  2016-10-03  8:58               ` Iremonger, Bernard
  1 sibling, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-22 11:25 UTC (permalink / raw)
  To: Jerin Jacob, Thomas Monjalon
  Cc: Shah, Rahul R, Lu, Wenzhuo, dev, ZELEZNIAK, ALEX

Hi Jerin, Thomas,

<snip>

> -----Original Message-----
> Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add internal
> callback functions
> 
> On Tue, Sep 13, 2016 at 02:05:49PM +0000, ZELEZNIAK, ALEX wrote:
> > Idea here is not to allow VM to control policies assigned to it for
> > security and other reasons. PF is controlled by host and dictates what
> > VM can and can't do in regards of setting VF parameters.
> 
> I think the proposed scheme, The VM does not take any action on its own.
> The VM will just follow what the centralized entity to do so.
> I think if you are planning to support different varieties of PMD then this
> could be an option. However, if you wish to support only a subset of PMDs
> then PF MBOX based scheme may be enough.
> In any case, I think exposing the fine details of PF/VF MBOX scheme in the
> ethdev spec is not a good idea.

The AT&T requirement is to have the application controlling the PF (for example VFD) receive information via a callback when a VF mailbox event is received (for example IXGBE_VF_SET_VLAN) to decide whether to allow or deny a VF request. 

Do you have any suggestions on how the above requirement can be met without "exposing the fine details of PF/VF MBOX scheme in the ethdev spec".

Regards,

Bernard.


> > > -----Original Message-----
> > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > Sent: Tuesday, September 13, 2016 4:46 AM
> > > To: ZELEZNIAK, ALEX <az5157@att.com>
> > > Cc: Bernard Iremonger <bernard.iremonger@intel.com>;
> > > rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add
> > > internal callback functions
> > >
> > > On Fri, Sep 09, 2016 at 04:32:07PM +0000, ZELEZNIAK, ALEX wrote:
> > > > Use case could be to inform application managing SRIOV about VM's
> > > intention
> > > > to modify parameters like add VLAN which might not be the one
> > > > which is assigned to VF or inform about VF reset and reapply
> > > > settings like
> > > strip/insert
> > > > VLAN id based on policy.
> > >
> > > Is there any other way(more portable way) where we can realize the
> > > same use case?
> > >
> > > Something like,
> > >
> > > 1) The assigned VM operates/control the VF
> > > 2) A centralized entity post messages through UNIX socket or
> > > something(like vhost user communicates with VM).
> > > On message receive, VM can take necessary action on assigned VF.
> > >
> > > This will avoid the need of defining specifics of PF to VF mailbox
> > > communication in normative ethdev specification.
> > >
> > > And I guess it will work almost the PMD drivers as their is no PMD
> > > specific work here.
> > >
> > > Just a thought.
> > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > > > Sent: Friday, September 09, 2016 10:11 AM
> > > > > To: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > Cc: rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org;
> > > > > ZELEZNIAK, ALEX <az5157@att.com>
> > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add
> > > > > internal callback functions
> > > > >
> > > > > On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
> > > > > > add _rte_eth_dev_callback_process_vf function.
> > > > > > add _rte_eth_dev_callback_process_generic function
> > > > > >
> > > > > > Adding a callback to the user application on VF to PF mailbox
> > > > > > message, allows passing information to the application
> > > > > > controlling the PF when a VF mailbox event message is received,
> such as VF reset.
> > > > > >
> > > > > > Signed-off-by: azelezniak <alexz@att.com>
> > > > > > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > > ---
> > > > > >  lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
> > > > > >  lib/librte_ether/rte_ethdev.h          | 61
> > > > > ++++++++++++++++++++++++++++++++++
> > > > > >  lib/librte_ether/rte_ether_version.map |  7 ++++
> > > > > >  3 files changed, 85 insertions(+)
> > > > > >
> > > > > > diff --git a/lib/librte_ether/rte_ethdev.c
> > > b/lib/librte_ether/rte_ethdev.c
> > > > > > index f62a9ec..1388ea3 100644
> > > > > > --- a/lib/librte_ether/rte_ethdev.c
> > > > > > +++ b/lib/librte_ether/rte_ethdev.c
> > > > > > @@ -2690,6 +2690,20 @@ void
> > > > > >  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
> > > > > >  	enum rte_eth_event_type event)  {
> > > > > > +	return _rte_eth_dev_callback_process_generic(dev, event,
> > > > > > +NULL); }
> > > > > > +
> > > > > > +void
> > > > > > +_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
> > > > > > +	enum rte_eth_event_type event, void *param) {
> > > > > > +	return _rte_eth_dev_callback_process_generic(dev, event,
> > > > > > +param); }
> > > > > > +
> > > > > > +void
> > > > > > +_rte_eth_dev_callback_process_generic(struct rte_eth_dev
> *dev,
> > > > > > +	enum rte_eth_event_type event, void *param) {
> > > > > >  	struct rte_eth_dev_callback *cb_lst;
> > > > > >  	struct rte_eth_dev_callback dev_cb;
> > > > > >
> > > > > > @@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct
> > > > > rte_eth_dev *dev,
> > > > > >  			continue;
> > > > > >  		dev_cb = *cb_lst;
> > > > > >  		cb_lst->active = 1;
> > > > > > +		if (param != NULL)
> > > > > > +			dev_cb.cb_arg = (void *) param;
> > > > > > +
> > > > > >  		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
> > > > > >  		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
> > > > > >  						dev_cb.cb_arg);
> > > > > > diff --git a/lib/librte_ether/rte_ethdev.h
> > > b/lib/librte_ether/rte_ethdev.h
> > > > > > index b0fe033..4fb0b9c 100644
> > > > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > > > @@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
> > > > > >  				/**< queue state event
> (enabled/disabled)
> > > > > */
> > > > > >  	RTE_ETH_EVENT_INTR_RESET,
> > > > > >  			/**< reset interrupt event, sent to VF on PF
> reset */
> > > > > > +	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing
> callback
> > > > > > +*/
> > > > > >  	RTE_ETH_EVENT_MAX       /**< max value of this enum */
> > > > > >  };
> > > > > >
> > > > > > +/**
> > > > > > + * Response sent back to ixgbe driver from user app after
> > > > > > +callback  */ enum rte_eth_mb_event_rsp {
> > > > > > +	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request
> and ACK
> > > > > */
> > > > > > +	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request
> and
> > > > > NACK */
> > > > > > +	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox
> request
> > > > > */
> > > > > > +	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum
> */
> > > > > > +};
> > > > >
> > > > > Do we really need to define the specifics of PF to VF MBOX
> > > communication
> > > > > in normative ethdev specification?
> > > > > Each drivers may have different PF to VF MBOX definitions so it
> > > > > may not
> > > be
> > > > > very portable.
> > > > > What is the use-case here? If its for VF configuration, I think
> > > > > we can do it as separate 'sync' functions for each functionality
> > > > > so that PMDs will have room hiding the specifics on MBOX definitions.
> > > >

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-15 16:46           ` Iremonger, Bernard
@ 2016-09-22 17:04             ` Thomas Monjalon
  2016-09-23  9:20               ` Bruce Richardson
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-22 17:04 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo, azelezniak

2016-09-15 16:46, Iremonger, Bernard:
> > > > Do we really need to expose VF specific functions here?
> > > > It can be generic(PF/VF) function indexed only through port_id.
> > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
> > > > uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
> > > > separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > port_id
> > >
> > > Our intention with this patch is to control the VF from the PF.
> > >
> > > The following librte_ether functions already work in a similar way:
> > >
> > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t
> > > rx_mode, uint8_t on)
> > >
> > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> > >
> > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> > >
> > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
> > > tx_rate, uint64_t q_msk)
> > 
> > I have a bad feeling with these functions dedicated to VF from PF.
> > Are we sure there is no other way?
> > I mean we just need to know the VF with a port ID.
> 
> When the VF is used in a VM the port ID of the VF is not visible to the PF.
> I don't think there is another way to do this.

I don't understand why we could not assign a port id to the VF from the
host instead of having the couple PF port id / VF id.
Can we enumerate all the VFs associated to a PF?
Then can we allocate them a port id in the array rte_eth_devices?

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-22 17:04             ` Thomas Monjalon
@ 2016-09-23  9:20               ` Bruce Richardson
  2016-09-23  9:36                 ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Bruce Richardson @ 2016-09-23  9:20 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> 2016-09-15 16:46, Iremonger, Bernard:
> > > > > Do we really need to expose VF specific functions here?
> > > > > It can be generic(PF/VF) function indexed only through port_id.
> > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
> > > > > uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
> > > > > separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > > port_id
> > > >
> > > > Our intention with this patch is to control the VF from the PF.
> > > >
> > > > The following librte_ether functions already work in a similar way:
> > > >
> > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t
> > > > rx_mode, uint8_t on)
> > > >
> > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > >
> > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > >
> > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
> > > > tx_rate, uint64_t q_msk)
> > > 
> > > I have a bad feeling with these functions dedicated to VF from PF.
> > > Are we sure there is no other way?
> > > I mean we just need to know the VF with a port ID.
> > 
> > When the VF is used in a VM the port ID of the VF is not visible to the PF.
> > I don't think there is another way to do this.
> 
> I don't understand why we could not assign a port id to the VF from the
> host instead of having the couple PF port id / VF id.
> Can we enumerate all the VFs associated to a PF?
> Then can we allocate them a port id in the array rte_eth_devices?

Hi Thomas,

The VF is not a port visible to DPDK, though, so it shouldn't have a port id
IMHO. DPDK can't actually do anything with it.

The PCI device for the VF is likely passed through to a different VM and being
used there. Unfortunately, the VF still needs certain things done for it by the
PF, so if the PF is under DPDK control, it needs to provide the functionality
to assist the VF.

/Bruce

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23  9:20               ` Bruce Richardson
@ 2016-09-23  9:36                 ` Thomas Monjalon
  2016-09-23  9:53                   ` Richardson, Bruce
  2016-09-23 10:34                   ` Bruce Richardson
  0 siblings, 2 replies; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-23  9:36 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Iremonger, Bernard, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

2016-09-23 10:20, Bruce Richardson:
> On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > Do we really need to expose VF specific functions here?
> > > > > > It can be generic(PF/VF) function indexed only through port_id.
> > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
> > > > > > uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
> > > > > > separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > > > port_id
> > > > >
> > > > > Our intention with this patch is to control the VF from the PF.
> > > > >
> > > > > The following librte_ether functions already work in a similar way:
> > > > >
> > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t
> > > > > rx_mode, uint8_t on)
> > > > >
> > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > > >
> > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > > >
> > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
> > > > > tx_rate, uint64_t q_msk)
> > > > 
> > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > Are we sure there is no other way?
> > > > I mean we just need to know the VF with a port ID.
> > > 
> > > When the VF is used in a VM the port ID of the VF is not visible to the PF.
> > > I don't think there is another way to do this.
> > 
> > I don't understand why we could not assign a port id to the VF from the
> > host instead of having the couple PF port id / VF id.
> > Can we enumerate all the VFs associated to a PF?
> > Then can we allocate them a port id in the array rte_eth_devices?
> 
> Hi Thomas,
> 
> The VF is not a port visible to DPDK, though, so it shouldn't have a port id
> IMHO. DPDK can't actually do anything with it.

You say the contrary below.

> The PCI device for the VF is likely passed through to a different VM and being
> used there. Unfortunately, the VF still needs certain things done for it by the
> PF, so if the PF is under DPDK control, it needs to provide the functionality
> to assist the VF.

Why not have a VF_from_PF driver which does the mailbox things?
So you can manage the VF from the PF with a simple port id.
It really seems to be the cleanest design to me.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23  9:36                 ` Thomas Monjalon
@ 2016-09-23  9:53                   ` Richardson, Bruce
  2016-09-23 13:15                     ` Thomas Monjalon
  2016-09-23 10:34                   ` Bruce Richardson
  1 sibling, 1 reply; 94+ messages in thread
From: Richardson, Bruce @ 2016-09-23  9:53 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, September 23, 2016 10:36 AM
> To: Richardson, Bruce <bruce.richardson@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; dev@dpdk.org; Jerin
> Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul R
> <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; azelezniak
> <alexz@att.com>
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-23 10:20, Bruce Richardson:
> > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > It can be generic(PF/VF) function indexed only through
> port_id.
> > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD, We are
> > > > > > > not exposing a separate port_id for PF. We only enumerate
> > > > > > > 0..N VFs as 0..N ethdev port_id
> > > > > >
> > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > >
> > > > > > The following librte_ether functions already work in a similar
> way:
> > > > > >
> > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
> > > > > > uint16_t rx_mode, uint8_t on)
> > > > > >
> > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t
> > > > > > on)
> > > > > >
> > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t
> > > > > > on)
> > > > > >
> > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf,
> > > > > > uint16_t tx_rate, uint64_t q_msk)
> > > > >
> > > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > > Are we sure there is no other way?
> > > > > I mean we just need to know the VF with a port ID.
> > > >
> > > > When the VF is used in a VM the port ID of the VF is not visible to
> the PF.
> > > > I don't think there is another way to do this.
> > >
> > > I don't understand why we could not assign a port id to the VF from
> > > the host instead of having the couple PF port id / VF id.
> > > Can we enumerate all the VFs associated to a PF?
> > > Then can we allocate them a port id in the array rte_eth_devices?
> >
> > Hi Thomas,
> >
> > The VF is not a port visible to DPDK, though, so it shouldn't have a
> > port id IMHO. DPDK can't actually do anything with it.
> 
> You say the contrary below.

Well, yes and no. The driver can manipulate things for the VF, but DPDK doesn't actually have a device that corresponds to the VF. There are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
> 
> > The PCI device for the VF is likely passed through to a different VM
> > and being used there. Unfortunately, the VF still needs certain things
> > done for it by the PF, so if the PF is under DPDK control, it needs to
> > provide the functionality to assist the VF.
> 
> Why not have a VF_from_PF driver which does the mailbox things?
> So you can manage the VF from the PF with a simple port id.
> It really seems to be the cleanest design to me.

While I see your point, and it could work, I just want to be sure that we are ok with the results of that. Suppose we do create ethdevs for the VFs controlled by the PF. Does the new VF get counted in the rte_eth_dev_count() value (I assume yes)? How are apps meant to use the port? Do they have to put in a special case when iterating through all the port ids to check that it's not a pseudo port that can't do anything. None of the standard ethdev calls from an app will work on it, you can't configure nb rx/tx queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.

/Bruce

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23  9:36                 ` Thomas Monjalon
  2016-09-23  9:53                   ` Richardson, Bruce
@ 2016-09-23 10:34                   ` Bruce Richardson
  1 sibling, 0 replies; 94+ messages in thread
From: Bruce Richardson @ 2016-09-23 10:34 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

On Fri, Sep 23, 2016 at 11:36:21AM +0200, Thomas Monjalon wrote:
> 2016-09-23 10:20, Bruce Richardson:
> > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > It can be generic(PF/VF) function indexed only through port_id.
> > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t port_id,
> > > > > > > uint8_t on)) For instance, In Thunderx PMD, We are not exposing a
> > > > > > > separate port_id for PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > > > > port_id
> > > > > >
> > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > >
> > > > > > The following librte_ether functions already work in a similar way:
> > > > > >
> > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf, uint16_t
> > > > > > rx_mode, uint8_t on)
> > > > > >
> > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > > > >
> > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
> > > > > >
> > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t
> > > > > > tx_rate, uint64_t q_msk)
> > > > > 
> > > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > > Are we sure there is no other way?
> > > > > I mean we just need to know the VF with a port ID.
> > > > 
> > > > When the VF is used in a VM the port ID of the VF is not visible to the PF.
> > > > I don't think there is another way to do this.
> > > 
> > > I don't understand why we could not assign a port id to the VF from the
> > > host instead of having the couple PF port id / VF id.
> > > Can we enumerate all the VFs associated to a PF?
> > > Then can we allocate them a port id in the array rte_eth_devices?
> > 
> > Hi Thomas,
> > 
> > The VF is not a port visible to DPDK, though, so it shouldn't have a port id
> > IMHO. DPDK can't actually do anything with it.
> 
> You say the contrary below.
> 
> > The PCI device for the VF is likely passed through to a different VM and being
> > used there. Unfortunately, the VF still needs certain things done for it by the
> > PF, so if the PF is under DPDK control, it needs to provide the functionality
> > to assist the VF.
> 
> Why not have a VF_from_PF driver which does the mailbox things?
> So you can manage the VF from the PF with a simple port id.
> It really seems to be the cleanest design to me.

Just to confirm I am understanding your suggestion correctly:

* for a normal app, eg. testpmd or l2fwd, things stay exactly as they are
* for an app that wants to control VFs from PFs, then we provide a new 
  ethdev driver, and a call in the PF to create an new instance of it 
  e.g. rte_eth_vf_from_pf(pf_port_id, vf_number)
* then to control the VF, you make regular rte_ethdev calls using the new
  ethdev port id you got from the vf_from_pf call.
* it's up to that app to know what ports are regular ports that can do IO,
  and what ports are VF control ports, though we may add in an ethdev flag value
  somewhere to assist in this.

Is that basically it?

/Bruce

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23  9:53                   ` Richardson, Bruce
@ 2016-09-23 13:15                     ` Thomas Monjalon
  2016-09-23 17:02                       ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-23 13:15 UTC (permalink / raw)
  To: Richardson, Bruce, Iremonger, Bernard
  Cc: dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo, azelezniak

2016-09-23 09:53, Richardson, Bruce:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-09-23 10:20, Bruce Richardson:
> > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > > It can be generic(PF/VF) function indexed only through
> > port_id.
> > > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD, We are
> > > > > > > > not exposing a separate port_id for PF. We only enumerate
> > > > > > > > 0..N VFs as 0..N ethdev port_id
> > > > > > >
> > > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > > >
> > > > > > > The following librte_ether functions already work in a similar
> > way:
> > > > > > >
> > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
> > > > > > > uint16_t rx_mode, uint8_t on)
> > > > > > >
> > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t
> > > > > > > on)
> > > > > > >
> > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t
> > > > > > > on)
> > > > > > >
> > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf,
> > > > > > > uint16_t tx_rate, uint64_t q_msk)
> > > > > >
> > > > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > > > Are we sure there is no other way?
> > > > > > I mean we just need to know the VF with a port ID.
> > > > >
> > > > > When the VF is used in a VM the port ID of the VF is not visible to
> > the PF.
> > > > > I don't think there is another way to do this.
> > > >
> > > > I don't understand why we could not assign a port id to the VF from
> > > > the host instead of having the couple PF port id / VF id.
> > > > Can we enumerate all the VFs associated to a PF?
> > > > Then can we allocate them a port id in the array rte_eth_devices?
> > >
> > > Hi Thomas,
> > >
> > > The VF is not a port visible to DPDK, though, so it shouldn't have a
> > > port id IMHO. DPDK can't actually do anything with it.
> > 
> > You say the contrary below.
> 
> Well, yes and no. The driver can manipulate things for the VF, but DPDK doesn't actually have a device that corresponds to the VF. There are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?

Very good point.
There are only few ethdev functions which are supported by every drivers,
like Rx/Tx and would not be available for VF from PF interface.

> > > The PCI device for the VF is likely passed through to a different VM
> > > and being used there. Unfortunately, the VF still needs certain things
> > > done for it by the PF, so if the PF is under DPDK control, it needs to
> > > provide the functionality to assist the VF.
> > 
> > Why not have a VF_from_PF driver which does the mailbox things?
> > So you can manage the VF from the PF with a simple port id.
> > It really seems to be the cleanest design to me.
> 
> While I see your point, and it could work, I just want to be sure that we are ok with the results of that. Suppose we do create ethdevs for the VFs controlled by the PF. Does the new VF get counted in the rte_eth_dev_count() value (I assume yes)? How are apps meant to use the port? Do they have to put in a special case when iterating through all the port ids to check that it's not a pseudo port that can't do anything. None of the standard ethdev calls from an app will work on it, you can't configure nb rx/tx queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.

Yes these devices would be special because their supported API would be
quite different. I was thinking that in the future you could add most
of the configuration functions through the VF mailbox.
But the Intel mailbox currently support only some special configurations
which are not supported by other devices even its own VF device (except
setting MAC address).
And when I read "set drop enable bit in the VF split rx control register",
it becomes clear it is really specific and has nothing to do in the
generic ethdev API.
That's why it is a NACK.

When we want to use these very specific features we are aware of the
underlying device and driver. So we can directly include a header from
the driver. I suggest to retrieve a handler for the device which is not
a port id and will allow to call ixgbe functions directly.
It could be achieved by adding an ethdev function like discussed here:
	http://dpdk.org/ml/archives/dev/2016-September/047392.html

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23 13:15                     ` Thomas Monjalon
@ 2016-09-23 17:02                       ` Iremonger, Bernard
  2016-09-23 17:18                         ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-23 17:02 UTC (permalink / raw)
  To: Thomas Monjalon, Richardson, Bruce
  Cc: dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo, azelezniak

Hi Thoms

> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Friday, September 23, 2016 2:15 PM
> To: Richardson, Bruce <bruce.richardson@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>
> Cc: dev@dpdk.org; Jerin Jacob <jerin.jacob@caviumnetworks.com>; Shah,
> Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> azelezniak <alexz@att.com>
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-23 09:53, Richardson, Bruce:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-09-23 10:20, Bruce Richardson:
> > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > > > It can be generic(PF/VF) function indexed only through
> > > port_id.
> > > > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD, We
> > > > > > > > > are not exposing a separate port_id for PF. We only
> > > > > > > > > enumerate 0..N VFs as 0..N ethdev port_id
> > > > > > > >
> > > > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > > > >
> > > > > > > > The following librte_ether functions already work in a
> > > > > > > > similar
> > > way:
> > > > > > > >
> > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
> > > > > > > > uint16_t rx_mode, uint8_t on)
> > > > > > > >
> > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf,
> > > > > > > > uint8_t
> > > > > > > > on)
> > > > > > > >
> > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf,
> > > > > > > > uint8_t
> > > > > > > > on)
> > > > > > > >
> > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t
> > > > > > > > vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > >
> > > > > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > > > > Are we sure there is no other way?
> > > > > > > I mean we just need to know the VF with a port ID.
> > > > > >
> > > > > > When the VF is used in a VM the port ID of the VF is not
> > > > > > visible to
> > > the PF.
> > > > > > I don't think there is another way to do this.
> > > > >
> > > > > I don't understand why we could not assign a port id to the VF
> > > > > from the host instead of having the couple PF port id / VF id.
> > > > > Can we enumerate all the VFs associated to a PF?
> > > > > Then can we allocate them a port id in the array rte_eth_devices?
> > > >
> > > > Hi Thomas,
> > > >
> > > > The VF is not a port visible to DPDK, though, so it shouldn't have
> > > > a port id IMHO. DPDK can't actually do anything with it.
> > >
> > > You say the contrary below.
> >
> > Well, yes and no. The driver can manipulate things for the VF, but DPDK
> doesn't actually have a device that corresponds to the VF. There are no PCI
> bar mappings for it, DPDK can't do RX and TX with it etc.?
> 
> Very good point.
> There are only few ethdev functions which are supported by every drivers,
> like Rx/Tx and would not be available for VF from PF interface.
> 
> > > > The PCI device for the VF is likely passed through to a different
> > > > VM and being used there. Unfortunately, the VF still needs certain
> > > > things done for it by the PF, so if the PF is under DPDK control,
> > > > it needs to provide the functionality to assist the VF.
> > >
> > > Why not have a VF_from_PF driver which does the mailbox things?
> > > So you can manage the VF from the PF with a simple port id.
> > > It really seems to be the cleanest design to me.
> >
> > While I see your point, and it could work, I just want to be sure that we are
> ok with the results of that. Suppose we do create ethdevs for the VFs
> controlled by the PF. Does the new VF get counted in the
> rte_eth_dev_count() value (I assume yes)? How are apps meant to use the
> port? Do they have to put in a special case when iterating through all the port
> ids to check that it's not a pseudo port that can't do anything. None of the
> standard ethdev calls from an app will work on it, you can't configure nb rx/tx
> queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
> 
> Yes these devices would be special because their supported API would be
> quite different. I was thinking that in the future you could add most of the
> configuration functions through the VF mailbox.
> But the Intel mailbox currently support only some special configurations
> which are not supported by other devices even its own VF device (except
> setting MAC address).
> And when I read "set drop enable bit in the VF split rx control register", it
> becomes clear it is really specific and has nothing to do in the generic ethdev
> API.
> That's why it is a NACK.
> 
> When we want to use these very specific features we are aware of the
> underlying device and driver. So we can directly include a header from the
> driver. I suggest to retrieve a handler for the device which is not a port id and
> will allow to call ixgbe functions directly.
> It could be achieved by adding an ethdev function like discussed here:
> 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> 

I have been reading the net/vhost mail thread above. The following quote is from this thread.

"It means I would be in favor of introducing API in drivers for very specific features."

At present all the PMD functions are accessed through the eth_dev_ops structure, there are no PMD API's.

Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver ioctl API) which can be accessed through a generic API in the ethdev?

What will this generic API look like?

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23 17:02                       ` Iremonger, Bernard
@ 2016-09-23 17:18                         ` Thomas Monjalon
  2016-09-26 15:37                           ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-23 17:18 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: dev, Richardson, Bruce, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

2016-09-23 17:02, Iremonger, Bernard:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-09-23 09:53, Richardson, Bruce:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > > > > It can be generic(PF/VF) function indexed only through
> > > > port_id.
> > > > > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD, We
> > > > > > > > > > are not exposing a separate port_id for PF. We only
> > > > > > > > > > enumerate 0..N VFs as 0..N ethdev port_id
> > > > > > > > >
> > > > > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > > > > >
> > > > > > > > > The following librte_ether functions already work in a
> > > > > > > > > similar
> > > > way:
> > > > > > > > >
> > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
> > > > > > > > > uint16_t rx_mode, uint8_t on)
> > > > > > > > >
> > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf,
> > > > > > > > > uint8_t
> > > > > > > > > on)
> > > > > > > > >
> > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf,
> > > > > > > > > uint8_t
> > > > > > > > > on)
> > > > > > > > >
> > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t
> > > > > > > > > vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > >
> > > > > > > > I have a bad feeling with these functions dedicated to VF from PF.
> > > > > > > > Are we sure there is no other way?
> > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > >
> > > > > > > When the VF is used in a VM the port ID of the VF is not
> > > > > > > visible to
> > > > the PF.
> > > > > > > I don't think there is another way to do this.
> > > > > >
> > > > > > I don't understand why we could not assign a port id to the VF
> > > > > > from the host instead of having the couple PF port id / VF id.
> > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > Then can we allocate them a port id in the array rte_eth_devices?
> > > > >
> > > > > Hi Thomas,
> > > > >
> > > > > The VF is not a port visible to DPDK, though, so it shouldn't have
> > > > > a port id IMHO. DPDK can't actually do anything with it.
> > > >
> > > > You say the contrary below.
> > >
> > > Well, yes and no. The driver can manipulate things for the VF, but DPDK
> > doesn't actually have a device that corresponds to the VF. There are no PCI
> > bar mappings for it, DPDK can't do RX and TX with it etc.?
> > 
> > Very good point.
> > There are only few ethdev functions which are supported by every drivers,
> > like Rx/Tx and would not be available for VF from PF interface.
> > 
> > > > > The PCI device for the VF is likely passed through to a different
> > > > > VM and being used there. Unfortunately, the VF still needs certain
> > > > > things done for it by the PF, so if the PF is under DPDK control,
> > > > > it needs to provide the functionality to assist the VF.
> > > >
> > > > Why not have a VF_from_PF driver which does the mailbox things?
> > > > So you can manage the VF from the PF with a simple port id.
> > > > It really seems to be the cleanest design to me.
> > >
> > > While I see your point, and it could work, I just want to be sure that we are
> > ok with the results of that. Suppose we do create ethdevs for the VFs
> > controlled by the PF. Does the new VF get counted in the
> > rte_eth_dev_count() value (I assume yes)? How are apps meant to use the
> > port? Do they have to put in a special case when iterating through all the port
> > ids to check that it's not a pseudo port that can't do anything. None of the
> > standard ethdev calls from an app will work on it, you can't configure nb rx/tx
> > queues on it, you can't start or stop it, you can't do rx or tx on it, etc, etc.
> > 
> > Yes these devices would be special because their supported API would be
> > quite different. I was thinking that in the future you could add most of the
> > configuration functions through the VF mailbox.
> > But the Intel mailbox currently support only some special configurations
> > which are not supported by other devices even its own VF device (except
> > setting MAC address).
> > And when I read "set drop enable bit in the VF split rx control register", it
> > becomes clear it is really specific and has nothing to do in the generic ethdev
> > API.
> > That's why it is a NACK.
> > 
> > When we want to use these very specific features we are aware of the
> > underlying device and driver. So we can directly include a header from the
> > driver. I suggest to retrieve a handler for the device which is not a port id and
> > will allow to call ixgbe functions directly.
> > It could be achieved by adding an ethdev function like discussed here:
> > 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> > 
> 
> I have been reading the net/vhost mail thread above. The following quote is from this thread.
> 
> "It means I would be in favor of introducing API in drivers for very specific features."
> 
> At present all the PMD functions are accessed through the eth_dev_ops structure, there are no PMD API's.
> 
> Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver ioctl API) which can be accessed through a generic API in the ethdev?

Not exactly. I'm thinking about a PMD specific API.
The only ethdev API you need would be a function to retrieve a handler
(an opaque pointer on the device struct) from the port id.
Then you can include rte_ixgbe.h and directly call the specific ixgbe
function, passing the device handler.
How does it sound?

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-23 17:18                         ` Thomas Monjalon
@ 2016-09-26 15:37                           ` Iremonger, Bernard
  2016-09-26 16:59                             ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-26 15:37 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Richardson, Bruce, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

Hi Thomas, Bruce,

<snip>

> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-23 17:02, Iremonger, Bernard:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-09-23 09:53, Richardson, Bruce:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > > > > > It can be generic(PF/VF) function indexed only
> > > > > > > > > > > through
> > > > > port_id.
> > > > > > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD,
> > > > > > > > > > > We are not exposing a separate port_id for PF. We
> > > > > > > > > > > only enumerate 0..N VFs as 0..N ethdev port_id
> > > > > > > > > >
> > > > > > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > > > > > >
> > > > > > > > > > The following librte_ether functions already work in a
> > > > > > > > > > similar
> > > > > way:
> > > > > > > > > >
> > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t
> > > > > > > > > > vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > >
> > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf,
> > > > > > > > > > uint8_t
> > > > > > > > > > on)
> > > > > > > > > >
> > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf,
> > > > > > > > > > uint8_t
> > > > > > > > > > on)
> > > > > > > > > >
> > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > > > > > > > > > uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > > >
> > > > > > > > > I have a bad feeling with these functions dedicated to VF from
> PF.
> > > > > > > > > Are we sure there is no other way?
> > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > >
> > > > > > > > When the VF is used in a VM the port ID of the VF is not
> > > > > > > > visible to
> > > > > the PF.
> > > > > > > > I don't think there is another way to do this.
> > > > > > >
> > > > > > > I don't understand why we could not assign a port id to the
> > > > > > > VF from the host instead of having the couple PF port id / VF id.
> > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > Then can we allocate them a port id in the array rte_eth_devices?
> > > > > >
> > > > > > Hi Thomas,
> > > > > >
> > > > > > The VF is not a port visible to DPDK, though, so it shouldn't
> > > > > > have a port id IMHO. DPDK can't actually do anything with it.
> > > > >
> > > > > You say the contrary below.
> > > >
> > > > Well, yes and no. The driver can manipulate things for the VF, but
> > > > DPDK
> > > doesn't actually have a device that corresponds to the VF. There are
> > > no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
> > >
> > > Very good point.
> > > There are only few ethdev functions which are supported by every
> > > drivers, like Rx/Tx and would not be available for VF from PF interface.
> > >
> > > > > > The PCI device for the VF is likely passed through to a
> > > > > > different VM and being used there. Unfortunately, the VF still
> > > > > > needs certain things done for it by the PF, so if the PF is
> > > > > > under DPDK control, it needs to provide the functionality to assist
> the VF.
> > > > >
> > > > > Why not have a VF_from_PF driver which does the mailbox things?
> > > > > So you can manage the VF from the PF with a simple port id.
> > > > > It really seems to be the cleanest design to me.
> > > >
> > > > While I see your point, and it could work, I just want to be sure
> > > > that we are
> > > ok with the results of that. Suppose we do create ethdevs for the
> > > VFs controlled by the PF. Does the new VF get counted in the
> > > rte_eth_dev_count() value (I assume yes)? How are apps meant to use
> > > the port? Do they have to put in a special case when iterating
> > > through all the port ids to check that it's not a pseudo port that
> > > can't do anything. None of the standard ethdev calls from an app
> > > will work on it, you can't configure nb rx/tx queues on it, you can't start or
> stop it, you can't do rx or tx on it, etc, etc.
> > >
> > > Yes these devices would be special because their supported API would
> > > be quite different. I was thinking that in the future you could add
> > > most of the configuration functions through the VF mailbox.
> > > But the Intel mailbox currently support only some special
> > > configurations which are not supported by other devices even its own
> > > VF device (except setting MAC address).
> > > And when I read "set drop enable bit in the VF split rx control
> > > register", it becomes clear it is really specific and has nothing to
> > > do in the generic ethdev API.
> > > That's why it is a NACK.
> > >
> > > When we want to use these very specific features we are aware of the
> > > underlying device and driver. So we can directly include a header
> > > from the driver. I suggest to retrieve a handler for the device
> > > which is not a port id and will allow to call ixgbe functions directly.
> > > It could be achieved by adding an ethdev function like discussed here:
> > > 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> > >
> >
> > I have been reading the net/vhost mail thread above. The following quote
> is from this thread.
> >
> > "It means I would be in favor of introducing API in drivers for very specific
> features."
> >
> > At present all the PMD functions are accessed through the eth_dev_ops
> structure, there are no PMD API's.
> >
> > Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver
> ioctl API) which can be accessed through a generic API in the ethdev?
> 
> Not exactly. I'm thinking about a PMD specific API.
> The only ethdev API you need would be a function to retrieve a handler (an
> opaque pointer on the device struct) from the port id.
> Then you can include rte_ixgbe.h and directly call the specific ixgbe function,
> passing the device handler.
> How does it sound?

I have been prototyping this proposed solution, it appears to work.

I have added the following function:

int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);

The pmd_handle is a pointer to a dev_ops structure containing driver specific functions.

Using the pmd_handle the driver specific functions can be called (without having them in struct eth_dev_ops)

Has this proposal been superseded by the discussion on the following patch?

[PATCH] net/vhost: Add function to retreive the 'vid' for a given port id

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-26 15:37                           ` Iremonger, Bernard
@ 2016-09-26 16:59                             ` Thomas Monjalon
  2016-09-27 10:31                               ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-26 16:59 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: dev, Richardson, Bruce, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

2016-09-26 15:37, Iremonger, Bernard:
> Hi Thomas, Bruce,
> 
> <snip>
> 
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> > management
> > 
> > 2016-09-23 17:02, Iremonger, Bernard:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon wrote:
> > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > Do we really need to expose VF specific functions here?
> > > > > > > > > > > > It can be generic(PF/VF) function indexed only
> > > > > > > > > > > > through
> > > > > > port_id.
> > > > > > > > > > > > (example: as rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx PMD,
> > > > > > > > > > > > We are not exposing a separate port_id for PF. We
> > > > > > > > > > > > only enumerate 0..N VFs as 0..N ethdev port_id
> > > > > > > > > > >
> > > > > > > > > > > Our intention with this patch is to control the VF from the PF.
> > > > > > > > > > >
> > > > > > > > > > > The following librte_ether functions already work in a
> > > > > > > > > > > similar
> > > > > > way:
> > > > > > > > > > >
> > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t
> > > > > > > > > > > vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > >
> > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf,
> > > > > > > > > > > uint8_t
> > > > > > > > > > > on)
> > > > > > > > > > >
> > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf,
> > > > > > > > > > > uint8_t
> > > > > > > > > > > on)
> > > > > > > > > > >
> > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > > > > > > > > > > uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > > > >
> > > > > > > > > > I have a bad feeling with these functions dedicated to VF from
> > PF.
> > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > >
> > > > > > > > > When the VF is used in a VM the port ID of the VF is not
> > > > > > > > > visible to
> > > > > > the PF.
> > > > > > > > > I don't think there is another way to do this.
> > > > > > > >
> > > > > > > > I don't understand why we could not assign a port id to the
> > > > > > > > VF from the host instead of having the couple PF port id / VF id.
> > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > Then can we allocate them a port id in the array rte_eth_devices?
> > > > > > >
> > > > > > > Hi Thomas,
> > > > > > >
> > > > > > > The VF is not a port visible to DPDK, though, so it shouldn't
> > > > > > > have a port id IMHO. DPDK can't actually do anything with it.
> > > > > >
> > > > > > You say the contrary below.
> > > > >
> > > > > Well, yes and no. The driver can manipulate things for the VF, but
> > > > > DPDK
> > > > doesn't actually have a device that corresponds to the VF. There are
> > > > no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
> > > >
> > > > Very good point.
> > > > There are only few ethdev functions which are supported by every
> > > > drivers, like Rx/Tx and would not be available for VF from PF interface.
> > > >
> > > > > > > The PCI device for the VF is likely passed through to a
> > > > > > > different VM and being used there. Unfortunately, the VF still
> > > > > > > needs certain things done for it by the PF, so if the PF is
> > > > > > > under DPDK control, it needs to provide the functionality to assist
> > the VF.
> > > > > >
> > > > > > Why not have a VF_from_PF driver which does the mailbox things?
> > > > > > So you can manage the VF from the PF with a simple port id.
> > > > > > It really seems to be the cleanest design to me.
> > > > >
> > > > > While I see your point, and it could work, I just want to be sure
> > > > > that we are
> > > > ok with the results of that. Suppose we do create ethdevs for the
> > > > VFs controlled by the PF. Does the new VF get counted in the
> > > > rte_eth_dev_count() value (I assume yes)? How are apps meant to use
> > > > the port? Do they have to put in a special case when iterating
> > > > through all the port ids to check that it's not a pseudo port that
> > > > can't do anything. None of the standard ethdev calls from an app
> > > > will work on it, you can't configure nb rx/tx queues on it, you can't start or
> > stop it, you can't do rx or tx on it, etc, etc.
> > > >
> > > > Yes these devices would be special because their supported API would
> > > > be quite different. I was thinking that in the future you could add
> > > > most of the configuration functions through the VF mailbox.
> > > > But the Intel mailbox currently support only some special
> > > > configurations which are not supported by other devices even its own
> > > > VF device (except setting MAC address).
> > > > And when I read "set drop enable bit in the VF split rx control
> > > > register", it becomes clear it is really specific and has nothing to
> > > > do in the generic ethdev API.
> > > > That's why it is a NACK.
> > > >
> > > > When we want to use these very specific features we are aware of the
> > > > underlying device and driver. So we can directly include a header
> > > > from the driver. I suggest to retrieve a handler for the device
> > > > which is not a port id and will allow to call ixgbe functions directly.
> > > > It could be achieved by adding an ethdev function like discussed here:
> > > > 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> > > >
> > >
> > > I have been reading the net/vhost mail thread above. The following quote
> > is from this thread.
> > >
> > > "It means I would be in favor of introducing API in drivers for very specific
> > features."
> > >
> > > At present all the PMD functions are accessed through the eth_dev_ops
> > structure, there are no PMD API's.
> > >
> > > Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a driver
> > ioctl API) which can be accessed through a generic API in the ethdev?
> > 
> > Not exactly. I'm thinking about a PMD specific API.
> > The only ethdev API you need would be a function to retrieve a handler (an
> > opaque pointer on the device struct) from the port id.
> > Then you can include rte_ixgbe.h and directly call the specific ixgbe function,
> > passing the device handler.
> > How does it sound?
> 
> I have been prototyping this proposed solution, it appears to work.
> 
> I have added the following function:
> 
> int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
> 
> The pmd_handle is a pointer to a dev_ops structure containing driver specific functions.
> 
> Using the pmd_handle the driver specific functions can be called (without having them in struct eth_dev_ops)
> 
> Has this proposal been superseded by the discussion on the following patch?
> 
> [PATCH] net/vhost: Add function to retreive the 'vid' for a given port id

Maybe, it can be superseded by this discussion, yes.
Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
What is your opinion about using port_id directly and retrieving the
structs from the driver via rte_eth_devices?

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-26 16:59                             ` Thomas Monjalon
@ 2016-09-27 10:31                               ` Iremonger, Bernard
  2016-09-27 13:01                                 ` Bruce Richardson
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-27 10:31 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Richardson, Bruce, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

Hi Thomas, Bruce,

<snip>

> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-26 15:37, Iremonger, Bernard:
> > Hi Thomas, Bruce,
> >
> > <snip>
> >
> > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's
> > > for VF management
> > >
> > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon
> wrote:
> > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > Do we really need to expose VF specific functions
> here?
> > > > > > > > > > > > > It can be generic(PF/VF) function indexed only
> > > > > > > > > > > > > through
> > > > > > > port_id.
> > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx
> > > > > > > > > > > > > PMD, We are not exposing a separate port_id for
> > > > > > > > > > > > > PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > > > > > > > > > > port_id
> > > > > > > > > > > >
> > > > > > > > > > > > Our intention with this patch is to control the VF from the
> PF.
> > > > > > > > > > > >
> > > > > > > > > > > > The following librte_ether functions already work
> > > > > > > > > > > > in a similar
> > > > > > > way:
> > > > > > > > > > > >
> > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > >
> > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t
> > > > > > > > > > > > vf, uint8_t
> > > > > > > > > > > > on)
> > > > > > > > > > > >
> > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t
> > > > > > > > > > > > vf, uint8_t
> > > > > > > > > > > > on)
> > > > > > > > > > > >
> > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > > > > > > > > > > > uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > > > > >
> > > > > > > > > > > I have a bad feeling with these functions dedicated
> > > > > > > > > > > to VF from
> > > PF.
> > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > > >
> > > > > > > > > > When the VF is used in a VM the port ID of the VF is
> > > > > > > > > > not visible to
> > > > > > > the PF.
> > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > >
> > > > > > > > > I don't understand why we could not assign a port id to
> > > > > > > > > the VF from the host instead of having the couple PF port id /
> VF id.
> > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > Then can we allocate them a port id in the array
> rte_eth_devices?
> > > > > > > >
> > > > > > > > Hi Thomas,
> > > > > > > >
> > > > > > > > The VF is not a port visible to DPDK, though, so it
> > > > > > > > shouldn't have a port id IMHO. DPDK can't actually do anything
> with it.
> > > > > > >
> > > > > > > You say the contrary below.
> > > > > >
> > > > > > Well, yes and no. The driver can manipulate things for the VF,
> > > > > > but DPDK
> > > > > doesn't actually have a device that corresponds to the VF. There
> > > > > are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
> > > > >
> > > > > Very good point.
> > > > > There are only few ethdev functions which are supported by every
> > > > > drivers, like Rx/Tx and would not be available for VF from PF
> interface.
> > > > >
> > > > > > > > The PCI device for the VF is likely passed through to a
> > > > > > > > different VM and being used there. Unfortunately, the VF
> > > > > > > > still needs certain things done for it by the PF, so if
> > > > > > > > the PF is under DPDK control, it needs to provide the
> > > > > > > > functionality to assist
> > > the VF.
> > > > > > >
> > > > > > > Why not have a VF_from_PF driver which does the mailbox
> things?
> > > > > > > So you can manage the VF from the PF with a simple port id.
> > > > > > > It really seems to be the cleanest design to me.
> > > > > >
> > > > > > While I see your point, and it could work, I just want to be
> > > > > > sure that we are
> > > > > ok with the results of that. Suppose we do create ethdevs for
> > > > > the VFs controlled by the PF. Does the new VF get counted in the
> > > > > rte_eth_dev_count() value (I assume yes)? How are apps meant to
> > > > > use the port? Do they have to put in a special case when
> > > > > iterating through all the port ids to check that it's not a
> > > > > pseudo port that can't do anything. None of the standard ethdev
> > > > > calls from an app will work on it, you can't configure nb rx/tx
> > > > > queues on it, you can't start or
> > > stop it, you can't do rx or tx on it, etc, etc.
> > > > >
> > > > > Yes these devices would be special because their supported API
> > > > > would be quite different. I was thinking that in the future you
> > > > > could add most of the configuration functions through the VF
> mailbox.
> > > > > But the Intel mailbox currently support only some special
> > > > > configurations which are not supported by other devices even its
> > > > > own VF device (except setting MAC address).
> > > > > And when I read "set drop enable bit in the VF split rx control
> > > > > register", it becomes clear it is really specific and has
> > > > > nothing to do in the generic ethdev API.
> > > > > That's why it is a NACK.
> > > > >
> > > > > When we want to use these very specific features we are aware of
> > > > > the underlying device and driver. So we can directly include a
> > > > > header from the driver. I suggest to retrieve a handler for the
> > > > > device which is not a port id and will allow to call ixgbe functions
> directly.
> > > > > It could be achieved by adding an ethdev function like discussed here:
> > > > > 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> > > > >
> > > >
> > > > I have been reading the net/vhost mail thread above. The following
> > > > quote
> > > is from this thread.
> > > >
> > > > "It means I would be in favor of introducing API in drivers for
> > > > very specific
> > > features."
> > > >
> > > > At present all the PMD functions are accessed through the
> > > > eth_dev_ops
> > > structure, there are no PMD API's.
> > > >
> > > > Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a
> > > > driver
> > > ioctl API) which can be accessed through a generic API in the ethdev?
> > >
> > > Not exactly. I'm thinking about a PMD specific API.
> > > The only ethdev API you need would be a function to retrieve a
> > > handler (an opaque pointer on the device struct) from the port id.
> > > Then you can include rte_ixgbe.h and directly call the specific
> > > ixgbe function, passing the device handler.
> > > How does it sound?
> >
> > I have been prototyping this proposed solution, it appears to work.
> >
> > I have added the following function:
> >
> > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
> >
> > The pmd_handle is a pointer to a dev_ops structure containing driver
> specific functions.
> >
> > Using the pmd_handle the driver specific functions can be called
> > (without having them in struct eth_dev_ops)
> >
> > Has this proposal been superseded by the discussion on the following
> patch?
> >
> > [PATCH] net/vhost: Add function to retreive the 'vid' for a given port
> > id
> 
> Maybe, it can be superseded by this discussion, yes.
> Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> What is your opinion about using port_id directly and retrieving the structs
> from the driver via rte_eth_devices?

Looking at the code in rte_eth_devices[]

struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];

struct rte_eth_dev {

...

const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */ 

...

 void *pmd_ops;  /** < exported PMD specific functions */ 
  
}

The PMD functions are only accessible at present if they are in struct eth_dev_ops.

Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions accessible and is a simpler solution than using rte_eth_dev_get_pmd_handle() to get access to the PMD functions.

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-27 10:31                               ` Iremonger, Bernard
@ 2016-09-27 13:01                                 ` Bruce Richardson
  2016-09-27 14:13                                   ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Bruce Richardson @ 2016-09-27 13:01 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: Thomas Monjalon, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

On Tue, Sep 27, 2016 at 11:31:06AM +0100, Iremonger, Bernard wrote:
> Hi Thomas, Bruce,
> 
> <snip>
> 
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> > management
> > 
> > 2016-09-26 15:37, Iremonger, Bernard:
> > > Hi Thomas, Bruce,
> > >
> > > <snip>
> > >
> > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's
> > > > for VF management
> > > >
> > > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas Monjalon
> > wrote:
> > > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > > Do we really need to expose VF specific functions
> > here?
> > > > > > > > > > > > > > It can be generic(PF/VF) function indexed only
> > > > > > > > > > > > > > through
> > > > > > > > port_id.
> > > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > > port_id, uint8_t on)) For instance, In Thunderx
> > > > > > > > > > > > > > PMD, We are not exposing a separate port_id for
> > > > > > > > > > > > > > PF. We only enumerate 0..N VFs as 0..N ethdev
> > > > > > > > > > > > > > port_id
> > > > > > > > > > > > >
> > > > > > > > > > > > > Our intention with this patch is to control the VF from the
> > PF.
> > > > > > > > > > > > >
> > > > > > > > > > > > > The following librte_ether functions already work
> > > > > > > > > > > > > in a similar
> > > > > > > > way:
> > > > > > > > > > > > >
> > > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > > >
> > > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t
> > > > > > > > > > > > > vf, uint8_t
> > > > > > > > > > > > > on)
> > > > > > > > > > > > >
> > > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t
> > > > > > > > > > > > > vf, uint8_t
> > > > > > > > > > > > > on)
> > > > > > > > > > > > >
> > > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > > > > > > > > > > > > uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > > > > > >
> > > > > > > > > > > > I have a bad feeling with these functions dedicated
> > > > > > > > > > > > to VF from
> > > > PF.
> > > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > > > >
> > > > > > > > > > > When the VF is used in a VM the port ID of the VF is
> > > > > > > > > > > not visible to
> > > > > > > > the PF.
> > > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > > >
> > > > > > > > > > I don't understand why we could not assign a port id to
> > > > > > > > > > the VF from the host instead of having the couple PF port id /
> > VF id.
> > > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > > Then can we allocate them a port id in the array
> > rte_eth_devices?
> > > > > > > > >
> > > > > > > > > Hi Thomas,
> > > > > > > > >
> > > > > > > > > The VF is not a port visible to DPDK, though, so it
> > > > > > > > > shouldn't have a port id IMHO. DPDK can't actually do anything
> > with it.
> > > > > > > >
> > > > > > > > You say the contrary below.
> > > > > > >
> > > > > > > Well, yes and no. The driver can manipulate things for the VF,
> > > > > > > but DPDK
> > > > > > doesn't actually have a device that corresponds to the VF. There
> > > > > > are no PCI bar mappings for it, DPDK can't do RX and TX with it etc.?
> > > > > >
> > > > > > Very good point.
> > > > > > There are only few ethdev functions which are supported by every
> > > > > > drivers, like Rx/Tx and would not be available for VF from PF
> > interface.
> > > > > >
> > > > > > > > > The PCI device for the VF is likely passed through to a
> > > > > > > > > different VM and being used there. Unfortunately, the VF
> > > > > > > > > still needs certain things done for it by the PF, so if
> > > > > > > > > the PF is under DPDK control, it needs to provide the
> > > > > > > > > functionality to assist
> > > > the VF.
> > > > > > > >
> > > > > > > > Why not have a VF_from_PF driver which does the mailbox
> > things?
> > > > > > > > So you can manage the VF from the PF with a simple port id.
> > > > > > > > It really seems to be the cleanest design to me.
> > > > > > >
> > > > > > > While I see your point, and it could work, I just want to be
> > > > > > > sure that we are
> > > > > > ok with the results of that. Suppose we do create ethdevs for
> > > > > > the VFs controlled by the PF. Does the new VF get counted in the
> > > > > > rte_eth_dev_count() value (I assume yes)? How are apps meant to
> > > > > > use the port? Do they have to put in a special case when
> > > > > > iterating through all the port ids to check that it's not a
> > > > > > pseudo port that can't do anything. None of the standard ethdev
> > > > > > calls from an app will work on it, you can't configure nb rx/tx
> > > > > > queues on it, you can't start or
> > > > stop it, you can't do rx or tx on it, etc, etc.
> > > > > >
> > > > > > Yes these devices would be special because their supported API
> > > > > > would be quite different. I was thinking that in the future you
> > > > > > could add most of the configuration functions through the VF
> > mailbox.
> > > > > > But the Intel mailbox currently support only some special
> > > > > > configurations which are not supported by other devices even its
> > > > > > own VF device (except setting MAC address).
> > > > > > And when I read "set drop enable bit in the VF split rx control
> > > > > > register", it becomes clear it is really specific and has
> > > > > > nothing to do in the generic ethdev API.
> > > > > > That's why it is a NACK.
> > > > > >
> > > > > > When we want to use these very specific features we are aware of
> > > > > > the underlying device and driver. So we can directly include a
> > > > > > header from the driver. I suggest to retrieve a handler for the
> > > > > > device which is not a port id and will allow to call ixgbe functions
> > directly.
> > > > > > It could be achieved by adding an ethdev function like discussed here:
> > > > > > 	http://dpdk.org/ml/archives/dev/2016-September/047392.html
> > > > > >
> > > > >
> > > > > I have been reading the net/vhost mail thread above. The following
> > > > > quote
> > > > is from this thread.
> > > > >
> > > > > "It means I would be in favor of introducing API in drivers for
> > > > > very specific
> > > > features."
> > > > >
> > > > > At present all the PMD functions are accessed through the
> > > > > eth_dev_ops
> > > > structure, there are no PMD API's.
> > > > >
> > > > > Is your proposal to add API(s) to the DPDK ixgbe PMD (similar to a
> > > > > driver
> > > > ioctl API) which can be accessed through a generic API in the ethdev?
> > > >
> > > > Not exactly. I'm thinking about a PMD specific API.
> > > > The only ethdev API you need would be a function to retrieve a
> > > > handler (an opaque pointer on the device struct) from the port id.
> > > > Then you can include rte_ixgbe.h and directly call the specific
> > > > ixgbe function, passing the device handler.
> > > > How does it sound?
> > >
> > > I have been prototyping this proposed solution, it appears to work.
> > >
> > > I have added the following function:
> > >
> > > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void** pmd_handle);
> > >
> > > The pmd_handle is a pointer to a dev_ops structure containing driver
> > specific functions.
> > >
> > > Using the pmd_handle the driver specific functions can be called
> > > (without having them in struct eth_dev_ops)
> > >
> > > Has this proposal been superseded by the discussion on the following
> > patch?
> > >
> > > [PATCH] net/vhost: Add function to retreive the 'vid' for a given port
> > > id
> > 
> > Maybe, it can be superseded by this discussion, yes.
> > Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> > What is your opinion about using port_id directly and retrieving the structs
> > from the driver via rte_eth_devices?
> 
> Looking at the code in rte_eth_devices[]
> 
> struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];
> 
> struct rte_eth_dev {
> 
> ...
> 
> const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */ 
> 
> ...
> 
>  void *pmd_ops;  /** < exported PMD specific functions */ 
>   
> }
> 
> The PMD functions are only accessible at present if they are in struct eth_dev_ops.
> 
> Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions accessible and is a simpler solution than using rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
> 
> Regards,
> 

Why would an ops structure be needed? If it's a private API for a driver, there
should be no need for function pointers, and instead the driver can define
regular functions in it's header file, no?

/Bruce

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-27 13:01                                 ` Bruce Richardson
@ 2016-09-27 14:13                                   ` Iremonger, Bernard
  2016-09-28 11:23                                     ` Ananyev, Konstantin
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-27 14:13 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: Thomas Monjalon, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

Hi Bruce,

<snip>

> > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add
> > > > > API's for VF management
> > > > >
> > > > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
> > > > > > > > > > Monjalon
> > > wrote:
> > > > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > > > Do we really need to expose VF specific
> > > > > > > > > > > > > > > functions
> > > here?
> > > > > > > > > > > > > > > It can be generic(PF/VF) function indexed
> > > > > > > > > > > > > > > only through
> > > > > > > > > port_id.
> > > > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > > > port_id, uint8_t on)) For instance, In
> > > > > > > > > > > > > > > Thunderx PMD, We are not exposing a separate
> > > > > > > > > > > > > > > port_id for PF. We only enumerate 0..N VFs
> > > > > > > > > > > > > > > as 0..N ethdev port_id
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Our intention with this patch is to control
> > > > > > > > > > > > > > the VF from the
> > > PF.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > The following librte_ether functions already
> > > > > > > > > > > > > > work in a similar
> > > > > > > > > way:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id,
> > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > on)
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id,
> > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > on)
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t port_id,
> > > > > > > > > > > > > > uint16_t vf, uint16_t tx_rate, uint64_t q_msk)
> > > > > > > > > > > > >
> > > > > > > > > > > > > I have a bad feeling with these functions
> > > > > > > > > > > > > dedicated to VF from
> > > > > PF.
> > > > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > > > > >
> > > > > > > > > > > > When the VF is used in a VM the port ID of the VF
> > > > > > > > > > > > is not visible to
> > > > > > > > > the PF.
> > > > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > > > >
> > > > > > > > > > > I don't understand why we could not assign a port id
> > > > > > > > > > > to the VF from the host instead of having the couple
> > > > > > > > > > > PF port id /
> > > VF id.
> > > > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > > > Then can we allocate them a port id in the array
> > > rte_eth_devices?
> > > > > > > > > >
> > > > > > > > > > Hi Thomas,
> > > > > > > > > >
> > > > > > > > > > The VF is not a port visible to DPDK, though, so it
> > > > > > > > > > shouldn't have a port id IMHO. DPDK can't actually do
> > > > > > > > > > anything
> > > with it.
> > > > > > > > >
> > > > > > > > > You say the contrary below.
> > > > > > > >
> > > > > > > > Well, yes and no. The driver can manipulate things for the
> > > > > > > > VF, but DPDK
> > > > > > > doesn't actually have a device that corresponds to the VF.
> > > > > > > There are no PCI bar mappings for it, DPDK can't do RX and TX with
> it etc.?
> > > > > > >
> > > > > > > Very good point.
> > > > > > > There are only few ethdev functions which are supported by
> > > > > > > every drivers, like Rx/Tx and would not be available for VF
> > > > > > > from PF
> > > interface.
> > > > > > >
> > > > > > > > > > The PCI device for the VF is likely passed through to
> > > > > > > > > > a different VM and being used there. Unfortunately,
> > > > > > > > > > the VF still needs certain things done for it by the
> > > > > > > > > > PF, so if the PF is under DPDK control, it needs to
> > > > > > > > > > provide the functionality to assist
> > > > > the VF.
> > > > > > > > >
> > > > > > > > > Why not have a VF_from_PF driver which does the mailbox
> > > things?
> > > > > > > > > So you can manage the VF from the PF with a simple port id.
> > > > > > > > > It really seems to be the cleanest design to me.
> > > > > > > >
> > > > > > > > While I see your point, and it could work, I just want to
> > > > > > > > be sure that we are
> > > > > > > ok with the results of that. Suppose we do create ethdevs
> > > > > > > for the VFs controlled by the PF. Does the new VF get
> > > > > > > counted in the
> > > > > > > rte_eth_dev_count() value (I assume yes)? How are apps meant
> > > > > > > to use the port? Do they have to put in a special case when
> > > > > > > iterating through all the port ids to check that it's not a
> > > > > > > pseudo port that can't do anything. None of the standard
> > > > > > > ethdev calls from an app will work on it, you can't
> > > > > > > configure nb rx/tx queues on it, you can't start or
> > > > > stop it, you can't do rx or tx on it, etc, etc.
> > > > > > >
> > > > > > > Yes these devices would be special because their supported
> > > > > > > API would be quite different. I was thinking that in the
> > > > > > > future you could add most of the configuration functions
> > > > > > > through the VF
> > > mailbox.
> > > > > > > But the Intel mailbox currently support only some special
> > > > > > > configurations which are not supported by other devices even
> > > > > > > its own VF device (except setting MAC address).
> > > > > > > And when I read "set drop enable bit in the VF split rx
> > > > > > > control register", it becomes clear it is really specific
> > > > > > > and has nothing to do in the generic ethdev API.
> > > > > > > That's why it is a NACK.
> > > > > > >
> > > > > > > When we want to use these very specific features we are
> > > > > > > aware of the underlying device and driver. So we can
> > > > > > > directly include a header from the driver. I suggest to
> > > > > > > retrieve a handler for the device which is not a port id and
> > > > > > > will allow to call ixgbe functions
> > > directly.
> > > > > > > It could be achieved by adding an ethdev function like discussed
> here:
> > > > > > > 	http://dpdk.org/ml/archives/dev/2016-
> September/047392.html
> > > > > > >
> > > > > >
> > > > > > I have been reading the net/vhost mail thread above. The
> > > > > > following quote
> > > > > is from this thread.
> > > > > >
> > > > > > "It means I would be in favor of introducing API in drivers
> > > > > > for very specific
> > > > > features."
> > > > > >
> > > > > > At present all the PMD functions are accessed through the
> > > > > > eth_dev_ops
> > > > > structure, there are no PMD API's.
> > > > > >
> > > > > > Is your proposal to add API(s) to the DPDK ixgbe PMD (similar
> > > > > > to a driver
> > > > > ioctl API) which can be accessed through a generic API in the ethdev?
> > > > >
> > > > > Not exactly. I'm thinking about a PMD specific API.
> > > > > The only ethdev API you need would be a function to retrieve a
> > > > > handler (an opaque pointer on the device struct) from the port id.
> > > > > Then you can include rte_ixgbe.h and directly call the specific
> > > > > ixgbe function, passing the device handler.
> > > > > How does it sound?
> > > >
> > > > I have been prototyping this proposed solution, it appears to work.
> > > >
> > > > I have added the following function:
> > > >
> > > > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
> > > > pmd_handle);
> > > >
> > > > The pmd_handle is a pointer to a dev_ops structure containing
> > > > driver
> > > specific functions.
> > > >
> > > > Using the pmd_handle the driver specific functions can be called
> > > > (without having them in struct eth_dev_ops)
> > > >
> > > > Has this proposal been superseded by the discussion on the
> > > > following
> > > patch?
> > > >
> > > > [PATCH] net/vhost: Add function to retreive the 'vid' for a given
> > > > port id
> > >
> > > Maybe, it can be superseded by this discussion, yes.
> > > Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> > > What is your opinion about using port_id directly and retrieving the
> > > structs from the driver via rte_eth_devices?
> >
> > Looking at the code in rte_eth_devices[]
> >
> > struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];
> >
> > struct rte_eth_dev {
> >
> > ...
> >
> > const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
> >
> > ...
> >
> >  void *pmd_ops;  /** < exported PMD specific functions */
> >
> > }
> >
> > The PMD functions are only accessible at present if they are in struct
> eth_dev_ops.
> >
> > Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD functions
> accessible and is a simpler solution than using
> rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
> >
> > Regards,
> >
> 
> Why would an ops structure be needed? If it's a private API for a driver,
> there should be no need for function pointers, and instead the driver can
> define regular functions in it's header file, no?
> 
> /Bruce

The driver functions were static, I have made them public and added them to the rte_pmd_ixgbe.h file, and it works.  These functions will also need to be added to the rte_pmd_ixgbe_version.map file, previously there were no public functions.

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-27 14:13                                   ` Iremonger, Bernard
@ 2016-09-28 11:23                                     ` Ananyev, Konstantin
  2016-09-28 12:31                                       ` Iremonger, Bernard
                                                         ` (2 more replies)
  0 siblings, 3 replies; 94+ messages in thread
From: Ananyev, Konstantin @ 2016-09-28 11:23 UTC (permalink / raw)
  To: Iremonger, Bernard, Richardson, Bruce
  Cc: Thomas Monjalon, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

Hi lads,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger, Bernard
> Sent: Tuesday, September 27, 2016 3:13 PM
> To: Richardson, Bruce <bruce.richardson@intel.com>
> Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; dev@dpdk.org; Jerin Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul
> R <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>; azelezniak <alexz@att.com>
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
> 
> Hi Bruce,
> 
> <snip>
> 
> > > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add
> > > > > > API's for VF management
> > > > > >
> > > > > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
> > > > > > > > > > > Monjalon
> > > > wrote:
> > > > > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > > > > Do we really need to expose VF specific
> > > > > > > > > > > > > > > > functions
> > > > here?
> > > > > > > > > > > > > > > > It can be generic(PF/VF) function indexed
> > > > > > > > > > > > > > > > only through
> > > > > > > > > > port_id.
> > > > > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > > > > port_id, uint8_t on)) For instance, In
> > > > > > > > > > > > > > > > Thunderx PMD, We are not exposing a
> > > > > > > > > > > > > > > > separate port_id for PF. We only enumerate
> > > > > > > > > > > > > > > > 0..N VFs as 0..N ethdev port_id
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Our intention with this patch is to control
> > > > > > > > > > > > > > > the VF from the
> > > > PF.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > The following librte_ether functions already
> > > > > > > > > > > > > > > work in a similar
> > > > > > > > > > way:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id,
> > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id,
> > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t
> > > > > > > > > > > > > > > port_id, uint16_t vf, uint16_t tx_rate,
> > > > > > > > > > > > > > > uint64_t q_msk)
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I have a bad feeling with these functions
> > > > > > > > > > > > > > dedicated to VF from
> > > > > > PF.
> > > > > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > > > > > >
> > > > > > > > > > > > > When the VF is used in a VM the port ID of the
> > > > > > > > > > > > > VF is not visible to
> > > > > > > > > > the PF.
> > > > > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > > > > >
> > > > > > > > > > > > I don't understand why we could not assign a port
> > > > > > > > > > > > id to the VF from the host instead of having the
> > > > > > > > > > > > couple PF port id /
> > > > VF id.
> > > > > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > > > > Then can we allocate them a port id in the array
> > > > rte_eth_devices?
> > > > > > > > > > >
> > > > > > > > > > > Hi Thomas,
> > > > > > > > > > >
> > > > > > > > > > > The VF is not a port visible to DPDK, though, so it
> > > > > > > > > > > shouldn't have a port id IMHO. DPDK can't actually
> > > > > > > > > > > do anything
> > > > with it.
> > > > > > > > > >
> > > > > > > > > > You say the contrary below.
> > > > > > > > >
> > > > > > > > > Well, yes and no. The driver can manipulate things for
> > > > > > > > > the VF, but DPDK
> > > > > > > > doesn't actually have a device that corresponds to the VF.
> > > > > > > > There are no PCI bar mappings for it, DPDK can't do RX and
> > > > > > > > TX with
> > it etc.?
> > > > > > > >
> > > > > > > > Very good point.
> > > > > > > > There are only few ethdev functions which are supported by
> > > > > > > > every drivers, like Rx/Tx and would not be available for
> > > > > > > > VF from PF
> > > > interface.
> > > > > > > >
> > > > > > > > > > > The PCI device for the VF is likely passed through
> > > > > > > > > > > to a different VM and being used there.
> > > > > > > > > > > Unfortunately, the VF still needs certain things
> > > > > > > > > > > done for it by the PF, so if the PF is under DPDK
> > > > > > > > > > > control, it needs to provide the functionality to
> > > > > > > > > > > assist
> > > > > > the VF.
> > > > > > > > > >
> > > > > > > > > > Why not have a VF_from_PF driver which does the
> > > > > > > > > > mailbox
> > > > things?
> > > > > > > > > > So you can manage the VF from the PF with a simple port id.
> > > > > > > > > > It really seems to be the cleanest design to me.
> > > > > > > > >
> > > > > > > > > While I see your point, and it could work, I just want
> > > > > > > > > to be sure that we are
> > > > > > > > ok with the results of that. Suppose we do create ethdevs
> > > > > > > > for the VFs controlled by the PF. Does the new VF get
> > > > > > > > counted in the
> > > > > > > > rte_eth_dev_count() value (I assume yes)? How are apps
> > > > > > > > meant to use the port? Do they have to put in a special
> > > > > > > > case when iterating through all the port ids to check that
> > > > > > > > it's not a pseudo port that can't do anything. None of the
> > > > > > > > standard ethdev calls from an app will work on it, you
> > > > > > > > can't configure nb rx/tx queues on it, you can't start or
> > > > > > stop it, you can't do rx or tx on it, etc, etc.
> > > > > > > >
> > > > > > > > Yes these devices would be special because their supported
> > > > > > > > API would be quite different. I was thinking that in the
> > > > > > > > future you could add most of the configuration functions
> > > > > > > > through the VF
> > > > mailbox.
> > > > > > > > But the Intel mailbox currently support only some special
> > > > > > > > configurations which are not supported by other devices
> > > > > > > > even its own VF device (except setting MAC address).
> > > > > > > > And when I read "set drop enable bit in the VF split rx
> > > > > > > > control register", it becomes clear it is really specific
> > > > > > > > and has nothing to do in the generic ethdev API.
> > > > > > > > That's why it is a NACK.
> > > > > > > >
> > > > > > > > When we want to use these very specific features we are
> > > > > > > > aware of the underlying device and driver. So we can
> > > > > > > > directly include a header from the driver. I suggest to
> > > > > > > > retrieve a handler for the device which is not a port id
> > > > > > > > and will allow to call ixgbe functions
> > > > directly.
> > > > > > > > It could be achieved by adding an ethdev function like
> > > > > > > > discussed
> > here:
> > > > > > > > 	http://dpdk.org/ml/archives/dev/2016-
> > September/047392.html
> > > > > > > >
> > > > > > >
> > > > > > > I have been reading the net/vhost mail thread above. The
> > > > > > > following quote
> > > > > > is from this thread.
> > > > > > >
> > > > > > > "It means I would be in favor of introducing API in drivers
> > > > > > > for very specific
> > > > > > features."
> > > > > > >
> > > > > > > At present all the PMD functions are accessed through the
> > > > > > > eth_dev_ops
> > > > > > structure, there are no PMD API's.
> > > > > > >
> > > > > > > Is your proposal to add API(s) to the DPDK ixgbe PMD
> > > > > > > (similar to a driver
> > > > > > ioctl API) which can be accessed through a generic API in the ethdev?
> > > > > >
> > > > > > Not exactly. I'm thinking about a PMD specific API.
> > > > > > The only ethdev API you need would be a function to retrieve a
> > > > > > handler (an opaque pointer on the device struct) from the port id.
> > > > > > Then you can include rte_ixgbe.h and directly call the
> > > > > > specific ixgbe function, passing the device handler.
> > > > > > How does it sound?
> > > > >
> > > > > I have been prototyping this proposed solution, it appears to work.
> > > > >
> > > > > I have added the following function:
> > > > >
> > > > > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
> > > > > pmd_handle);
> > > > >
> > > > > The pmd_handle is a pointer to a dev_ops structure containing
> > > > > driver
> > > > specific functions.
> > > > >
> > > > > Using the pmd_handle the driver specific functions can be called
> > > > > (without having them in struct eth_dev_ops)
> > > > >
> > > > > Has this proposal been superseded by the discussion on the
> > > > > following
> > > > patch?
> > > > >
> > > > > [PATCH] net/vhost: Add function to retreive the 'vid' for a
> > > > > given port id
> > > >
> > > > Maybe, it can be superseded by this discussion, yes.
> > > > Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> > > > What is your opinion about using port_id directly and retrieving
> > > > the structs from the driver via rte_eth_devices?
> > >
> > > Looking at the code in rte_eth_devices[]
> > >
> > > struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];
> > >
> > > struct rte_eth_dev {
> > >
> > > ...
> > >
> > > const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
> > >
> > > ...
> > >
> > >  void *pmd_ops;  /** < exported PMD specific functions */
> > >
> > > }
> > >
> > > The PMD functions are only accessible at present if they are in
> > > struct
> > eth_dev_ops.
> > >
> > > Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
> > > functions
> > accessible and is a simpler solution than using
> > rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
> > >
> > > Regards,
> > >
> >
> > Why would an ops structure be needed? If it's a private API for a
> > driver, there should be no need for function pointers, and instead the
> > driver can define regular functions in it's header file, no?
> >
> > /Bruce
> 
> The driver functions were static, I have made them public and added them to the rte_pmd_ixgbe.h file, and it works.  These functions
> will also need to be added to the rte_pmd_ixgbe_version.map file, previously there were no public functions.

Sorry for being late in the discussion, but I have a question:
If we  this way (force user to include driver specific headers and call driver specific functions),
how you guys plan to make this functionality available for multiple driver types.
>From discussion with Bernard  understand that customers would need similar functionality for i40e.
Does it mean that they'll have to re-implement this part of their code again?
Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
Basically their own version of rte_ethdev?

Konstantin

> 
> Regards,
> 
> Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 11:23                                     ` Ananyev, Konstantin
@ 2016-09-28 12:31                                       ` Iremonger, Bernard
  2016-09-28 13:01                                       ` Richardson, Bruce
  2016-09-28 13:03                                       ` Thomas Monjalon
  2 siblings, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-28 12:31 UTC (permalink / raw)
  To: Ananyev, Konstantin, Richardson, Bruce
  Cc: Thomas Monjalon, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

Hi Bruce, Konstantin,

<snip>

> Subject: RE: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> Hi lads,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger,
> > Bernard
> > Sent: Tuesday, September 27, 2016 3:13 PM
> > To: Richardson, Bruce <bruce.richardson@intel.com>
> > Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; dev@dpdk.org;
> Jerin
> > Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul R
> > <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> > azelezniak <alexz@att.com>
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
> > VF management
> >
> > Hi Bruce,
> >
> > <snip>
> >
> > > > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add
> > > > > > > API's for VF management
> > > > > > >
> > > > > > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > > > > > From: Thomas Monjalon
> > > > > > > > > > [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
> > > > > > > > > > > > Monjalon
> > > > > wrote:
> > > > > > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > > > > > Do we really need to expose VF specific
> > > > > > > > > > > > > > > > > functions
> > > > > here?
> > > > > > > > > > > > > > > > > It can be generic(PF/VF) function
> > > > > > > > > > > > > > > > > indexed only through
> > > > > > > > > > > port_id.
> > > > > > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > > > > > port_id, uint8_t on)) For instance, In
> > > > > > > > > > > > > > > > > Thunderx PMD, We are not exposing a
> > > > > > > > > > > > > > > > > separate port_id for PF. We only
> > > > > > > > > > > > > > > > > enumerate 0..N VFs as 0..N ethdev
> > > > > > > > > > > > > > > > > port_id
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Our intention with this patch is to
> > > > > > > > > > > > > > > > control the VF from the
> > > > > PF.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > The following librte_ether functions
> > > > > > > > > > > > > > > > already work in a similar
> > > > > > > > > > > way:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t
> > > > > > > > > > > > > > > > port_id, uint16_t vf, uint16_t tx_rate,
> > > > > > > > > > > > > > > > uint64_t q_msk)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I have a bad feeling with these functions
> > > > > > > > > > > > > > > dedicated to VF from
> > > > > > > PF.
> > > > > > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > > > > > I mean we just need to know the VF with a port ID.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > When the VF is used in a VM the port ID of the
> > > > > > > > > > > > > > VF is not visible to
> > > > > > > > > > > the PF.
> > > > > > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > > > > > >
> > > > > > > > > > > > > I don't understand why we could not assign a
> > > > > > > > > > > > > port id to the VF from the host instead of
> > > > > > > > > > > > > having the couple PF port id /
> > > > > VF id.
> > > > > > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > > > > > Then can we allocate them a port id in the array
> > > > > rte_eth_devices?
> > > > > > > > > > > >
> > > > > > > > > > > > Hi Thomas,
> > > > > > > > > > > >
> > > > > > > > > > > > The VF is not a port visible to DPDK, though, so
> > > > > > > > > > > > it shouldn't have a port id IMHO. DPDK can't
> > > > > > > > > > > > actually do anything
> > > > > with it.
> > > > > > > > > > >
> > > > > > > > > > > You say the contrary below.
> > > > > > > > > >
> > > > > > > > > > Well, yes and no. The driver can manipulate things for
> > > > > > > > > > the VF, but DPDK
> > > > > > > > > doesn't actually have a device that corresponds to the VF.
> > > > > > > > > There are no PCI bar mappings for it, DPDK can't do RX
> > > > > > > > > and TX with
> > > it etc.?
> > > > > > > > >
> > > > > > > > > Very good point.
> > > > > > > > > There are only few ethdev functions which are supported
> > > > > > > > > by every drivers, like Rx/Tx and would not be available
> > > > > > > > > for VF from PF
> > > > > interface.
> > > > > > > > >
> > > > > > > > > > > > The PCI device for the VF is likely passed through
> > > > > > > > > > > > to a different VM and being used there.
> > > > > > > > > > > > Unfortunately, the VF still needs certain things
> > > > > > > > > > > > done for it by the PF, so if the PF is under DPDK
> > > > > > > > > > > > control, it needs to provide the functionality to
> > > > > > > > > > > > assist
> > > > > > > the VF.
> > > > > > > > > > >
> > > > > > > > > > > Why not have a VF_from_PF driver which does the
> > > > > > > > > > > mailbox
> > > > > things?
> > > > > > > > > > > So you can manage the VF from the PF with a simple port
> id.
> > > > > > > > > > > It really seems to be the cleanest design to me.
> > > > > > > > > >
> > > > > > > > > > While I see your point, and it could work, I just want
> > > > > > > > > > to be sure that we are
> > > > > > > > > ok with the results of that. Suppose we do create
> > > > > > > > > ethdevs for the VFs controlled by the PF. Does the new
> > > > > > > > > VF get counted in the
> > > > > > > > > rte_eth_dev_count() value (I assume yes)? How are apps
> > > > > > > > > meant to use the port? Do they have to put in a special
> > > > > > > > > case when iterating through all the port ids to check
> > > > > > > > > that it's not a pseudo port that can't do anything. None
> > > > > > > > > of the standard ethdev calls from an app will work on
> > > > > > > > > it, you can't configure nb rx/tx queues on it, you can't
> > > > > > > > > start or
> > > > > > > stop it, you can't do rx or tx on it, etc, etc.
> > > > > > > > >
> > > > > > > > > Yes these devices would be special because their
> > > > > > > > > supported API would be quite different. I was thinking
> > > > > > > > > that in the future you could add most of the
> > > > > > > > > configuration functions through the VF
> > > > > mailbox.
> > > > > > > > > But the Intel mailbox currently support only some
> > > > > > > > > special configurations which are not supported by other
> > > > > > > > > devices even its own VF device (except setting MAC address).
> > > > > > > > > And when I read "set drop enable bit in the VF split rx
> > > > > > > > > control register", it becomes clear it is really
> > > > > > > > > specific and has nothing to do in the generic ethdev API.
> > > > > > > > > That's why it is a NACK.
> > > > > > > > >
> > > > > > > > > When we want to use these very specific features we are
> > > > > > > > > aware of the underlying device and driver. So we can
> > > > > > > > > directly include a header from the driver. I suggest to
> > > > > > > > > retrieve a handler for the device which is not a port id
> > > > > > > > > and will allow to call ixgbe functions
> > > > > directly.
> > > > > > > > > It could be achieved by adding an ethdev function like
> > > > > > > > > discussed
> > > here:
> > > > > > > > > 	http://dpdk.org/ml/archives/dev/2016-
> > > September/047392.html
> > > > > > > > >
> > > > > > > >
> > > > > > > > I have been reading the net/vhost mail thread above. The
> > > > > > > > following quote
> > > > > > > is from this thread.
> > > > > > > >
> > > > > > > > "It means I would be in favor of introducing API in
> > > > > > > > drivers for very specific
> > > > > > > features."
> > > > > > > >
> > > > > > > > At present all the PMD functions are accessed through the
> > > > > > > > eth_dev_ops
> > > > > > > structure, there are no PMD API's.
> > > > > > > >
> > > > > > > > Is your proposal to add API(s) to the DPDK ixgbe PMD
> > > > > > > > (similar to a driver
> > > > > > > ioctl API) which can be accessed through a generic API in the
> ethdev?
> > > > > > >
> > > > > > > Not exactly. I'm thinking about a PMD specific API.
> > > > > > > The only ethdev API you need would be a function to retrieve
> > > > > > > a handler (an opaque pointer on the device struct) from the port
> id.
> > > > > > > Then you can include rte_ixgbe.h and directly call the
> > > > > > > specific ixgbe function, passing the device handler.
> > > > > > > How does it sound?
> > > > > >
> > > > > > I have been prototyping this proposed solution, it appears to work.
> > > > > >
> > > > > > I have added the following function:
> > > > > >
> > > > > > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
> > > > > > pmd_handle);
> > > > > >
> > > > > > The pmd_handle is a pointer to a dev_ops structure containing
> > > > > > driver
> > > > > specific functions.
> > > > > >
> > > > > > Using the pmd_handle the driver specific functions can be
> > > > > > called (without having them in struct eth_dev_ops)
> > > > > >
> > > > > > Has this proposal been superseded by the discussion on the
> > > > > > following
> > > > > patch?
> > > > > >
> > > > > > [PATCH] net/vhost: Add function to retreive the 'vid' for a
> > > > > > given port id
> > > > >
> > > > > Maybe, it can be superseded by this discussion, yes.
> > > > > Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> > > > > What is your opinion about using port_id directly and retrieving
> > > > > the structs from the driver via rte_eth_devices?
> > > >
> > > > Looking at the code in rte_eth_devices[]
> > > >
> > > > struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];
> > > >
> > > > struct rte_eth_dev {
> > > >
> > > > ...
> > > >
> > > > const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD
> > > > */
> > > >
> > > > ...
> > > >
> > > >  void *pmd_ops;  /** < exported PMD specific functions */
> > > >
> > > > }
> > > >
> > > > The PMD functions are only accessible at present if they are in
> > > > struct
> > > eth_dev_ops.
> > > >
> > > > Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
> > > > functions
> > > accessible and is a simpler solution than using
> > > rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
> > > >
> > > > Regards,
> > > >
> > >
> > > Why would an ops structure be needed? If it's a private API for a
> > > driver, there should be no need for function pointers, and instead
> > > the driver can define regular functions in it's header file, no?
> > >
> > > /Bruce
> >
> > The driver functions were static, I have made them public and added
> > them to the rte_pmd_ixgbe.h file, and it works.  These functions will also
> need to be added to the rte_pmd_ixgbe_version.map file, previously there
> were no public functions.
> 
> Sorry for being late in the discussion, but I have a question:
> If we  this way (force user to include driver specific headers and call driver
> specific functions), how you guys plan to make this functionality available for
> multiple driver types.
> From discussion with Bernard  understand that customers would need similar
> functionality for i40e.
> Does it mean that they'll have to re-implement this part of their code again?
> Or would have to create (and maintain) their own shim layer that would
> provide some s of abstraction?
> Basically their own version of rte_ethdev?
> 
> Konstantin

Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h. 

Regards,

Bernard.


 

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 11:23                                     ` Ananyev, Konstantin
  2016-09-28 12:31                                       ` Iremonger, Bernard
@ 2016-09-28 13:01                                       ` Richardson, Bruce
  2016-09-28 13:03                                       ` Thomas Monjalon
  2 siblings, 0 replies; 94+ messages in thread
From: Richardson, Bruce @ 2016-09-28 13:01 UTC (permalink / raw)
  To: Ananyev, Konstantin, Iremonger, Bernard
  Cc: Thomas Monjalon, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak



> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Wednesday, September 28, 2016 12:24 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>
> Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; dev@dpdk.org; Jerin Jacob
> <jerin.jacob@caviumnetworks.com>; Shah, Rahul R <rahul.r.shah@intel.com>;
> Lu, Wenzhuo <wenzhuo.lu@intel.com>; azelezniak <alexz@att.com>
> Subject: RE: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> Hi lads,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger,
> > Bernard
> > Sent: Tuesday, September 27, 2016 3:13 PM
> > To: Richardson, Bruce <bruce.richardson@intel.com>
> > Cc: Thomas Monjalon <thomas.monjalon@6wind.com>; dev@dpdk.org; Jerin
> > Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul R
> > <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> > azelezniak <alexz@att.com>
> > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
> > VF management
> >
> > Hi Bruce,
> >
> > <snip>
> >
> > > > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add
> > > > > > > API's for VF management
> > > > > > >
> > > > > > > 2016-09-23 17:02, Iremonger, Bernard:
> > > > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > 2016-09-23 09:53, Richardson, Bruce:
> > > > > > > > > > From: Thomas Monjalon
> > > > > > > > > > [mailto:thomas.monjalon@6wind.com]
> > > > > > > > > > > 2016-09-23 10:20, Bruce Richardson:
> > > > > > > > > > > > On Thu, Sep 22, 2016 at 07:04:37PM +0200, Thomas
> > > > > > > > > > > > Monjalon
> > > > > wrote:
> > > > > > > > > > > > > 2016-09-15 16:46, Iremonger, Bernard:
> > > > > > > > > > > > > > > > > Do we really need to expose VF specific
> > > > > > > > > > > > > > > > > functions
> > > > > here?
> > > > > > > > > > > > > > > > > It can be generic(PF/VF) function
> > > > > > > > > > > > > > > > > indexed only through
> > > > > > > > > > > port_id.
> > > > > > > > > > > > > > > > > (example: as
> > > > > > > > > > > > > > > > > rte_eth_dev_set_vlan_anti_spoof(uint8_t
> > > > > > > > > > > > > > > > > port_id, uint8_t on)) For instance, In
> > > > > > > > > > > > > > > > > Thunderx PMD, We are not exposing a
> > > > > > > > > > > > > > > > > separate port_id for PF. We only
> > > > > > > > > > > > > > > > > enumerate 0..N VFs as 0..N ethdev
> > > > > > > > > > > > > > > > > port_id
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Our intention with this patch is to
> > > > > > > > > > > > > > > > control the VF from the
> > > > > PF.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > The following librte_ether functions
> > > > > > > > > > > > > > > > already work in a similar
> > > > > > > > > > > way:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_rxmode(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint16_t rx_mode, uint8_t on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_rx(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > rte_eth_dev_set_vf_tx(uint8_t port_id,
> > > > > > > > > > > > > > > > uint16_t vf, uint8_t
> > > > > > > > > > > > > > > > on)
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > int rte_eth_set_vf_rate_limit(uint8_t
> > > > > > > > > > > > > > > > port_id, uint16_t vf, uint16_t tx_rate,
> > > > > > > > > > > > > > > > uint64_t q_msk)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I have a bad feeling with these functions
> > > > > > > > > > > > > > > dedicated to VF from
> > > > > > > PF.
> > > > > > > > > > > > > > > Are we sure there is no other way?
> > > > > > > > > > > > > > > I mean we just need to know the VF with a port
> ID.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > When the VF is used in a VM the port ID of the
> > > > > > > > > > > > > > VF is not visible to
> > > > > > > > > > > the PF.
> > > > > > > > > > > > > > I don't think there is another way to do this.
> > > > > > > > > > > > >
> > > > > > > > > > > > > I don't understand why we could not assign a
> > > > > > > > > > > > > port id to the VF from the host instead of
> > > > > > > > > > > > > having the couple PF port id /
> > > > > VF id.
> > > > > > > > > > > > > Can we enumerate all the VFs associated to a PF?
> > > > > > > > > > > > > Then can we allocate them a port id in the array
> > > > > rte_eth_devices?
> > > > > > > > > > > >
> > > > > > > > > > > > Hi Thomas,
> > > > > > > > > > > >
> > > > > > > > > > > > The VF is not a port visible to DPDK, though, so
> > > > > > > > > > > > it shouldn't have a port id IMHO. DPDK can't
> > > > > > > > > > > > actually do anything
> > > > > with it.
> > > > > > > > > > >
> > > > > > > > > > > You say the contrary below.
> > > > > > > > > >
> > > > > > > > > > Well, yes and no. The driver can manipulate things for
> > > > > > > > > > the VF, but DPDK
> > > > > > > > > doesn't actually have a device that corresponds to the VF.
> > > > > > > > > There are no PCI bar mappings for it, DPDK can't do RX
> > > > > > > > > and TX with
> > > it etc.?
> > > > > > > > >
> > > > > > > > > Very good point.
> > > > > > > > > There are only few ethdev functions which are supported
> > > > > > > > > by every drivers, like Rx/Tx and would not be available
> > > > > > > > > for VF from PF
> > > > > interface.
> > > > > > > > >
> > > > > > > > > > > > The PCI device for the VF is likely passed through
> > > > > > > > > > > > to a different VM and being used there.
> > > > > > > > > > > > Unfortunately, the VF still needs certain things
> > > > > > > > > > > > done for it by the PF, so if the PF is under DPDK
> > > > > > > > > > > > control, it needs to provide the functionality to
> > > > > > > > > > > > assist
> > > > > > > the VF.
> > > > > > > > > > >
> > > > > > > > > > > Why not have a VF_from_PF driver which does the
> > > > > > > > > > > mailbox
> > > > > things?
> > > > > > > > > > > So you can manage the VF from the PF with a simple
> port id.
> > > > > > > > > > > It really seems to be the cleanest design to me.
> > > > > > > > > >
> > > > > > > > > > While I see your point, and it could work, I just want
> > > > > > > > > > to be sure that we are
> > > > > > > > > ok with the results of that. Suppose we do create
> > > > > > > > > ethdevs for the VFs controlled by the PF. Does the new
> > > > > > > > > VF get counted in the
> > > > > > > > > rte_eth_dev_count() value (I assume yes)? How are apps
> > > > > > > > > meant to use the port? Do they have to put in a special
> > > > > > > > > case when iterating through all the port ids to check
> > > > > > > > > that it's not a pseudo port that can't do anything. None
> > > > > > > > > of the standard ethdev calls from an app will work on
> > > > > > > > > it, you can't configure nb rx/tx queues on it, you can't
> > > > > > > > > start or
> > > > > > > stop it, you can't do rx or tx on it, etc, etc.
> > > > > > > > >
> > > > > > > > > Yes these devices would be special because their
> > > > > > > > > supported API would be quite different. I was thinking
> > > > > > > > > that in the future you could add most of the
> > > > > > > > > configuration functions through the VF
> > > > > mailbox.
> > > > > > > > > But the Intel mailbox currently support only some
> > > > > > > > > special configurations which are not supported by other
> > > > > > > > > devices even its own VF device (except setting MAC
> address).
> > > > > > > > > And when I read "set drop enable bit in the VF split rx
> > > > > > > > > control register", it becomes clear it is really
> > > > > > > > > specific and has nothing to do in the generic ethdev API.
> > > > > > > > > That's why it is a NACK.
> > > > > > > > >
> > > > > > > > > When we want to use these very specific features we are
> > > > > > > > > aware of the underlying device and driver. So we can
> > > > > > > > > directly include a header from the driver. I suggest to
> > > > > > > > > retrieve a handler for the device which is not a port id
> > > > > > > > > and will allow to call ixgbe functions
> > > > > directly.
> > > > > > > > > It could be achieved by adding an ethdev function like
> > > > > > > > > discussed
> > > here:
> > > > > > > > > 	http://dpdk.org/ml/archives/dev/2016-
> > > September/047392.html
> > > > > > > > >
> > > > > > > >
> > > > > > > > I have been reading the net/vhost mail thread above. The
> > > > > > > > following quote
> > > > > > > is from this thread.
> > > > > > > >
> > > > > > > > "It means I would be in favor of introducing API in
> > > > > > > > drivers for very specific
> > > > > > > features."
> > > > > > > >
> > > > > > > > At present all the PMD functions are accessed through the
> > > > > > > > eth_dev_ops
> > > > > > > structure, there are no PMD API's.
> > > > > > > >
> > > > > > > > Is your proposal to add API(s) to the DPDK ixgbe PMD
> > > > > > > > (similar to a driver
> > > > > > > ioctl API) which can be accessed through a generic API in the
> ethdev?
> > > > > > >
> > > > > > > Not exactly. I'm thinking about a PMD specific API.
> > > > > > > The only ethdev API you need would be a function to retrieve
> > > > > > > a handler (an opaque pointer on the device struct) from the
> port id.
> > > > > > > Then you can include rte_ixgbe.h and directly call the
> > > > > > > specific ixgbe function, passing the device handler.
> > > > > > > How does it sound?
> > > > > >
> > > > > > I have been prototyping this proposed solution, it appears to
> work.
> > > > > >
> > > > > > I have added the following function:
> > > > > >
> > > > > > int  rte_eth_dev_get_pmd_handle(uint8_t port_id, void**
> > > > > > pmd_handle);
> > > > > >
> > > > > > The pmd_handle is a pointer to a dev_ops structure containing
> > > > > > driver
> > > > > specific functions.
> > > > > >
> > > > > > Using the pmd_handle the driver specific functions can be
> > > > > > called (without having them in struct eth_dev_ops)
> > > > > >
> > > > > > Has this proposal been superseded by the discussion on the
> > > > > > following
> > > > > patch?
> > > > > >
> > > > > > [PATCH] net/vhost: Add function to retreive the 'vid' for a
> > > > > > given port id
> > > > >
> > > > > Maybe, it can be superseded by this discussion, yes.
> > > > > Bruce thinks we do not need rte_eth_dev_get_pmd_handle().
> > > > > What is your opinion about using port_id directly and retrieving
> > > > > the structs from the driver via rte_eth_devices?
> > > >
> > > > Looking at the code in rte_eth_devices[]
> > > >
> > > > struct rte_eth_dev  rte_eth_devices[RTE_MAX_ETHPORTS];
> > > >
> > > > struct rte_eth_dev {
> > > >
> > > > ...
> > > >
> > > > const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD
> > > > */
> > > >
> > > > ...
> > > >
> > > >  void *pmd_ops;  /** < exported PMD specific functions */
> > > >
> > > > }
> > > >
> > > > The PMD functions are only accessible at present if they are in
> > > > struct
> > > eth_dev_ops.
> > > >
> > > > Adding a pmd_ops field to struct rte_eth_dev {} makes the PMD
> > > > functions
> > > accessible and is a simpler solution than using
> > > rte_eth_dev_get_pmd_handle() to get access to the PMD functions.
> > > >
> > > > Regards,
> > > >
> > >
> > > Why would an ops structure be needed? If it's a private API for a
> > > driver, there should be no need for function pointers, and instead
> > > the driver can define regular functions in it's header file, no?
> > >
> > > /Bruce
> >
> > The driver functions were static, I have made them public and added
> > them to the rte_pmd_ixgbe.h file, and it works.  These functions will
> also need to be added to the rte_pmd_ixgbe_version.map file, previously
> there were no public functions.
> 
> Sorry for being late in the discussion, but I have a question:
> If we  this way (force user to include driver specific headers and call
> driver specific functions), how you guys plan to make this functionality
> available for multiple driver types.
> From discussion with Bernard  understand that customers would need similar
> functionality for i40e.
> Does it mean that they'll have to re-implement this part of their code
> again?
> Or would have to create (and maintain) their own shim layer that would
> provide some s of abstraction?
> Basically their own version of rte_ethdev?
> 
> Konstantin

Yes, it's a problem. However, the concern right now is that this functionality is not generic across NICs, and will only be implemented for ixgbe and i40e. If it turns out to be implemented for a significant subset of DPDK PMDs, e.g. 4 or 5 drivers from at least two vendors, then I would expect the case to be made to "promote" this functionality to ethdev.

Does this sound reasonable. Any other thoughts?

/Bruce

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 11:23                                     ` Ananyev, Konstantin
  2016-09-28 12:31                                       ` Iremonger, Bernard
  2016-09-28 13:01                                       ` Richardson, Bruce
@ 2016-09-28 13:03                                       ` Thomas Monjalon
  2016-09-28 13:26                                         ` Ananyev, Konstantin
  2 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-28 13:03 UTC (permalink / raw)
  To: Ananyev, Konstantin
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

2016-09-28 11:23, Ananyev, Konstantin:
> If we  this way (force user to include driver specific headers and call driver specific functions),
> how you guys plan to make this functionality available for multiple driver types.

Multiple drivers won't have exactly the same specific features.
But yes, there are some things common to several Intel NICs.

> From discussion with Bernard  understand that customers would need similar functionality for i40e.
> Does it mean that they'll have to re-implement this part of their code again?
> Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> Basically their own version of rte_ethdev?

No definitive answer.
But we can argue the contrary: how to handle a generic API which is implemented
only in 1 or 2 drivers? If the application tries to use it, we can imagine
that a specific range of hardware is expected.

I think it is an important question.
Previously we had the issue of having some API which are too specific
and need a rework to be used with other NICs. In order to avoid such
rework and API break, we can try to make them available in a driver-specific
or vendor-specific staging area, waiting for a later generalization.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 13:03                                       ` Thomas Monjalon
@ 2016-09-28 13:26                                         ` Ananyev, Konstantin
  2016-09-28 14:24                                           ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Ananyev, Konstantin @ 2016-09-28 13:26 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, September 28, 2016 2:03 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; dev@dpdk.org; Jerin
> Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> azelezniak <alexz@att.com>
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
> 
> 2016-09-28 11:23, Ananyev, Konstantin:
> > If we  this way (force user to include driver specific headers and
> > call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> 
> Multiple drivers won't have exactly the same specific features.
> But yes, there are some things common to several Intel NICs.
> 
> > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > Does it mean that they'll have to re-implement this part of their code again?
> > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > Basically their own version of rte_ethdev?
> 
> No definitive answer.
> But we can argue the contrary: how to handle a generic API which is implemented only in 1 or 2 drivers? If the application tries to use
> it, we can imagine that a specific range of hardware is expected.

Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.

> 
> I think it is an important question.
> Previously we had the issue of having some API which are too specific and need a rework to be used with other NICs. In order to avoid
> such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for a later
> generalization.

Could you remind me why you guys were that opposed to ioctl style approach?
It is not my favorite thing either, but it seems pretty generic way to handle such situations.

Konstantin
 

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 13:26                                         ` Ananyev, Konstantin
@ 2016-09-28 14:24                                           ` Thomas Monjalon
  2016-09-28 14:30                                             ` Ananyev, Konstantin
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-28 14:24 UTC (permalink / raw)
  To: Ananyev, Konstantin
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

2016-09-28 13:26, Ananyev, Konstantin:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-09-28 11:23, Ananyev, Konstantin:
> > > If we  this way (force user to include driver specific headers and
> > > call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > 
> > Multiple drivers won't have exactly the same specific features.
> > But yes, there are some things common to several Intel NICs.
> > 
> > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > Does it mean that they'll have to re-implement this part of their code again?
> > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > Basically their own version of rte_ethdev?
> > 
> > No definitive answer.
> > But we can argue the contrary: how to handle a generic API which is implemented only in 1 or 2 drivers? If the application tries to use
> > it, we can imagine that a specific range of hardware is expected.
> 
> Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
> 
> > 
> > I think it is an important question.
> > Previously we had the issue of having some API which are too specific and need a rework to be used with other NICs. In order to avoid
> > such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for a later
> > generalization.
> 
> Could you remind me why you guys were that opposed to ioctl style approach?
> It is not my favorite thing either, but it seems pretty generic way to handle such situations.

We prefer having well-defined functions instead of opaque ioctl-style encoding.
And it was not clear what is the benefit of ioctl.
Now I think I understand you would like to have a common ioctl service for
features available on 2 drivers. Right? Example (trying to read your mind):
	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>);
instead of
	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
	rte_pmd_i40e_vf_ping(port_id, vf_id);
Please confirm I understand what you are thinking about.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 14:24                                           ` Thomas Monjalon
@ 2016-09-28 14:30                                             ` Ananyev, Konstantin
  2016-09-28 14:48                                               ` Iremonger, Bernard
  2016-09-28 14:59                                               ` Thomas Monjalon
  0 siblings, 2 replies; 94+ messages in thread
From: Ananyev, Konstantin @ 2016-09-28 14:30 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Wednesday, September 28, 2016 3:24 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; dev@dpdk.org; Jerin
> Jacob <jerin.jacob@caviumnetworks.com>; Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> azelezniak <alexz@att.com>
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF management
> 
> 2016-09-28 13:26, Ananyev, Konstantin:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > If we  this way (force user to include driver specific headers and
> > > > call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > >
> > > Multiple drivers won't have exactly the same specific features.
> > > But yes, there are some things common to several Intel NICs.
> > >
> > > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > > Does it mean that they'll have to re-implement this part of their code again?
> > > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > > Basically their own version of rte_ethdev?
> > >
> > > No definitive answer.
> > > But we can argue the contrary: how to handle a generic API which is
> > > implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is expected.
> >
> > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> > Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
> >
> > >
> > > I think it is an important question.
> > > Previously we had the issue of having some API which are too
> > > specific and need a rework to be used with other NICs. In order to
> > > avoid such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for
> a later generalization.
> >
> > Could you remind me why you guys were that opposed to ioctl style approach?
> > It is not my favorite thing either, but it seems pretty generic way to handle such situations.
> 
> We prefer having well-defined functions instead of opaque ioctl-style encoding.
> And it was not clear what is the benefit of ioctl.
> Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?

Yes.

> Example (trying to  read your mind):
> 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
> 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> 	rte_pmd_i40e_vf_ping(port_id, vf_id);
> Please confirm I understand what you are thinking about.

Yep, you read my mind correctly :)
Konstantin

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 14:30                                             ` Ananyev, Konstantin
@ 2016-09-28 14:48                                               ` Iremonger, Bernard
  2016-09-28 15:00                                                 ` Thomas Monjalon
  2016-09-28 14:59                                               ` Thomas Monjalon
  1 sibling, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-28 14:48 UTC (permalink / raw)
  To: Ananyev, Konstantin, Thomas Monjalon
  Cc: Richardson, Bruce, dev, Jerin Jacob, Shah, Rahul R, Lu, Wenzhuo,
	azelezniak

<snip>

> > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
> > VF management
> >
> > 2016-09-28 13:26, Ananyev, Konstantin:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > If we  this way (force user to include driver specific headers
> > > > > and call driver specific functions), how you guys plan to make this
> functionality available for multiple driver types.
> > > >
> > > > Multiple drivers won't have exactly the same specific features.
> > > > But yes, there are some things common to several Intel NICs.
> > > >
> > > > > From discussion with Bernard  understand that customers would
> need similar functionality for i40e.
> > > > > Does it mean that they'll have to re-implement this part of their code
> again?
> > > > > Or would have to create (and maintain) their own shim layer that
> would provide some s of abstraction?
> > > > > Basically their own version of rte_ethdev?
> > > >
> > > > No definitive answer.
> > > > But we can argue the contrary: how to handle a generic API which
> > > > is implemented only in 1 or 2 drivers? If the application tries to use it,
> we can imagine that a specific range of hardware is expected.
> > >
> > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs
> for now, but different models/drivers).
> > > Obviously users would like to have an ability to run their app on all HW
> from this subset without rebuilding/implementing the app.
> > >
> > > >
> > > > I think it is an important question.
> > > > Previously we had the issue of having some API which are too
> > > > specific and need a rework to be used with other NICs. In order to
> > > > avoid such rework and API break, we can try to make them available
> > > > in a driver-specific or vendor-specific staging area, waiting for
> > a later generalization.
> > >
> > > Could you remind me why you guys were that opposed to ioctl style
> approach?
> > > It is not my favorite thing either, but it seems pretty generic way to
> handle such situations.
> >
> > We prefer having well-defined functions instead of opaque ioctl-style
> encoding.
> > And it was not clear what is the benefit of ioctl.
> > Now I think I understand you would like to have a common ioctl service for
> features available on 2 drivers. Right?
> 
> Yes.
> 
> > Example (trying to  read your mind):
> > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
> id>); instead of
> > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > what you are thinking about.
> 
> Yep, you read my mind correctly :)
> Konstantin
> 
Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h.
Would this be an acceptable solution?

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 14:30                                             ` Ananyev, Konstantin
  2016-09-28 14:48                                               ` Iremonger, Bernard
@ 2016-09-28 14:59                                               ` Thomas Monjalon
  2016-09-28 16:52                                                 ` Ananyev, Konstantin
  1 sibling, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-28 14:59 UTC (permalink / raw)
  To: Ananyev, Konstantin
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

2016-09-28 14:30, Ananyev, Konstantin:
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > 2016-09-28 13:26, Ananyev, Konstantin:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > If we  this way (force user to include driver specific headers and
> > > > > call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > > >
> > > > Multiple drivers won't have exactly the same specific features.
> > > > But yes, there are some things common to several Intel NICs.
> > > >
> > > > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > > > Does it mean that they'll have to re-implement this part of their code again?
> > > > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > > > Basically their own version of rte_ethdev?
> > > >
> > > > No definitive answer.
> > > > But we can argue the contrary: how to handle a generic API which is
> > > > implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is expected.
> > >
> > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> > > Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the app.
> > >
> > > >
> > > > I think it is an important question.
> > > > Previously we had the issue of having some API which are too
> > > > specific and need a rework to be used with other NICs. In order to
> > > > avoid such rework and API break, we can try to make them available in a driver-specific or vendor-specific staging area, waiting for
> > a later generalization.
> > >
> > > Could you remind me why you guys were that opposed to ioctl style approach?
> > > It is not my favorite thing either, but it seems pretty generic way to handle such situations.
> > 
> > We prefer having well-defined functions instead of opaque ioctl-style encoding.
> > And it was not clear what is the benefit of ioctl.
> > Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
> 
> Yes.
> 
> > Example (trying to  read your mind):
> > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
> > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > 	rte_pmd_i40e_vf_ping(port_id, vf_id);
> > Please confirm I understand what you are thinking about.
> 
> Yep, you read my mind correctly :)

Both could coexist (if ioctl was accepted by community).
What about starting to implement the PMD functions and postpone
ioctl to later with a dedicated thread?

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 14:48                                               ` Iremonger, Bernard
@ 2016-09-28 15:00                                                 ` Thomas Monjalon
  2016-09-28 15:24                                                   ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-28 15:00 UTC (permalink / raw)
  To: Iremonger, Bernard
  Cc: dev, Ananyev, Konstantin, Richardson, Bruce, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

2016-09-28 14:48, Iremonger, Bernard:
> <snip>
> 
> > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for
> > > VF management
> > >
> > > 2016-09-28 13:26, Ananyev, Konstantin:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > > If we  this way (force user to include driver specific headers
> > > > > > and call driver specific functions), how you guys plan to make this
> > functionality available for multiple driver types.
> > > > >
> > > > > Multiple drivers won't have exactly the same specific features.
> > > > > But yes, there are some things common to several Intel NICs.
> > > > >
> > > > > > From discussion with Bernard  understand that customers would
> > need similar functionality for i40e.
> > > > > > Does it mean that they'll have to re-implement this part of their code
> > again?
> > > > > > Or would have to create (and maintain) their own shim layer that
> > would provide some s of abstraction?
> > > > > > Basically their own version of rte_ethdev?
> > > > >
> > > > > No definitive answer.
> > > > > But we can argue the contrary: how to handle a generic API which
> > > > > is implemented only in 1 or 2 drivers? If the application tries to use it,
> > we can imagine that a specific range of hardware is expected.
> > > >
> > > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs
> > for now, but different models/drivers).
> > > > Obviously users would like to have an ability to run their app on all HW
> > from this subset without rebuilding/implementing the app.
> > > >
> > > > >
> > > > > I think it is an important question.
> > > > > Previously we had the issue of having some API which are too
> > > > > specific and need a rework to be used with other NICs. In order to
> > > > > avoid such rework and API break, we can try to make them available
> > > > > in a driver-specific or vendor-specific staging area, waiting for
> > > a later generalization.
> > > >
> > > > Could you remind me why you guys were that opposed to ioctl style
> > approach?
> > > > It is not my favorite thing either, but it seems pretty generic way to
> > handle such situations.
> > >
> > > We prefer having well-defined functions instead of opaque ioctl-style
> > encoding.
> > > And it was not clear what is the benefit of ioctl.
> > > Now I think I understand you would like to have a common ioctl service for
> > features available on 2 drivers. Right?
> > 
> > Yes.
> > 
> > > Example (trying to  read your mind):
> > > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
> > id>); instead of
> > > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > > what you are thinking about.
> > 
> > Yep, you read my mind correctly :)
> > Konstantin
> > 
> Adding the pmd_ops field to struct eth_devops {} discussed previously in this email thread will allow driver specific functions for multiple drivers and will get rid of the driver specific header file rte_pmd_driver.h.
> Would this be an acceptable solution?

How pmd_ops would be different of eth_devops?

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 15:00                                                 ` Thomas Monjalon
@ 2016-09-28 15:24                                                   ` Iremonger, Bernard
  0 siblings, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-28 15:24 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Ananyev, Konstantin, Richardson, Bruce, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

Hi Thomas,

<snip>

> -----Original Message-----
> Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's for VF
> management
> 
> 2016-09-28 14:48, Iremonger, Bernard:
> > <snip>
> >
> > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 3/5] librte_ether: add API's
> > > > for VF management
> > > >
> > > > 2016-09-28 13:26, Ananyev, Konstantin:
> > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > > > If we  this way (force user to include driver specific
> > > > > > > headers and call driver specific functions), how you guys
> > > > > > > plan to make this
> > > functionality available for multiple driver types.
> > > > > >
> > > > > > Multiple drivers won't have exactly the same specific features.
> > > > > > But yes, there are some things common to several Intel NICs.
> > > > > >
> > > > > > > From discussion with Bernard  understand that customers
> > > > > > > would
> > > need similar functionality for i40e.
> > > > > > > Does it mean that they'll have to re-implement this part of
> > > > > > > their code
> > > again?
> > > > > > > Or would have to create (and maintain) their own shim layer
> > > > > > > that
> > > would provide some s of abstraction?
> > > > > > > Basically their own version of rte_ethdev?
> > > > > >
> > > > > > No definitive answer.
> > > > > > But we can argue the contrary: how to handle a generic API
> > > > > > which is implemented only in 1 or 2 drivers? If the
> > > > > > application tries to use it,
> > > we can imagine that a specific range of hardware is expected.
> > > > >
> > > > > Yes, as I understand, it is a specific subset of supported HW
> > > > > (just Inel NICs
> > > for now, but different models/drivers).
> > > > > Obviously users would like to have an ability to run their app
> > > > > on all HW
> > > from this subset without rebuilding/implementing the app.
> > > > >
> > > > > >
> > > > > > I think it is an important question.
> > > > > > Previously we had the issue of having some API which are too
> > > > > > specific and need a rework to be used with other NICs. In
> > > > > > order to avoid such rework and API break, we can try to make
> > > > > > them available in a driver-specific or vendor-specific staging
> > > > > > area, waiting for
> > > > a later generalization.
> > > > >
> > > > > Could you remind me why you guys were that opposed to ioctl
> > > > > style
> > > approach?
> > > > > It is not my favorite thing either, but it seems pretty generic
> > > > > way to
> > > handle such situations.
> > > >
> > > > We prefer having well-defined functions instead of opaque
> > > > ioctl-style
> > > encoding.
> > > > And it was not clear what is the benefit of ioctl.
> > > > Now I think I understand you would like to have a common ioctl
> > > > service for
> > > features available on 2 drivers. Right?
> > >
> > > Yes.
> > >
> > > > Example (trying to  read your mind):
> > > > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF
> > > id>); instead of
> > > > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > > > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > > > what you are thinking about.
> > >
> > > Yep, you read my mind correctly :)
> > > Konstantin
> > >
> > Adding the pmd_ops field to struct eth_devops {} discussed previously in
> this email thread will allow driver specific functions for multiple drivers and
> will get rid of the driver specific header file rte_pmd_driver.h.
> > Would this be an acceptable solution?
> 
> How pmd_ops would be different of eth_devops?

There is not a lot of difference, however it would separate generic ethdev functions from driver specific functions.

Regards,

Bernard.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 14:59                                               ` Thomas Monjalon
@ 2016-09-28 16:52                                                 ` Ananyev, Konstantin
  2016-09-28 18:02                                                   ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Ananyev, Konstantin @ 2016-09-28 16:52 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak


> 
> 2016-09-28 14:30, Ananyev, Konstantin:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > 2016-09-28 13:26, Ananyev, Konstantin:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > > If we  this way (force user to include driver specific headers
> > > > > > and call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > > > >
> > > > > Multiple drivers won't have exactly the same specific features.
> > > > > But yes, there are some things common to several Intel NICs.
> > > > >
> > > > > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > > > > Does it mean that they'll have to re-implement this part of their code again?
> > > > > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > > > > Basically their own version of rte_ethdev?
> > > > >
> > > > > No definitive answer.
> > > > > But we can argue the contrary: how to handle a generic API which
> > > > > is implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is
> expected.
> > > >
> > > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> > > > Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the
> app.
> > > >
> > > > >
> > > > > I think it is an important question.
> > > > > Previously we had the issue of having some API which are too
> > > > > specific and need a rework to be used with other NICs. In order
> > > > > to avoid such rework and API break, we can try to make them
> > > > > available in a driver-specific or vendor-specific staging area,
> > > > > waiting for
> > > a later generalization.
> > > >
> > > > Could you remind me why you guys were that opposed to ioctl style approach?
> > > > It is not my favorite thing either, but it seems pretty generic way to handle such situations.
> > >
> > > We prefer having well-defined functions instead of opaque ioctl-style encoding.
> > > And it was not clear what is the benefit of ioctl.
> > > Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
> >
> > Yes.
> >
> > > Example (trying to  read your mind):
> > > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
> > > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > > what you are thinking about.
> >
> > Yep, you read my mind correctly :)
> 
> Both could coexist (if ioctl was accepted by community).

True.

> What about starting to implement the PMD functions and postpone ioctl to later with a dedicated thread?

You mean something like:
- 16.11: implement rte_pmd_ixgbe_vf_ping()
- 17.02:
	a) implement rte_pmd_i40e_vf_ping()
	b) introduce ioctl PMD API
	c) make possible to vf_ping via ioctl API
?
If so, then it sounds like reasonable approach to me.
Though would be inserting to hear what other guys think.
Konstantin

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 16:52                                                 ` Ananyev, Konstantin
@ 2016-09-28 18:02                                                   ` Thomas Monjalon
  2016-09-30  9:21                                                     ` Bruce Richardson
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-28 18:02 UTC (permalink / raw)
  To: Ananyev, Konstantin
  Cc: Iremonger, Bernard, Richardson, Bruce, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

2016-09-28 16:52, Ananyev, Konstantin:
> 
> > 
> > 2016-09-28 14:30, Ananyev, Konstantin:
> > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > 2016-09-28 13:26, Ananyev, Konstantin:
> > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > > > If we  this way (force user to include driver specific headers
> > > > > > > and call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > > > > >
> > > > > > Multiple drivers won't have exactly the same specific features.
> > > > > > But yes, there are some things common to several Intel NICs.
> > > > > >
> > > > > > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > > > > > Does it mean that they'll have to re-implement this part of their code again?
> > > > > > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > > > > > Basically their own version of rte_ethdev?
> > > > > >
> > > > > > No definitive answer.
> > > > > > But we can argue the contrary: how to handle a generic API which
> > > > > > is implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is
> > expected.
> > > > >
> > > > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> > > > > Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the
> > app.
> > > > >
> > > > > >
> > > > > > I think it is an important question.
> > > > > > Previously we had the issue of having some API which are too
> > > > > > specific and need a rework to be used with other NICs. In order
> > > > > > to avoid such rework and API break, we can try to make them
> > > > > > available in a driver-specific or vendor-specific staging area,
> > > > > > waiting for
> > > > a later generalization.
> > > > >
> > > > > Could you remind me why you guys were that opposed to ioctl style approach?
> > > > > It is not my favorite thing either, but it seems pretty generic way to handle such situations.
> > > >
> > > > We prefer having well-defined functions instead of opaque ioctl-style encoding.
> > > > And it was not clear what is the benefit of ioctl.
> > > > Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
> > >
> > > Yes.
> > >
> > > > Example (trying to  read your mind):
> > > > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
> > > > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > > > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > > > what you are thinking about.
> > >
> > > Yep, you read my mind correctly :)
> > 
> > Both could coexist (if ioctl was accepted by community).
> 
> True.
> 
> > What about starting to implement the PMD functions and postpone ioctl to later with a dedicated thread?
> 
> You mean something like:
> - 16.11: implement rte_pmd_ixgbe_vf_ping()
> - 17.02:
> 	a) implement rte_pmd_i40e_vf_ping()
> 	b) introduce ioctl PMD API
> 	c) make possible to vf_ping via ioctl API
> ?
> If so, then it sounds like reasonable approach to me.
> Though would be inserting to hear what other guys think.

Yes.
I would just add that we have to start a discussion thread to decide
wether we'll add an ioctl call in 17.02 or not.

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

* [PATCH v5 0/3] add API's for VF management
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
@ 2016-09-29 14:16       ` Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 0/2] " Bernard Iremonger
                           ` (2 more replies)
  2016-09-29 14:16       ` [PATCH v5 1/3] librte_ether: add API for VF management Bernard Iremonger
                         ` (2 subsequent siblings)
  3 siblings, 3 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-29 14:16 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This patch set adds API extensions to DPDK VF configuration.

Eight new API's have been added for the Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Changes in v5:
rebase to latest master branch.
remove new API's from eth_dev_ops structure.
add public API's to ixgbe PMD.
revise testpmd commands for new API's

Changes in v4:
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (3):
  librte_ether: add API for VF management
  net/ixgbe: add API's for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 drivers/net/ixgbe/Makefile                  |   2 +
 drivers/net/ixgbe/ixgbe_ethdev.c            | 200 +++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 162 +++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  12 +
 lib/librte_ether/rte_ethdev.c               |  27 ++
 lib/librte_ether/rte_ethdev.h               |  23 +-
 lib/librte_ether/rte_ether_version.map      |   6 +
 9 files changed, 1165 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

-- 
2.9.0

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

* [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
@ 2016-09-29 14:16       ` Bernard Iremonger
  2016-09-29 14:30         ` Thomas Monjalon
  2016-09-29 14:16       ` [PATCH v5 2/3] net/ixgbe: add API's " Bernard Iremonger
  2016-09-29 14:16       ` [PATCH v5 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  3 siblings, 1 reply; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-29 14:16 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add new API function to configure and manage VF's on a NIC.

add rte_eth_dev_set_vf_vlan_stripq function.

Signed-off-by: azelezniak <alexz@att.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 23 ++++++++++++++++++++++-
 lib/librte_ether/rte_ether_version.map |  6 ++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..15e21ca 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2489,6 +2489,33 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
 						   vf_mask, vlan_on);
 }
 
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port_id, uint16_t vf, int on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs) {
+		RTE_PMD_DEBUG_TRACE("set VF vlan stripq: invalid VF %d\n", vf);
+		return -EINVAL;
+	}
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	queues_per_pool = dev_info.vmdq_queue_num/dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
 					uint16_t tx_rate)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 96575e8..fb2be45 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3499,7 +3499,28 @@ rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
 				uint8_t vlan_on);
 
 /**
- * Set a traffic mirroring rule on an Ethernet device
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
+
+/** Set a traffic mirroring rule on an Ethernet device
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..ae44074 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,9 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_eth_dev_set_vf_vlan_stripq;
+} DPDK_16.07;
-- 
2.9.0

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

* [PATCH v5 2/3] net/ixgbe: add API's for VF management
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
  2016-09-29 14:16       ` [PATCH v5 1/3] librte_ether: add API for VF management Bernard Iremonger
@ 2016-09-29 14:16       ` Bernard Iremonger
  2016-09-29 16:11         ` Reshma Pattan
  2016-09-29 16:16         ` Pattan, Reshma
  2016-09-29 14:16       ` [PATCH v5 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
  3 siblings, 2 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-29 14:16 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger, azelezniak

Add API's to configure and manage VF's on an Intel 82559 NIC.

add rte_pmd_ixgbe_set_vf_vlan_anti_spoof function.
add rte_pmd_ixgbe_set_vf_mac_anti_spoof function.

Signed-off-by: azelezniak <alexz@att.com>

add rte_pmd_ixgbe_set_vf_vlan_insert function.
add rte_pmd_ixgbe_set_tx_loopback function.
add rte_pmd_ixgbe_set_all_queues_drop function.
add rte_pmd_ixgbe_set_vf_split_drop_en function.
add rte_pmd_ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/Makefile                  |   2 +
 drivers/net/ixgbe/ixgbe_ethdev.c            | 200 ++++++++++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 162 ++++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  12 ++
 4 files changed, 376 insertions(+)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index a6c71f3..7493b8d 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
 endif
 
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_ACL)-include := rte_pmd_ixgbe.h
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 73a406b..beaebe1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -72,6 +72,8 @@
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
 
+#include "rte_pmd_ixgbe.h"
+
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
  * least 8 bytes less than receive packet buffer size. This value is in units
@@ -4068,6 +4070,35 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 	ixgbe_add_rar(dev, addr, 0, 0);
 }
 
+int
+rte_pmd_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_vf_info *vfinfo;
+	int rar_entry;
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	rar_entry = hw->mac.num_rar_entries - (vf + 1);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -EINVAL;
+}
+
 static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
@@ -4661,6 +4692,175 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+int
+rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (on) {
+		ctrl = on;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(on & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	/* only support VF's 0 to 63 */
+	if ((vf >= dev_info.max_vfs) || (vf > 63))
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (on)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+
+	return 0;
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
new file mode 100644
index 0000000..918540b
--- /dev/null
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -0,0 +1,162 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2016 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.
+ */
+
+/**
+ * @file rte_pmd_ixgbe.h
+ * ixgbe PMD specific functions.
+ *
+ **/
+
+#ifndef _PMD_IXGBE_H_
+#define _PMD_IXGBE_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   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_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf,	uint8_t on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
+#endif /* _PMD_IXGBE_H_ */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index ef35398..7677885 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -2,3 +2,15 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_16.11 {
+	global:
+
+	rte_pmd_ixgbe_set_all_queues_drop_en;
+	rte_pmd_ixgbe_set_tx_loopback;
+	rte_pmd_ixgbe_set_vf_mac_addr;
+	rte_pmd_ixgbe_set_vf_mac_anti_spoof;
+	rte_pmd_ixgbe_set_vf_split_drop_en;
+	rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
+	rte_pmd_ixgbe_set_vf_vlan_insert;
+} DPDK_2.0;
-- 
2.9.0

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

* [PATCH v5 3/3] app/test_pmd: add tests for new API's
  2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
                         ` (2 preceding siblings ...)
  2016-09-29 14:16       ` [PATCH v5 2/3] net/ixgbe: add API's " Bernard Iremonger
@ 2016-09-29 14:16       ` Bernard Iremonger
  3 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-29 14:16 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for set vf vlan anti spoof
add test for set vf mac anti spoof
add test for set vf vlan stripq
add test for set vf vlan insert
add test for set tx loopback
add test for set all queues drop enable bit
add test for set vf split drop enable bit
add test for set vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 2 files changed, 734 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 17d238f..2847f94 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -87,6 +87,7 @@
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
+#include <rte_pmd_ixgbe.h>
 
 #include "testpmd.h"
 
@@ -10585,6 +10586,672 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan strip queue configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_stripq_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t stripq;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 stripq, "stripq");
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_stripq_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_stripq_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_eth_dev_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
+	.f = cmd_set_vf_vlan_stripq_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan stripq port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_stripq_set,
+		(void *)&cmd_vf_vlan_stripq_vf,
+		(void *)&cmd_vf_vlan_stripq_vlan,
+		(void *)&cmd_vf_vlan_stripq_stripq,
+		(void *)&cmd_vf_vlan_stripq_port_id,
+		(void *)&cmd_vf_vlan_stripq_vf_id,
+		(void *)&cmd_vf_vlan_stripq_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or mac_addr\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
+
+/* get PMD dev_ops handle */
+
+/* Common result structure for vf mac address */
+struct cmd_get_pmd_handle_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t pmd;
+	cmdline_fixed_string_t handle;
+	uint8_t port_id;
+};
+
+
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11406,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..145c425 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set stripq (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for all queues in a pool for a VF from the PF::
+
+   testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +776,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* Re: [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-29 14:16       ` [PATCH v5 1/3] librte_ether: add API for VF management Bernard Iremonger
@ 2016-09-29 14:30         ` Thomas Monjalon
  2016-09-29 15:16           ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-29 14:30 UTC (permalink / raw)
  To: Bernard Iremonger; +Cc: dev, rahul.r.shah, wenzhuo.lu, az5157, azelezniak

2016-09-29 15:16, Bernard Iremonger:
> Add new API function to configure and manage VF's on a NIC.
> 
> add rte_eth_dev_set_vf_vlan_stripq function.
> 
> Signed-off-by: azelezniak <alexz@att.com>

We need the full name of azelezniak.

> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
[...]
> +int
> +rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);

Why keeping this function in ethdev?

I think it would be more consistent to have also existing VF functions
moving from ethdev to rte_pmd_ixgbe.h.
You cannot remove them, but you can create their ixgbe-specific version
and announce that the ethdev ones are deprecated.

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

* Re: [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-29 14:30         ` Thomas Monjalon
@ 2016-09-29 15:16           ` Iremonger, Bernard
  2016-09-29 16:19             ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-29 15:16 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shah, Rahul R, Lu, Wenzhuo, az5157, azelezniak

Hi Thomas,

<snip>

> Subject: Re: [dpdk-dev] [PATCH v5 1/3] librte_ether: add API for VF
> management
> 
> 2016-09-29 15:16, Bernard Iremonger:
> > Add new API function to configure and manage VF's on a NIC.
> >
> > add rte_eth_dev_set_vf_vlan_stripq function.
> >
> > Signed-off-by: azelezniak <alexz@att.com>
> 
> We need the full name of azelezniak.

It is Alex Zelezniak, I will update the commit messages.

> > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> [...]
> > +int
> > +rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
> 
> Why keeping this function in ethdev?

This function is using an existing API in the eth_dev_ops structure.

dev->dev_ops->vlan_strip_queue_set

The vlan_strip_queue_set API is used by  the i40e, ixgbe and mlx5 PMD's.

> I think it would be more consistent to have also existing VF functions moving
> from ethdev to rte_pmd_ixgbe.h.
> You cannot remove them, but you can create their ixgbe-specific version and
> announce that the ethdev ones are deprecated.

There are 5 existing VF functions which are only used by ixgbe PMD at present.
It would make sense to create ixgbe-specific versions, however I think this should be done in a separate patchset.

Regards,

Bernard

 

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

* Re: [PATCH v5 2/3] net/ixgbe: add API's for VF management
  2016-09-29 14:16       ` [PATCH v5 2/3] net/ixgbe: add API's " Bernard Iremonger
@ 2016-09-29 16:11         ` Reshma Pattan
  2016-09-29 16:32           ` Iremonger, Bernard
  2016-09-29 16:16         ` Pattan, Reshma
  1 sibling, 1 reply; 94+ messages in thread
From: Reshma Pattan @ 2016-09-29 16:11 UTC (permalink / raw)
  To: Bernard Iremonger, dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: azelezniak

Hi,


On 9/29/2016 3:16 PM, Bernard Iremonger wrote:
> diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
> index a6c71f3..7493b8d 100644
> --- a/drivers/net/ixgbe/Makefile
> +++ b/drivers/net/ixgbe/Makefile
> @@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c
>   SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
>   endif
>   
> +# install this header file
> +SYMLINK-$(CONFIG_RTE_LIBRTE_ACL)-include := rte_pmd_ixgbe.h
>   

In correct config flag  CONFIG_RTE_LIBRTE_ACL , should be 
CONFIG_RTE_LIBRTE_IXGBE_PMD

Thanks,
Reshma

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

* Re: [PATCH v5 2/3] net/ixgbe: add API's for VF management
  2016-09-29 14:16       ` [PATCH v5 2/3] net/ixgbe: add API's " Bernard Iremonger
  2016-09-29 16:11         ` Reshma Pattan
@ 2016-09-29 16:16         ` Pattan, Reshma
  2016-09-29 16:30           ` Iremonger, Bernard
  1 sibling, 1 reply; 94+ messages in thread
From: Pattan, Reshma @ 2016-09-29 16:16 UTC (permalink / raw)
  To: Iremonger, Bernard, dev, Shah, Rahul R, Lu, Wenzhuo, az5157
  Cc: Iremonger, Bernard, azelezniak

Hi,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard Iremonger
> Sent: Thursday, September 29, 2016 3:17 PM
> To: dev@dpdk.org; Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; az5157@att.com
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; azelezniak
> <alexz@att.com>
> Subject: [dpdk-dev] [PATCH v5 2/3] net/ixgbe: add API's for VF management
> 
> diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile index
> a6c71f3..7493b8d 100644
> --- a/drivers/net/ixgbe/Makefile
> +++ b/drivers/net/ixgbe/Makefile
> @@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=
> ixgbe_bypass.c
>  SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c  endif
> 
> +# install this header file
> +SYMLINK-$(CONFIG_RTE_LIBRTE_ACL)-include := rte_pmd_ixgbe.h
> 

Config flag should be CONFIG_RTE_LIBRTE_IXGBE_PMD .

Thanks,
Reshma

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

* Re: [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-29 15:16           ` Iremonger, Bernard
@ 2016-09-29 16:19             ` Thomas Monjalon
  2016-09-29 16:38               ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-29 16:19 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev, Shah, Rahul R, Lu, Wenzhuo, az5157, azelezniak

2016-09-29 15:16, Iremonger, Bernard:
> > 2016-09-29 15:16, Bernard Iremonger:
> > > +int
> > > +rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int on);
> > 
> > Why keeping this function in ethdev?
> 
> This function is using an existing API in the eth_dev_ops structure.
> 
> dev->dev_ops->vlan_strip_queue_set
> 
> The vlan_strip_queue_set API is used by  the i40e, ixgbe and mlx5 PMD's.

OK but it was not used to control VF from PF.
This line:
	(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
seems Intel specific.
Please keep "VF from PF" outside of ethdev for 16.11.

> > I think it would be more consistent to have also existing VF functions moving
> > from ethdev to rte_pmd_ixgbe.h.
> > You cannot remove them, but you can create their ixgbe-specific version and
> > announce that the ethdev ones are deprecated.
> 
> There are 5 existing VF functions which are only used by ixgbe PMD at present.
> It would make sense to create ixgbe-specific versions, however I think this should be done in a separate patchset.

Yes it can be a separate patchset for RC2 of course.

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

* Re: [PATCH v5 2/3] net/ixgbe: add API's for VF management
  2016-09-29 16:16         ` Pattan, Reshma
@ 2016-09-29 16:30           ` Iremonger, Bernard
  0 siblings, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-29 16:30 UTC (permalink / raw)
  To: Pattan, Reshma, dev, Shah, Rahul R, Lu, Wenzhuo, az5157; +Cc: azelezniak

Hi Reshma,

> -----Original Message-----
> From: Pattan, Reshma
> Sent: Thursday, September 29, 2016 5:16 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; dev@dpdk.org;
> Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; az5157@att.com
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; azelezniak
> <alexz@att.com>
> Subject: RE: [dpdk-dev] [PATCH v5 2/3] net/ixgbe: add API's for VF
> management
> 
> Hi,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bernard
> Iremonger
> > Sent: Thursday, September 29, 2016 3:17 PM
> > To: dev@dpdk.org; Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> > <wenzhuo.lu@intel.com>; az5157@att.com
> > Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; azelezniak
> > <alexz@att.com>
> > Subject: [dpdk-dev] [PATCH v5 2/3] net/ixgbe: add API's for VF
> > management
> >
> > diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
> > index a6c71f3..7493b8d 100644
> > --- a/drivers/net/ixgbe/Makefile
> > +++ b/drivers/net/ixgbe/Makefile
> > @@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=
> > ixgbe_bypass.c
> >  SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
> endif
> >
> > +# install this header file
> > +SYMLINK-$(CONFIG_RTE_LIBRTE_ACL)-include := rte_pmd_ixgbe.h
> >
> 
> Config flag should be CONFIG_RTE_LIBRTE_IXGBE_PMD .
> 
> Thanks,
> Reshma

I will correct this in v6 patchset.

Regards,

Bernard.

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

* Re: [PATCH v5 2/3] net/ixgbe: add API's for VF management
  2016-09-29 16:11         ` Reshma Pattan
@ 2016-09-29 16:32           ` Iremonger, Bernard
  0 siblings, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-29 16:32 UTC (permalink / raw)
  To: Pattan, Reshma, dev, Shah, Rahul R, Lu, Wenzhuo, az5157; +Cc: azelezniak


Hi Reshma,

> -----Original Message-----
> From: Pattan, Reshma
> Sent: Thursday, September 29, 2016 5:11 PM
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; dev@dpdk.org;
> Shah, Rahul R <rahul.r.shah@intel.com>; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; az5157@att.com
> Cc: azelezniak <alexz@att.com>
> Subject: Re: [dpdk-dev] [PATCH v5 2/3] net/ixgbe: add API's for VF
> management
> 
> Hi,
> 
> 
> On 9/29/2016 3:16 PM, Bernard Iremonger wrote:
> > diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
> > index a6c71f3..7493b8d 100644
> > --- a/drivers/net/ixgbe/Makefile
> > +++ b/drivers/net/ixgbe/Makefile
> > @@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) +=
> ixgbe_bypass.c
> >   SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
> >   endif
> >
> > +# install this header file
> > +SYMLINK-$(CONFIG_RTE_LIBRTE_ACL)-include := rte_pmd_ixgbe.h
> >
> 
> In correct config flag  CONFIG_RTE_LIBRTE_ACL , should be
> CONFIG_RTE_LIBRTE_IXGBE_PMD
> 
> Thanks,
> Reshma

I will correct this in v6 patchset.

Regards,

Bernard.

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

* Re: [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-29 16:19             ` Thomas Monjalon
@ 2016-09-29 16:38               ` Iremonger, Bernard
  2016-09-29 16:45                 ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-09-29 16:38 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, Shah, Rahul R, Lu, Wenzhuo, az5157, azelezniak

Hi Thomas,

> Subject: Re: [dpdk-dev] [PATCH v5 1/3] librte_ether: add API for VF
> management
> 
> 2016-09-29 15:16, Iremonger, Bernard:
> > > 2016-09-29 15:16, Bernard Iremonger:
> > > > +int
> > > > +rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int
> > > > +on);
> > >
> > > Why keeping this function in ethdev?
> >
> > This function is using an existing API in the eth_dev_ops structure.
> >
> > dev->dev_ops->vlan_strip_queue_set
> >
> > The vlan_strip_queue_set API is used by  the i40e, ixgbe and mlx5 PMD's.
> 
> OK but it was not used to control VF from PF.
> This line:
> 	(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf *
> queues_per_pool, on); seems Intel specific.
> Please keep "VF from PF" outside of ethdev for 16.11.

I will try calling  (*dev->dev_ops->vlan_strip_queue_set) from an ixgbe-specific function.
Will this be acceptable? 

Regards,

Bernard.

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

* Re: [PATCH v5 1/3] librte_ether: add API for VF management
  2016-09-29 16:38               ` Iremonger, Bernard
@ 2016-09-29 16:45                 ` Thomas Monjalon
  0 siblings, 0 replies; 94+ messages in thread
From: Thomas Monjalon @ 2016-09-29 16:45 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: dev, Shah, Rahul R, Lu, Wenzhuo, az5157, azelezniak

2016-09-29 16:38, Iremonger, Bernard:
> Hi Thomas,
> 
> > Subject: Re: [dpdk-dev] [PATCH v5 1/3] librte_ether: add API for VF
> > management
> > 
> > 2016-09-29 15:16, Iremonger, Bernard:
> > > > 2016-09-29 15:16, Bernard Iremonger:
> > > > > +int
> > > > > +rte_eth_dev_set_vf_vlan_stripq(uint8_t port, uint16_t vf, int
> > > > > +on);
> > > >
> > > > Why keeping this function in ethdev?
> > >
> > > This function is using an existing API in the eth_dev_ops structure.
> > >
> > > dev->dev_ops->vlan_strip_queue_set
> > >
> > > The vlan_strip_queue_set API is used by  the i40e, ixgbe and mlx5 PMD's.
> > 
> > OK but it was not used to control VF from PF.
> > This line:
> > 	(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf *
> > queues_per_pool, on); seems Intel specific.
> > Please keep "VF from PF" outside of ethdev for 16.11.
> 
> I will try calling  (*dev->dev_ops->vlan_strip_queue_set) from an ixgbe-specific function.
> Will this be acceptable? 

I think it is acceptable.

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

* Re: [RFC PATCH v2 3/5] librte_ether: add API's for VF management
  2016-09-28 18:02                                                   ` Thomas Monjalon
@ 2016-09-30  9:21                                                     ` Bruce Richardson
  0 siblings, 0 replies; 94+ messages in thread
From: Bruce Richardson @ 2016-09-30  9:21 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Ananyev, Konstantin, Iremonger, Bernard, dev, Jerin Jacob, Shah,
	Rahul R, Lu, Wenzhuo, azelezniak

On Wed, Sep 28, 2016 at 08:02:21PM +0200, Thomas Monjalon wrote:
> 2016-09-28 16:52, Ananyev, Konstantin:
> > 
> > > 
> > > 2016-09-28 14:30, Ananyev, Konstantin:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-09-28 13:26, Ananyev, Konstantin:
> > > > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > > > 2016-09-28 11:23, Ananyev, Konstantin:
> > > > > > > > If we  this way (force user to include driver specific headers
> > > > > > > > and call driver specific functions), how you guys plan to make this functionality available for multiple driver types.
> > > > > > >
> > > > > > > Multiple drivers won't have exactly the same specific features.
> > > > > > > But yes, there are some things common to several Intel NICs.
> > > > > > >
> > > > > > > > From discussion with Bernard  understand that customers would need similar functionality for i40e.
> > > > > > > > Does it mean that they'll have to re-implement this part of their code again?
> > > > > > > > Or would have to create (and maintain) their own shim layer that would provide some s of abstraction?
> > > > > > > > Basically their own version of rte_ethdev?
> > > > > > >
> > > > > > > No definitive answer.
> > > > > > > But we can argue the contrary: how to handle a generic API which
> > > > > > > is implemented only in 1 or 2 drivers? If the application tries to use it, we can imagine that a specific range of hardware is
> > > expected.
> > > > > >
> > > > > > Yes, as I understand, it is a specific subset of supported HW (just Inel NICs for now, but different models/drivers).
> > > > > > Obviously users would like to have an ability to run their app on all HW from this subset without rebuilding/implementing the
> > > app.
> > > > > >
> > > > > > >
> > > > > > > I think it is an important question.
> > > > > > > Previously we had the issue of having some API which are too
> > > > > > > specific and need a rework to be used with other NICs. In order
> > > > > > > to avoid such rework and API break, we can try to make them
> > > > > > > available in a driver-specific or vendor-specific staging area,
> > > > > > > waiting for
> > > > > a later generalization.
> > > > > >
> > > > > > Could you remind me why you guys were that opposed to ioctl style approach?
> > > > > > It is not my favorite thing either, but it seems pretty generic way to handle such situations.
> > > > >
> > > > > We prefer having well-defined functions instead of opaque ioctl-style encoding.
> > > > > And it was not clear what is the benefit of ioctl.
> > > > > Now I think I understand you would like to have a common ioctl service for features available on 2 drivers. Right?
> > > >
> > > > Yes.
> > > >
> > > > > Example (trying to  read your mind):
> > > > > 	rte_ethdev_ioctl(port_id, <TLV encoding VF_PING service and VF id>); instead of
> > > > > 	rte_pmd_ixgbe_vf_ping(port_id, vf_id);
> > > > > 	rte_pmd_i40e_vf_ping(port_id, vf_id); Please confirm I understand
> > > > > what you are thinking about.
> > > >
> > > > Yep, you read my mind correctly :)
> > > 
> > > Both could coexist (if ioctl was accepted by community).
> > 
> > True.
> > 
> > > What about starting to implement the PMD functions and postpone ioctl to later with a dedicated thread?
> > 
> > You mean something like:
> > - 16.11: implement rte_pmd_ixgbe_vf_ping()
> > - 17.02:
> > 	a) implement rte_pmd_i40e_vf_ping()
> > 	b) introduce ioctl PMD API
> > 	c) make possible to vf_ping via ioctl API
> > ?
> > If so, then it sounds like reasonable approach to me.
> > Though would be inserting to hear what other guys think.
> 
> Yes.
> I would just add that we have to start a discussion thread to decide
> wether we'll add an ioctl call in 17.02 or not.

I still don't like IOCTLs as an option, I still think that they are awkward to
use and hinder code readability. Here is an addition suggestion to get people
thinking.

How about allowing a set of "vendor-specific" operations for each device. We
could do this using Bernard's suggestion of adding a set of additional 
function pointers to the device struct. The reason for doing this is that it
would allow us to group functionality into families of functionality, rather
than having to things either fully generically or specifically to each NIC. If
we look at the capabilities of most NICs, the other NICs which support similar
functions are generally other NICs from the same vendor. We could therefore
have ops common across ixgbe and i40e and other ops mlx4 and mlx5 drivers.

Could such a scheme work? Would it be worth doing?

/Bruce

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

* [PATCH v6 0/2] add API's for VF management
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
@ 2016-09-30 10:30         ` Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 " Bernard Iremonger
  2 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-30 10:30 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's requested by AT&T for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where AT&T have devloped a DPDK based tool, VFD, to do this.

This patch set adds API extensions to DPDK for VF configuration.

Eight new API's have been added for the Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Changes in v6:
rebase to latest master branch.
fix ixgbe makefile.
move set_vf_vlan_stripq function from ethdev to ixgbe PMD.
revise testpmd command for set_vf_vlan_stripq.

Changes in v5:
rebase to latest master branch.
remove new API's from eth_dev_ops structure.
add public API's to ixgbe PMD.
revise testpmd commands for new API's

Changes in v4:
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (2):
  net/ixgbe: add API's for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 drivers/net/ixgbe/Makefile                  |   4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 228 ++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 184 ++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  13 +
 6 files changed, 1162 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

-- 
2.9.0

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

* [PATCH v6 1/2] net/ixgbe: add API's for VF management
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 0/2] " Bernard Iremonger
@ 2016-09-30 10:30         ` Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 0/2] " Bernard Iremonger
                             ` (2 more replies)
  2016-09-30 10:30         ` [PATCH v6 " Bernard Iremonger
  2 siblings, 3 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-30 10:30 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

Add API's to configure and manage VF's on an Intel 82559 NIC.

add rte_pmd_ixgbe_set_vf_vlan_anti_spoof function.
add rte_pmd_ixgbe_set_vf_mac_anti_spoof function.
add rte_pmd_ixgbe_set_vf_stripq function.

Signed-off-by: Alex Zelezniak <az5157@att.com>

add rte_pmd_ixgbe_set_vf_vlan_insert function.
add rte_pmd_ixgbe_set_tx_loopback function.
add rte_pmd_ixgbe_set_all_queues_drop function.
add rte_pmd_ixgbe_set_vf_split_drop_en function.
add rte_pmd_ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/Makefile                  |   4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 228 ++++++++++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 184 ++++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  13 ++
 4 files changed, 428 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index a6c71f3..94ddc7b 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
 endif
 
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 73a406b..94ec0f9 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -72,6 +72,8 @@
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
 
+#include "rte_pmd_ixgbe.h"
+
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
  * least 8 bytes less than receive packet buffer size. This value is in units
@@ -4068,6 +4070,35 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 	ixgbe_add_rar(dev, addr, 0, 0);
 }
 
+int
+rte_pmd_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_vf_info *vfinfo;
+	int rar_entry;
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	rar_entry = hw->mac.num_rar_entries - (vf + 1);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -EINVAL;
+}
+
 static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
@@ -4661,6 +4692,203 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+int
+rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (on) {
+		ctrl = on;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(on & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	/* only support VF's 0 to 63 */
+	if ((vf >= dev_info.max_vfs) || (vf > 63))
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (on)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port_id, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	dev = &rte_eth_devices[port_id];
+	rte_eth_dev_info_get(port_id, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
new file mode 100644
index 0000000..33b5b2d
--- /dev/null
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -0,0 +1,184 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2016 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.
+ */
+
+/**
+ * @file rte_pmd_ixgbe.h
+ * ixgbe PMD specific functions.
+ *
+ **/
+
+#ifndef _PMD_IXGBE_H_
+#define _PMD_IXGBE_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   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_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf,	uint8_t on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ * @param queues_per_pool
+ *    The number of queues per pool.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+#endif /* _PMD_IXGBE_H_ */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index ef35398..92434f3 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -2,3 +2,16 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_16.11 {
+	global:
+
+	rte_pmd_ixgbe_set_all_queues_drop_en;
+	rte_pmd_ixgbe_set_tx_loopback;
+	rte_pmd_ixgbe_set_vf_mac_addr;
+	rte_pmd_ixgbe_set_vf_mac_anti_spoof;
+	rte_pmd_ixgbe_set_vf_split_drop_en;
+	rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
+	rte_pmd_ixgbe_set_vf_vlan_insert;
+	rte_pmd_ixgbe_set_vf_vlan_stripq;
+} DPDK_2.0;
-- 
2.9.0

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

* [PATCH v6 2/2] app/test_pmd: add tests for new API's
  2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 0/2] " Bernard Iremonger
  2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
@ 2016-09-30 10:30         ` Bernard Iremonger
  2 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-09-30 10:30 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for set vf vlan anti spoof
add test for set vf mac anti spoof
add test for set vf vlan stripq
add test for set vf vlan insert
add test for set tx loopback
add test for set all queues drop enable bit
add test for set vf split drop enable bit
add test for set vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 2 files changed, 734 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 17d238f..d26db62 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -87,6 +87,7 @@
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
+#include <rte_pmd_ixgbe.h>
 
 #include "testpmd.h"
 
@@ -10585,6 +10586,672 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan strip queue configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_stripq_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t stripq;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 stripq, "stripq");
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_stripq_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_stripq_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
+	.f = cmd_set_vf_vlan_stripq_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan stripq port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_stripq_set,
+		(void *)&cmd_vf_vlan_stripq_vf,
+		(void *)&cmd_vf_vlan_stripq_vlan,
+		(void *)&cmd_vf_vlan_stripq_stripq,
+		(void *)&cmd_vf_vlan_stripq_port_id,
+		(void *)&cmd_vf_vlan_stripq_vf_id,
+		(void *)&cmd_vf_vlan_stripq_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or mac_addr\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
+
+/* get PMD dev_ops handle */
+
+/* Common result structure for vf mac address */
+struct cmd_get_pmd_handle_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t pmd;
+	cmdline_fixed_string_t handle;
+	uint8_t port_id;
+};
+
+
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11406,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..145c425 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set stripq (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for all queues in a pool for a VF from the PF::
+
+   testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +776,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* Re: [RFC PATCH v2 1/5] librte_ether: add internal callback functions
  2016-09-14 11:28             ` Jerin Jacob
  2016-09-22 11:25               ` Iremonger, Bernard
@ 2016-10-03  8:58               ` Iremonger, Bernard
  1 sibling, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-10-03  8:58 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: Shah, Rahul R, Lu, Wenzhuo, dev, ZELEZNIAK, ALEX

Hi Jerin,

> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Wednesday, September 14, 2016 12:28 PM
> To: ZELEZNIAK, ALEX <az5157@att.com>
> Cc: Iremonger, Bernard <bernard.iremonger@intel.com>; Shah, Rahul R
> <rahul.r.shah@intel.com>; Lu, Wenzhuo <wenzhuo.lu@intel.com>;
> dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add internal
> callback functions
> 
> On Tue, Sep 13, 2016 at 02:05:49PM +0000, ZELEZNIAK, ALEX wrote:
> > Idea here is not to allow VM to control policies assigned to it for
> > security and other reasons. PF is controlled by host and dictates what
> > VM can and can't do in regards of setting VF parameters.
> 
> I think the proposed scheme, The VM does not take any action on its own.
> The VM will just follow what the centralized entity to do so.
> I think if you are planning to support different varieties of PMD then this
> could be an option.However, if you wish to support only a subset of PMDs
> then PF MBOX based scheme may be enough.
> In any case, I think exposing the fine details of PF/VF MBOX scheme in the
> ethdev spec is not a good idea.

I have reworked these patches (1/5 and 2/5) using the new rte_pmd_ixgbe.h file and submitted as a separate patchset.

[PATCH v3 0/2] add callbacks for VF management
http://dpdk.org/dev/patchwork/patch/16321/
http://dpdk.org/dev/patchwork/patch/16322/

Regards,

Bernard.

> > > -----Original Message-----
> > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > Sent: Tuesday, September 13, 2016 4:46 AM
> > > To: ZELEZNIAK, ALEX <az5157@att.com>
> > > Cc: Bernard Iremonger <bernard.iremonger@intel.com>;
> > > rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add
> > > internal callback functions
> > >
> > > On Fri, Sep 09, 2016 at 04:32:07PM +0000, ZELEZNIAK, ALEX wrote:
> > > > Use case could be to inform application managing SRIOV about VM's
> > > intention
> > > > to modify parameters like add VLAN which might not be the one
> > > > which is assigned to VF or inform about VF reset and reapply
> > > > settings like
> > > strip/insert
> > > > VLAN id based on policy.
> > >
> > > Is there any other way(more portable way) where we can realize the
> > > same use case?
> > >
> > > Something like,
> > >
> > > 1) The assigned VM operates/control the VF
> > > 2) A centralized entity post messages through UNIX socket or
> > > something(like vhost user communicates with VM).
> > > On message receive, VM can take necessary action on assigned VF.
> > >
> > > This will avoid the need of defining specifics of PF to VF mailbox
> > > communication in normative ethdev specification.
> > >
> > > And I guess it will work almost the PMD drivers as their is no PMD
> > > specific work here.
> > >
> > > Just a thought.
> > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > > > Sent: Friday, September 09, 2016 10:11 AM
> > > > > To: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > Cc: rahul.r.shah@intel.com; wenzhuo.lu@intel.com; dev@dpdk.org;
> > > > > ZELEZNIAK, ALEX <az5157@att.com>
> > > > > Subject: Re: [dpdk-dev] [RFC PATCH v2 1/5] librte_ether: add
> > > > > internal callback functions
> > > > >
> > > > > On Fri, Aug 26, 2016 at 10:10:16AM +0100, Bernard Iremonger wrote:
> > > > > > add _rte_eth_dev_callback_process_vf function.
> > > > > > add _rte_eth_dev_callback_process_generic function
> > > > > >
> > > > > > Adding a callback to the user application on VF to PF mailbox
> > > > > > message, allows passing information to the application
> > > > > > controlling the PF when a VF mailbox event message is received,
> such as VF reset.
> > > > > >
> > > > > > Signed-off-by: azelezniak <alexz@att.com>
> > > > > > Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> > > > > > ---
> > > > > >  lib/librte_ether/rte_ethdev.c          | 17 ++++++++++
> > > > > >  lib/librte_ether/rte_ethdev.h          | 61
> > > > > ++++++++++++++++++++++++++++++++++
> > > > > >  lib/librte_ether/rte_ether_version.map |  7 ++++
> > > > > >  3 files changed, 85 insertions(+)
> > > > > >
> > > > > > diff --git a/lib/librte_ether/rte_ethdev.c
> > > b/lib/librte_ether/rte_ethdev.c
> > > > > > index f62a9ec..1388ea3 100644
> > > > > > --- a/lib/librte_ether/rte_ethdev.c
> > > > > > +++ b/lib/librte_ether/rte_ethdev.c
> > > > > > @@ -2690,6 +2690,20 @@ void
> > > > > >  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
> > > > > >  	enum rte_eth_event_type event)  {
> > > > > > +	return _rte_eth_dev_callback_process_generic(dev, event,
> > > > > > +NULL); }
> > > > > > +
> > > > > > +void
> > > > > > +_rte_eth_dev_callback_process_vf(struct rte_eth_dev *dev,
> > > > > > +	enum rte_eth_event_type event, void *param) {
> > > > > > +	return _rte_eth_dev_callback_process_generic(dev, event,
> > > > > > +param); }
> > > > > > +
> > > > > > +void
> > > > > > +_rte_eth_dev_callback_process_generic(struct rte_eth_dev
> *dev,
> > > > > > +	enum rte_eth_event_type event, void *param) {
> > > > > >  	struct rte_eth_dev_callback *cb_lst;
> > > > > >  	struct rte_eth_dev_callback dev_cb;
> > > > > >
> > > > > > @@ -2699,6 +2713,9 @@ _rte_eth_dev_callback_process(struct
> > > > > rte_eth_dev *dev,
> > > > > >  			continue;
> > > > > >  		dev_cb = *cb_lst;
> > > > > >  		cb_lst->active = 1;
> > > > > > +		if (param != NULL)
> > > > > > +			dev_cb.cb_arg = (void *) param;
> > > > > > +
> > > > > >  		rte_spinlock_unlock(&rte_eth_dev_cb_lock);
> > > > > >  		dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
> > > > > >  						dev_cb.cb_arg);
> > > > > > diff --git a/lib/librte_ether/rte_ethdev.h
> > > b/lib/librte_ether/rte_ethdev.h
> > > > > > index b0fe033..4fb0b9c 100644
> > > > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > > > @@ -3047,9 +3047,27 @@ enum rte_eth_event_type {
> > > > > >  				/**< queue state event
> (enabled/disabled)
> > > > > */
> > > > > >  	RTE_ETH_EVENT_INTR_RESET,
> > > > > >  			/**< reset interrupt event, sent to VF on PF
> reset */
> > > > > > +	RTE_ETH_EVENT_VF_MBOX,  /**< PF mailbox processing
> callback
> > > > > > +*/
> > > > > >  	RTE_ETH_EVENT_MAX       /**< max value of this enum */
> > > > > >  };
> > > > > >
> > > > > > +/**
> > > > > > + * Response sent back to ixgbe driver from user app after
> > > > > > +callback  */ enum rte_eth_mb_event_rsp {
> > > > > > +	RTE_ETH_MB_EVENT_NOOP_ACK,  /**< skip mbox request
> and ACK
> > > > > */
> > > > > > +	RTE_ETH_MB_EVENT_NOOP_NACK, /**< skip mbox request
> and
> > > > > NACK */
> > > > > > +	RTE_ETH_MB_EVENT_PROCEED,  /**< proceed with mbox
> request
> > > > > */
> > > > > > +	RTE_ETH_MB_EVENT_MAX       /**< max value of this enum
> */
> > > > > > +};
> > > > >
> > > > > Do we really need to define the specifics of PF to VF MBOX
> > > communication
> > > > > in normative ethdev specification?
> > > > > Each drivers may have different PF to VF MBOX definitions so it
> > > > > may not
> > > be
> > > > > very portable.
> > > > > What is the use-case here? If its for VF configuration, I think
> > > > > we can do it as separate 'sync' functions for each functionality
> > > > > so that PMDs will have room hiding the specifics on MBOX definitions.
> > > >

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

* [PATCH v7 0/2] add API's for VF management
  2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
@ 2016-10-07 10:45           ` Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 1/2] net/ixgbe: " Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 2/2] app/test_pmd: add tests for new API's Bernard Iremonger
  2 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-10-07 10:45 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

This patchset contains new DPDK API's for use
with the Virtual Function Daemon (VFD).

The need to configure and manage VF's on a NIC has grown to the
point where a DPDK based tool, VFD, has been developed to do this.

This patch set adds API extensions to DPDK for VF configuration.

Eight new API's have been added for the Intel 82559 NIC.

Changes have been made to testpmd to facilitate testing of the new API's.
The testpmd documentation has been updated to document the testpmd changes.

Changes in v7:
rebase to latest master branch.
minor changes to ixgbe PMD following internal review.

Changes in v6:
rebase to latest master branch.
fix ixgbe makefile.
move set_vf_vlan_stripq function from ethdev to ixgbe PMD.
revise testpmd command for set_vf_vlan_stripq.

Changes in v5:
rebase to latest master branch.
remove new API's from eth_dev_ops structure.
add public API's to ixgbe PMD.
revise testpmd commands for new API's

Changes in v4:
The rte_eth_dev_vf_ping API has been dropped as it is a work around for a bug.
The rte_eth_dev_set_vf_vlan_strip API has been renamed to
rte_eth_dev_set_vf_vlan_stripq.

Changes in v3:
rebase to latest master branch.
drop patches for callback functions
revise VF id checks in new librte_ether functions
revise testpmd commands for new API's

Changes in V2:
rebase to latest master branch.
fix compile  error with clang.

Bernard Iremonger (2):
  net/ixgbe: add API's for VF management
  app/test_pmd: add tests for new API's

 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 drivers/net/ixgbe/Makefile                  |   4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 240 ++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 182 ++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  13 +
 6 files changed, 1172 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

-- 
2.9.0

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

* [PATCH v7 1/2] net/ixgbe: add API's for VF management
  2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 0/2] " Bernard Iremonger
@ 2016-10-07 10:45           ` Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 2/2] app/test_pmd: add tests for new API's Bernard Iremonger
  2 siblings, 0 replies; 94+ messages in thread
From: Bernard Iremonger @ 2016-10-07 10:45 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

Add API's to configure and manage VF's on an Intel 82559 NIC.

add rte_pmd_ixgbe_set_vf_vlan_anti_spoof function.
add rte_pmd_ixgbe_set_vf_mac_anti_spoof function.
add rte_pmd_ixgbe_set_vf_stripq function.

Signed-off-by: Alex Zelezniak <az5157@att.com>

add rte_pmd_ixgbe_set_vf_vlan_insert function.
add rte_pmd_ixgbe_set_tx_loopback function.
add rte_pmd_ixgbe_set_all_queues_drop function.
add rte_pmd_ixgbe_set_vf_split_drop_en function.
add rte_pmd_ixgbe_set_vf_mac_addr function.

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/ixgbe/Makefile                  |   4 +-
 drivers/net/ixgbe/ixgbe_ethdev.c            | 240 ++++++++++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe.h           | 182 +++++++++++++++++++++
 drivers/net/ixgbe/rte_pmd_ixgbe_version.map |  13 ++
 4 files changed, 438 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h

diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index a6c71f3..94ddc7b 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -119,6 +119,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c
 SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c
 endif
 
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)-include := rte_pmd_ixgbe.h
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 6b3d4fa..35281f9 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -72,6 +72,8 @@
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
 
+#include "rte_pmd_ixgbe.h"
+
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
  * least 8 bytes less than receive packet buffer size. This value is in units
@@ -4046,6 +4048,35 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 	ixgbe_add_rar(dev, addr, 0, 0);
 }
 
+int
+rte_pmd_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_vf_info *vfinfo;
+	int rar_entry;
+	uint8_t *new_mac = (uint8_t *)(mac_addr);
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+	rar_entry = hw->mac.num_rar_entries - (vf + 1);
+
+	if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+		rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, ETHER_ADDR_LEN);
+		return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV);
+	}
+	return -EINVAL;
+}
+
 static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
@@ -4639,6 +4670,215 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 	return ret;
 }
 
+int
+rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+
+	mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	struct ixgbe_mac_info *mac;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	mac = &hw->mac;
+	mac->ops.set_mac_anti_spoofing(hw, on, vf);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+	if (on) {
+		ctrl = on;
+		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+	} else {
+		ctrl = 0;
+	}
+
+	IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t ctrl;
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+	/* enable or disable VMDQ loopback */
+	if (on)
+		ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+	else
+		ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	int i;
+	int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	for (i = 0; i <= num_queues; i++) {
+		reg_value = IXGBE_QDE_WRITE |
+				(i << IXGBE_QDE_IDX_SHIFT) |
+				(on & IXGBE_QDE_ENABLE);
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+	}
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct ixgbe_hw *hw;
+	uint32_t reg_value;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	/* only support VF's 0 to 63 */
+	if ((vf >= dev_info.max_vfs) || (vf > 63))
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+	if (on)
+		reg_value |= IXGBE_SRRCTL_DROP_EN;
+	else
+		reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+
+	return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t queues_per_pool;
+	uint32_t q;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (on > 1)
+		return -EINVAL;
+
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+	/* The PF has 128 queue pairs and in SRIOV configuration
+	 * those queues will be assigned to VF's, so RXDCTL
+	 * registers will be dealing with queues which will be
+	 * assigned to VF's.
+	 * Let's say we have SRIOV configured with 31 VF's then the
+	 * first 124 queues 0-123 will be allocated to VF's and only
+	 * the last 4 queues 123-127 will be assigned to the PF.
+	 */
+
+	queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+
+	for (q = 0; q < queues_per_pool; q++)
+		(*dev->dev_ops->vlan_strip_queue_set)(dev, q + vf * queues_per_pool, on);
+	return 0;
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
new file mode 100644
index 0000000..2689668
--- /dev/null
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -0,0 +1,182 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2016 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.
+ */
+
+/**
+ * @file rte_pmd_ixgbe.h
+ * ixgbe PMD specific functions.
+ *
+ **/
+
+#ifndef _PMD_IXGBE_H_
+#define _PMD_IXGBE_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   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_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf, struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan insert.
+ *    0 - Disable VF's vlan insert
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf,	uint8_t on);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * set drop enable bit in the VF split rx control register
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - set the drop enable bit in the split rx control register.
+ *    0 - reset the drop enable bit in the split rx control register.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+#endif /* _PMD_IXGBE_H_ */
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index ef35398..92434f3 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -2,3 +2,16 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_16.11 {
+	global:
+
+	rte_pmd_ixgbe_set_all_queues_drop_en;
+	rte_pmd_ixgbe_set_tx_loopback;
+	rte_pmd_ixgbe_set_vf_mac_addr;
+	rte_pmd_ixgbe_set_vf_mac_anti_spoof;
+	rte_pmd_ixgbe_set_vf_split_drop_en;
+	rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
+	rte_pmd_ixgbe_set_vf_vlan_insert;
+	rte_pmd_ixgbe_set_vf_vlan_stripq;
+} DPDK_2.0;
-- 
2.9.0

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

* [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 0/2] " Bernard Iremonger
  2016-10-07 10:45           ` [PATCH v7 1/2] net/ixgbe: " Bernard Iremonger
@ 2016-10-07 10:45           ` Bernard Iremonger
  2016-10-11 15:09             ` Ferruh Yigit
  2 siblings, 1 reply; 94+ messages in thread
From: Bernard Iremonger @ 2016-10-07 10:45 UTC (permalink / raw)
  To: dev, rahul.r.shah, wenzhuo.lu, az5157; +Cc: Bernard Iremonger

add test for set vf vlan anti spoof
add test for set vf mac anti spoof
add test for set vf vlan stripq
add test for set vf vlan insert
add test for set tx loopback
add test for set all queues drop enable bit
add test for set vf split drop enable bit
add test for set vf mac address
add new API's to the testpmd guide

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  62 ++-
 2 files changed, 734 insertions(+), 3 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 17d238f..d26db62 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -87,6 +87,7 @@
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
+#include <rte_pmd_ixgbe.h>
 
 #include "testpmd.h"
 
@@ -10585,6 +10586,672 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
 	},
 };
 
+/* vf vlan anti spoof configuration */
+
+/* Common result structure for vf vlan anti spoof */
+struct cmd_vf_vlan_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
+	.f = cmd_set_vf_vlan_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_anti_spoof_set,
+		(void *)&cmd_vf_vlan_anti_spoof_vf,
+		(void *)&cmd_vf_vlan_anti_spoof_vlan,
+		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
+		(void *)&cmd_vf_vlan_anti_spoof_port_id,
+		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
+		(void *)&cmd_vf_vlan_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf mac anti spoof configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_mac_anti_spoof_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t antispoof;
+	uint8_t port_id;
+	uint32_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf mac anti spoof enable disable */
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 antispoof, "antispoof");
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_mac_anti_spoof_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_mac_anti_spoof_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
+	.f = cmd_set_vf_mac_anti_spoof_parsed,
+	.data = NULL,
+	.help_str = "set vf mac antispoof port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_mac_anti_spoof_set,
+		(void *)&cmd_vf_mac_anti_spoof_vf,
+		(void *)&cmd_vf_mac_anti_spoof_mac,
+		(void *)&cmd_vf_mac_anti_spoof_antispoof,
+		(void *)&cmd_vf_mac_anti_spoof_port_id,
+		(void *)&cmd_vf_mac_anti_spoof_vf_id,
+		(void *)&cmd_vf_mac_anti_spoof_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan strip queue configuration */
+
+/* Common result structure for vf mac anti spoof */
+struct cmd_vf_vlan_stripq_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t stripq;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan strip enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 stripq, "stripq");
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_stripq_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_stripq_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_stripq_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
+	.f = cmd_set_vf_vlan_stripq_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan stripq port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_stripq_set,
+		(void *)&cmd_vf_vlan_stripq_vf,
+		(void *)&cmd_vf_vlan_stripq_vlan,
+		(void *)&cmd_vf_vlan_stripq_stripq,
+		(void *)&cmd_vf_vlan_stripq_port_id,
+		(void *)&cmd_vf_vlan_stripq_vf_id,
+		(void *)&cmd_vf_vlan_stripq_on_off,
+		NULL,
+	},
+};
+
+/* vf vlan insert configuration */
+
+/* Common result structure for vf vlan insert */
+struct cmd_vf_vlan_insert_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t vlan;
+	cmdline_fixed_string_t insert;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan insert enable disable */
+cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vlan, "vlan");
+cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 insert, "insert");
+cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_vlan_insert_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_vlan_insert_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_insert_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_vlan_insert_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
+	.f = cmd_set_vf_vlan_insert_parsed,
+	.data = NULL,
+	.help_str = "set vf vlan insert port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_vlan_insert_set,
+		(void *)&cmd_vf_vlan_insert_vf,
+		(void *)&cmd_vf_vlan_insert_vlan,
+		(void *)&cmd_vf_vlan_insert_insert,
+		(void *)&cmd_vf_vlan_insert_port_id,
+		(void *)&cmd_vf_vlan_insert_vf_id,
+		(void *)&cmd_vf_vlan_insert_on_off,
+		NULL,
+	},
+};
+
+/* tx loopback configuration */
+
+/* Common result structure for tx loopback */
+struct cmd_tx_loopback_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t tx;
+	cmdline_fixed_string_t loopback;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_tx_loopback_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_tx_loopback_tx =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 tx, "tx");
+cmdline_parse_token_string_t cmd_tx_loopback_loopback =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 loopback, "loopback");
+cmdline_parse_token_num_t cmd_tx_loopback_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_tx_loopback_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_tx_loopback_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_tx_loopback_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_tx_loopback_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_tx_loopback = {
+	.f = cmd_set_tx_loopback_parsed,
+	.data = NULL,
+	.help_str = "set tx loopback port_id on|off",
+	.tokens = {
+		(void *)&cmd_tx_loopback_set,
+		(void *)&cmd_tx_loopback_tx,
+		(void *)&cmd_tx_loopback_loopback,
+		(void *)&cmd_tx_loopback_port_id,
+		(void *)&cmd_tx_loopback_on_off,
+		NULL,
+	},
+};
+
+/* all queues drop enable configuration */
+
+/* Common result structure for all queues drop enable */
+struct cmd_all_queues_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t all;
+	cmdline_fixed_string_t queues;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for tx loopback enable disable */
+cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 all, "all");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 queues, "queues");
+cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_all_queues_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_all_queues_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_all_queues_drop_en_result *res = parsed_result;
+	int ret = 0;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid is_on %d\n", is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
+	.f = cmd_set_all_queues_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set all queues drop port_id on|off",
+	.tokens = {
+		(void *)&cmd_all_queues_drop_en_set,
+		(void *)&cmd_all_queues_drop_en_all,
+		(void *)&cmd_all_queues_drop_en_queues,
+		(void *)&cmd_all_queues_drop_en_drop,
+		(void *)&cmd_all_queues_drop_en_port_id,
+		(void *)&cmd_all_queues_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf split drop enable configuration */
+
+/* Common result structure for vf split drop enable */
+struct cmd_vf_split_drop_en_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t split;
+	cmdline_fixed_string_t drop;
+	uint8_t port_id;
+	uint16_t vf_id;
+	cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 split, "split");
+cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 drop, "drop");
+cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 vf_id, UINT16);
+cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_vf_split_drop_en_result,
+		 on_off, "on#off");
+
+static void
+cmd_set_vf_split_drop_en_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_vf_split_drop_en_result *res = parsed_result;
+	int ret;
+	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+
+	ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res->vf_id, is_on);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
+	.f = cmd_set_vf_split_drop_en_parsed,
+	.data = NULL,
+	.help_str = "set vf split drop port_id vf_id on|off",
+	.tokens = {
+		(void *)&cmd_vf_split_drop_en_set,
+		(void *)&cmd_vf_split_drop_en_vf,
+		(void *)&cmd_vf_split_drop_en_split,
+		(void *)&cmd_vf_split_drop_en_drop,
+		(void *)&cmd_vf_split_drop_en_port_id,
+		(void *)&cmd_vf_split_drop_en_vf_id,
+		(void *)&cmd_vf_split_drop_en_on_off,
+		NULL,
+	},
+};
+
+/* vf mac address configuration */
+
+/* Common result structure for vf mac address */
+struct cmd_set_vf_mac_addr_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t vf;
+	cmdline_fixed_string_t mac;
+	cmdline_fixed_string_t addr;
+	uint8_t port_id;
+	uint16_t vf_id;
+	struct ether_addr mac_addr;
+
+};
+
+/* Common CLI fields for vf split drop enable disable */
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 set, "set");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 mac, "mac");
+cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
+	TOKEN_STRING_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 addr, "addr");
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
+	TOKEN_NUM_INITIALIZER
+		(struct cmd_set_vf_mac_addr_result,
+		 vf_id, UINT16);
+cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
+		 mac_addr);
+
+static void
+cmd_set_vf_mac_addr_parsed(
+	void *parsed_result,
+	__attribute__((unused)) struct cmdline *cl,
+	__attribute__((unused)) void *data)
+{
+	struct cmd_set_vf_mac_addr_result *res = parsed_result;
+	int ret;
+
+	ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id, &res->mac_addr);
+	switch (ret) {
+	case 0:
+		break;
+	case -EINVAL:
+		printf("invalid vf_id %d or mac_addr\n", res->vf_id);
+		break;
+	case -ENODEV:
+		printf("invalid port_id %d\n", res->port_id);
+		break;
+	default:
+		printf("programming error: (%s)\n", strerror(-ret));
+	}
+}
+
+cmdline_parse_inst_t cmd_set_vf_mac_addr = {
+	.f = cmd_set_vf_mac_addr_parsed,
+	.data = NULL,
+	.help_str = "set vf mac addr port_id vf_id xx:xx:xx:xx:xx:xx",
+	.tokens = {
+		(void *)&cmd_set_vf_mac_addr_set,
+		(void *)&cmd_set_vf_mac_addr_vf,
+		(void *)&cmd_set_vf_mac_addr_mac,
+		(void *)&cmd_set_vf_mac_addr_addr,
+		(void *)&cmd_set_vf_mac_addr_port_id,
+		(void *)&cmd_set_vf_mac_addr_vf_id,
+		(void *)&cmd_set_vf_mac_addr_mac_addr,
+		NULL,
+	},
+};
+
+
+/* get PMD dev_ops handle */
+
+/* Common result structure for vf mac address */
+struct cmd_get_pmd_handle_result {
+	cmdline_fixed_string_t get;
+	cmdline_fixed_string_t pmd;
+	cmdline_fixed_string_t handle;
+	uint8_t port_id;
+};
+
+
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -10739,6 +11406,14 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
+	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
+	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
+	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	NULL,
 };
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f87e0c2..145c425 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -473,6 +473,34 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set tx loopback
+~~~~~~~~~~~~~~~
+
+Enable/disable tx loopback::
+
+   testpmd> set tx loopback (port_id) (on|off)
+
+set drop enable
+~~~~~~~~~~~~~~~
+
+set drop enable bit for all queues::
+
+   testpmd> set all queues drop (port_id) (on|off)
+
+set split drop enable (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+set split drop enable bit for VF from PF::
+
+   testpmd> set vf split drop (port_id) (vf_id) (on|off)
+
+set mac antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set mac antispoof for a VF from the PF::
+
+   testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
+
 vlan set strip
 ~~~~~~~~~~~~~~
 
@@ -487,6 +515,27 @@ Set the VLAN strip for a queue on a port::
 
    testpmd> vlan set stripq (on|off) (port_id,queue_id)
 
+vlan set stripq (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN strip for all queues in a pool for a VF from the PF::
+
+   testpmd> set vf vlan stripq (port_id) (vf_id) (on|off)
+
+vlan set insert (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN insert for a VF from the PF::
+
+   testpmd> set vf vlan insert (port_id) (vf_id) (on|off)
+
+vlan set antispoof (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN antispoof for a VF from the PF::
+
+   testpmd> set vf vlan antispoof (port_id) (vf_id) (on|off)
+
 vlan set filter
 ~~~~~~~~~~~~~~~
 
@@ -727,13 +776,20 @@ Remove a MAC address from a port::
 
    testpmd> mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)
 
-mac_addr add(for VF)
-~~~~~~~~~~~~~~~~~~~~
+mac_addr add (for VF)
+~~~~~~~~~~~~~~~~~~~~~
 
 Add an alternative MAC address for a VF to a port::
 
    testpmd> mac_add add port (port_id) vf (vf_id) (XX:XX:XX:XX:XX:XX)
 
+mac_addr set (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set the MAC address for a VF from the PF::
+
+   testpmd> set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)
+
 set port-uta
 ~~~~~~~~~~~~
 
-- 
2.9.0

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-07 10:45           ` [PATCH v7 2/2] app/test_pmd: add tests for new API's Bernard Iremonger
@ 2016-10-11 15:09             ` Ferruh Yigit
  2016-10-11 15:41               ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Ferruh Yigit @ 2016-10-11 15:09 UTC (permalink / raw)
  To: Bernard Iremonger, dev, rahul.r.shah, wenzhuo.lu, az5157

Hi Bernard,

On 10/7/2016 11:45 AM, Bernard Iremonger wrote:
> add test for set vf vlan anti spoof
> add test for set vf mac anti spoof
> add test for set vf vlan stripq
> add test for set vf vlan insert
> add test for set tx loopback
> add test for set all queues drop enable bit
> add test for set vf split drop enable bit
> add test for set vf mac address
> add new API's to the testpmd guide
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
>  app/test-pmd/cmdline.c                      | 675 ++++++++++++++++++++++++++++

This will cause a compilation error for shared libraries. Because PMDs
not linked against application when compiled as shared library but used
as plugins.

Since it has been decided to have NIC specific APIs, we need to re-work
that approach to fix shared library compilation.

Thanks,
ferruh

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-11 15:09             ` Ferruh Yigit
@ 2016-10-11 15:41               ` Thomas Monjalon
  2016-10-11 15:51                 ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-10-11 15:41 UTC (permalink / raw)
  To: Ferruh Yigit, Bernard Iremonger; +Cc: dev, rahul.r.shah, wenzhuo.lu, az5157

2016-10-11 16:09, Ferruh Yigit:
> This will cause a compilation error for shared libraries. Because PMDs
> not linked against application when compiled as shared library but used
> as plugins.
> 
> Since it has been decided to have NIC specific APIs, we need to re-work
> that approach to fix shared library compilation.

If testpmd uses the ixgbe API, it must be linked with the PMD.
Is there any issue adapting the testpmd makefile?
Hope that dlopen an already linked PMD is nicely managed.

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-11 15:41               ` Thomas Monjalon
@ 2016-10-11 15:51                 ` Iremonger, Bernard
  2016-10-11 16:32                   ` Thomas Monjalon
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-10-11 15:51 UTC (permalink / raw)
  To: Thomas Monjalon, Yigit, Ferruh; +Cc: dev, Shah, Rahul R, Lu, Wenzhuo, az5157

Hi Thomas,

<snip>

> Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for new
> API's
> 
> 2016-10-11 16:09, Ferruh Yigit:
> > This will cause a compilation error for shared libraries. Because PMDs
> > not linked against application when compiled as shared library but
> > used as plugins.
> >
> > Since it has been decided to have NIC specific APIs, we need to
> > re-work that approach to fix shared library compilation.
> 
> If testpmd uses the ixgbe API, it must be linked with the PMD.
> Is there any issue adapting the testpmd makefile?
> Hope that dlopen an already linked PMD is nicely managed.

The ixgbe API will  be used by other apps, for example Virtual Function Daemon (VFD)
Moving the following line in rte.app.mak solves the problem

Line 117: _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe

To Line 103.

Will this be acceptable?

Regards,

Bernard.

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-11 15:51                 ` Iremonger, Bernard
@ 2016-10-11 16:32                   ` Thomas Monjalon
  2016-10-11 16:35                     ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: Thomas Monjalon @ 2016-10-11 16:32 UTC (permalink / raw)
  To: Iremonger, Bernard; +Cc: Yigit, Ferruh, dev, Shah, Rahul R, Lu, Wenzhuo, az5157

2016-10-11 15:51, Iremonger, Bernard:
> Hi Thomas,
> 
> <snip>
> 
> > Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for new
> > API's
> > 
> > 2016-10-11 16:09, Ferruh Yigit:
> > > This will cause a compilation error for shared libraries. Because PMDs
> > > not linked against application when compiled as shared library but
> > > used as plugins.
> > >
> > > Since it has been decided to have NIC specific APIs, we need to
> > > re-work that approach to fix shared library compilation.
> > 
> > If testpmd uses the ixgbe API, it must be linked with the PMD.
> > Is there any issue adapting the testpmd makefile?
> > Hope that dlopen an already linked PMD is nicely managed.
> 
> The ixgbe API will  be used by other apps, for example Virtual Function Daemon (VFD)
> Moving the following line in rte.app.mak solves the problem
> 
> Line 117: _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
> 
> To Line 103.
> 
> Will this be acceptable?

I think we must not link PMD in the general case but let this
responsibility to the application in case it uses some specific
functions.
Does it make sense?

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-11 16:32                   ` Thomas Monjalon
@ 2016-10-11 16:35                     ` Iremonger, Bernard
  2016-10-12  2:05                       ` De Lara Guarch, Pablo
  0 siblings, 1 reply; 94+ messages in thread
From: Iremonger, Bernard @ 2016-10-11 16:35 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Yigit, Ferruh, dev, Shah, Rahul R, Lu, Wenzhuo, az5157

Hi Thomas,

<snip>

> > > Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for
> > > new API's
> > >
> > > 2016-10-11 16:09, Ferruh Yigit:
> > > > This will cause a compilation error for shared libraries. Because
> > > > PMDs not linked against application when compiled as shared
> > > > library but used as plugins.
> > > >
> > > > Since it has been decided to have NIC specific APIs, we need to
> > > > re-work that approach to fix shared library compilation.
> > >
> > > If testpmd uses the ixgbe API, it must be linked with the PMD.
> > > Is there any issue adapting the testpmd makefile?
> > > Hope that dlopen an already linked PMD is nicely managed.
> >
> > The ixgbe API will  be used by other apps, for example Virtual
> > Function Daemon (VFD) Moving the following line in rte.app.mak solves
> > the problem
> >
> > Line 117: _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -
> lrte_pmd_ixgbe
> >
> > To Line 103.
> >
> > Will this be acceptable?
> 
> I think we must not link PMD in the general case but let this responsibility to
> the application in case it uses some specific functions.
> Does it make sense?

Yes, ok, will just modify the testpmd makefile  for this case.

Regards,

Bernard.

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-11 16:35                     ` Iremonger, Bernard
@ 2016-10-12  2:05                       ` De Lara Guarch, Pablo
  2016-10-12 15:00                         ` Iremonger, Bernard
  0 siblings, 1 reply; 94+ messages in thread
From: De Lara Guarch, Pablo @ 2016-10-12  2:05 UTC (permalink / raw)
  To: Iremonger, Bernard, Thomas Monjalon
  Cc: Yigit, Ferruh, dev, Shah, Rahul R, Lu, Wenzhuo, az5157

Hi,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Iremonger, Bernard
> Sent: Tuesday, October 11, 2016 9:35 AM
> To: Thomas Monjalon
> Cc: Yigit, Ferruh; dev@dpdk.org; Shah, Rahul R; Lu, Wenzhuo;
> az5157@att.com
> Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for new API's
> 
> Hi Thomas,
> 
> <snip>
> 
> > > > Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for
> > > > new API's
> > > >
> > > > 2016-10-11 16:09, Ferruh Yigit:
> > > > > This will cause a compilation error for shared libraries. Because
> > > > > PMDs not linked against application when compiled as shared
> > > > > library but used as plugins.
> > > > >
> > > > > Since it has been decided to have NIC specific APIs, we need to
> > > > > re-work that approach to fix shared library compilation.
> > > >
> > > > If testpmd uses the ixgbe API, it must be linked with the PMD.
> > > > Is there any issue adapting the testpmd makefile?
> > > > Hope that dlopen an already linked PMD is nicely managed.
> > >
> > > The ixgbe API will  be used by other apps, for example Virtual
> > > Function Daemon (VFD) Moving the following line in rte.app.mak solves
> > > the problem
> > >
> > > Line 117: _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -
> > lrte_pmd_ixgbe
> > >
> > > To Line 103.
> > >
> > > Will this be acceptable?
> >
> > I think we must not link PMD in the general case but let this responsibility to
> > the application in case it uses some specific functions.
> > Does it make sense?
> 
> Yes, ok, will just modify the testpmd makefile  for this case.

A couple of things:
You would need to use #ifdef RTE_LIBRTE_IXGBE_PMD in testpmd, right?
In case IXGBE is not available (maybe just modifying the makefile solves the problem).

Could you also add these new functions in the testpmd help?
Just add them in cmd_help_long_parsed.

Thanks,
Pablo

> 
> Regards,
> 
> Bernard.

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

* Re: [PATCH v7 2/2] app/test_pmd: add tests for new API's
  2016-10-12  2:05                       ` De Lara Guarch, Pablo
@ 2016-10-12 15:00                         ` Iremonger, Bernard
  0 siblings, 0 replies; 94+ messages in thread
From: Iremonger, Bernard @ 2016-10-12 15:00 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Thomas Monjalon
  Cc: Yigit, Ferruh, dev, Shah, Rahul R, Lu, Wenzhuo, az5157

Hi Pablo,

<snip>

> > Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests for new
> > API's
> >
> > Hi Thomas,
> >
> > <snip>
> >
> > > > > Subject: Re: [dpdk-dev] [PATCH v7 2/2] app/test_pmd: add tests
> > > > > for new API's
> > > > >
> > > > > 2016-10-11 16:09, Ferruh Yigit:
> > > > > > This will cause a compilation error for shared libraries.
> > > > > > Because PMDs not linked against application when compiled as
> > > > > > shared library but used as plugins.
> > > > > >
> > > > > > Since it has been decided to have NIC specific APIs, we need
> > > > > > to re-work that approach to fix shared library compilation.
> > > > >
> > > > > If testpmd uses the ixgbe API, it must be linked with the PMD.
> > > > > Is there any issue adapting the testpmd makefile?
> > > > > Hope that dlopen an already linked PMD is nicely managed.
> > > >
> > > > The ixgbe API will  be used by other apps, for example Virtual
> > > > Function Daemon (VFD) Moving the following line in rte.app.mak
> > > > solves the problem
> > > >
> > > > Line 117: _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -
> > > lrte_pmd_ixgbe
> > > >
> > > > To Line 103.
> > > >
> > > > Will this be acceptable?
> > >
> > > I think we must not link PMD in the general case but let this
> > > responsibility to the application in case it uses some specific functions.
> > > Does it make sense?
> >
> > Yes, ok, will just modify the testpmd makefile  for this case.
> 
> A couple of things:
> You would need to use #ifdef RTE_LIBRTE_IXGBE_PMD in testpmd, right?
> In case IXGBE is not available (maybe just modifying the makefile solves the
> problem).
> 
> Could you also add these new functions in the testpmd help?
> Just add them in cmd_help_long_parsed.
> 
> Thanks,
> Pablo

I have added #ifdef RTE_LIBRTE_IXGBE_PMD in testpmd.
The make file is modified to handle ixgbe PMD present and not present in shared library mode and default mode.
I have added the new functions to the testpmd help.

Thanks for reviewing.

Regards,

Bernard.

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

end of thread, other threads:[~2016-10-12 15:00 UTC | newest]

Thread overview: 94+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-18 13:48 [RFC PATCH 0/5] add API's for VF management Bernard Iremonger
2016-08-18 13:48 ` [RFC PATCH 1/5] librte_ether: add internal callback functions Bernard Iremonger
2016-08-18 13:48 ` [RFC PATCH 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
2016-08-18 13:48 ` [RFC PATCH 3/5] librte_ether: add API's for VF management Bernard Iremonger
2016-08-18 13:48 ` [RFC PATCH 4/5] net/ixgbe: add functions " Bernard Iremonger
2016-08-18 13:48 ` [RFC PATCH 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
2016-08-26  9:10 ` [RFC PATCH v2 0/5] add API's for VF management Bernard Iremonger
2016-08-26  9:10   ` [RFC PATCH v2 1/5] librte_ether: add internal callback functions Bernard Iremonger
2016-09-09 14:10     ` Jerin Jacob
     [not found]       ` <3C0218D8B3DD114D8DBFE6B68141FBE3185F9FE7@MISOUT7MSGUSRDI.ITServices.sbc.com>
2016-09-13  8:45         ` Jerin Jacob
     [not found]           ` <3C0218D8B3DD114D8DBFE6B68141FBE3185FDCDC@MISOUT7MSGUSRDI.ITServices.sbc.com>
2016-09-14 11:28             ` Jerin Jacob
2016-09-22 11:25               ` Iremonger, Bernard
2016-10-03  8:58               ` Iremonger, Bernard
2016-08-26  9:10   ` [RFC PATCH v2 2/5] net/ixgbe: add callback to user app on VF to PF mbox msg Bernard Iremonger
2016-08-26  9:10   ` [RFC PATCH v2 3/5] librte_ether: add API's for VF management Bernard Iremonger
2016-09-09 14:22     ` Jerin Jacob
2016-09-12 16:28       ` Iremonger, Bernard
2016-09-13  9:24         ` Thomas Monjalon
2016-09-15 16:46           ` Iremonger, Bernard
2016-09-22 17:04             ` Thomas Monjalon
2016-09-23  9:20               ` Bruce Richardson
2016-09-23  9:36                 ` Thomas Monjalon
2016-09-23  9:53                   ` Richardson, Bruce
2016-09-23 13:15                     ` Thomas Monjalon
2016-09-23 17:02                       ` Iremonger, Bernard
2016-09-23 17:18                         ` Thomas Monjalon
2016-09-26 15:37                           ` Iremonger, Bernard
2016-09-26 16:59                             ` Thomas Monjalon
2016-09-27 10:31                               ` Iremonger, Bernard
2016-09-27 13:01                                 ` Bruce Richardson
2016-09-27 14:13                                   ` Iremonger, Bernard
2016-09-28 11:23                                     ` Ananyev, Konstantin
2016-09-28 12:31                                       ` Iremonger, Bernard
2016-09-28 13:01                                       ` Richardson, Bruce
2016-09-28 13:03                                       ` Thomas Monjalon
2016-09-28 13:26                                         ` Ananyev, Konstantin
2016-09-28 14:24                                           ` Thomas Monjalon
2016-09-28 14:30                                             ` Ananyev, Konstantin
2016-09-28 14:48                                               ` Iremonger, Bernard
2016-09-28 15:00                                                 ` Thomas Monjalon
2016-09-28 15:24                                                   ` Iremonger, Bernard
2016-09-28 14:59                                               ` Thomas Monjalon
2016-09-28 16:52                                                 ` Ananyev, Konstantin
2016-09-28 18:02                                                   ` Thomas Monjalon
2016-09-30  9:21                                                     ` Bruce Richardson
2016-09-23 10:34                   ` Bruce Richardson
2016-08-26  9:10   ` [RFC PATCH v2 4/5] net/ixgbe: add functions " Bernard Iremonger
2016-08-26  9:10   ` [RFC PATCH v2 5/5] app/test_pmd: add tests for new API's Bernard Iremonger
2016-09-11 12:35     ` Yuanhan Liu
2016-09-12 15:57       ` Iremonger, Bernard
2016-09-13  4:34         ` Yuanhan Liu
2016-09-13  8:38           ` Iremonger, Bernard
2016-09-13  8:42             ` Yuanhan Liu
2016-09-07  9:18   ` [RFC PATCH v2 0/5] add API's for VF management Pattan, Reshma
2016-09-09  8:49   ` Pattan, Reshma
2016-09-09 13:02     ` Thomas Monjalon
2016-09-16 11:05   ` [PATCH v3 0/3] " Bernard Iremonger
2016-09-16 11:05   ` [PATCH v3 1/3] librte_ether: " Bernard Iremonger
2016-09-16 11:05   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
2016-09-16 11:05   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
2016-09-16 14:15   ` [PATCH v3 0/3] add API's for VF management Bernard Iremonger
2016-09-21 10:20     ` [PATCH v4 " Bernard Iremonger
2016-09-29 14:16       ` [PATCH v5 " Bernard Iremonger
2016-09-30 10:30         ` [PATCH v6 0/2] " Bernard Iremonger
2016-09-30 10:30         ` [PATCH v6 1/2] net/ixgbe: " Bernard Iremonger
2016-10-07 10:45           ` [PATCH v7 0/2] " Bernard Iremonger
2016-10-07 10:45           ` [PATCH v7 1/2] net/ixgbe: " Bernard Iremonger
2016-10-07 10:45           ` [PATCH v7 2/2] app/test_pmd: add tests for new API's Bernard Iremonger
2016-10-11 15:09             ` Ferruh Yigit
2016-10-11 15:41               ` Thomas Monjalon
2016-10-11 15:51                 ` Iremonger, Bernard
2016-10-11 16:32                   ` Thomas Monjalon
2016-10-11 16:35                     ` Iremonger, Bernard
2016-10-12  2:05                       ` De Lara Guarch, Pablo
2016-10-12 15:00                         ` Iremonger, Bernard
2016-09-30 10:30         ` [PATCH v6 " Bernard Iremonger
2016-09-29 14:16       ` [PATCH v5 1/3] librte_ether: add API for VF management Bernard Iremonger
2016-09-29 14:30         ` Thomas Monjalon
2016-09-29 15:16           ` Iremonger, Bernard
2016-09-29 16:19             ` Thomas Monjalon
2016-09-29 16:38               ` Iremonger, Bernard
2016-09-29 16:45                 ` Thomas Monjalon
2016-09-29 14:16       ` [PATCH v5 2/3] net/ixgbe: add API's " Bernard Iremonger
2016-09-29 16:11         ` Reshma Pattan
2016-09-29 16:32           ` Iremonger, Bernard
2016-09-29 16:16         ` Pattan, Reshma
2016-09-29 16:30           ` Iremonger, Bernard
2016-09-29 14:16       ` [PATCH v5 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
2016-09-21 10:20     ` [PATCH v4 1/3] librte_ether: add API's for VF management Bernard Iremonger
2016-09-21 10:20     ` [PATCH v4 2/3] net/ixgbe: add functions " Bernard Iremonger
2016-09-21 10:20     ` [PATCH v4 3/3] app/test_pmd: add tests for new API's Bernard Iremonger
2016-09-16 14:15   ` [PATCH v3 1/3] librte_ether: add API's for VF management Bernard Iremonger
2016-09-16 14:15   ` [PATCH v3 2/3] net/ixgbe: add functions " Bernard Iremonger
2016-09-16 14:15   ` [PATCH v3 3/3] app/test_pmd: add tests for new API's Bernard Iremonger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.