Discussion:
[dpdk-dev] [PATCH v3 0/2] add callbacks for VF management
(too old to reply)
Bernard Iremonger
2016-09-30 15:45:06 UTC
Permalink
This patchset contains new callback functions requested by AT&T for use
with the Virtual Function Daemon (VFD).

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

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16296/
[dpdk-dev,v6,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v3:
rebase to latest master
submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Bernard Iremonger (2):
librte_ether: add internal callback functions
net/ixgbe: add callback to user app on VF to PF mbox msg

drivers/net/ixgbe/ixgbe_pf.c | 42 ++++++++++++++++++++++++----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 11 ++++++++
lib/librte_ether/rte_ethdev.c | 17 ++++++++++++
lib/librte_ether/rte_ethdev.h | 51 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 7 +++++
5 files changed, 122 insertions(+), 6 deletions(-)
--
2.9.0
Bernard Iremonger
2016-09-30 15:45:07 UTC
Permalink
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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
lib/librte_ether/rte_ethdev.c | 17 ++++++++++++
lib/librte_ether/rte_ethdev.h | 51 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 7 +++++
3 files changed, 75 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..6d93fcf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2689,6 +2689,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;

@@ -2698,6 +2712,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 96575e8..a61905c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3051,9 +3051,17 @@ 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 */
};

+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 */
@@ -3118,6 +3126,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
Stephen Hemminger
2016-10-02 09:12:43 UTC
Permalink
I know callbacks are needed, in fact even more are necessary. That is why
I don't like this design. It expands the API for each event. I think
something like the Linux kernel netlink callback mechanism that passes an
event and device handle.
Iremonger, Bernard
2016-10-03 15:29:59 UTC
Permalink
Hi Stephen,

From: Stephen Hemminger [mailto:***@networkplumber.org]
Sent: Sunday, October 2, 2016 10:13 AM
To: Iremonger, Bernard <***@intel.com>
Cc: ***@dpdk.org; Lu, Wenzhuo <***@intel.com>; ***@caviumnetworks.com; ***@att.com; Shah, Rahul R <***@intel.com>
Subject: Re: [dpdk-dev] [PATCH v3 1/2] librte_ether: add internal callback functions


I know callbacks are needed, in fact even more are necessary. That is why I don't like this design. It expands the API for each event. I think something like the Linux kernel netlink callback mechanism that passes an event and device handle.

The current rte_eth_dev_callback_register() function takes a parameter void *cb_arg. This allows the passing of a parameter to the callback. For the events RTE_ETH_EVENT_QUEUE_STATE, RTE_ETH_EVENT_INTR_RESET the callback parameter is not used. In some cases for the RTE_ETH_EVENT_INTR_LSC the call back parameter is used.

This patch adds a new event RTE_ETH_VF_MBOX and a parameter for this event struct rte_eth_mb_event_param{}. This parameter is only used with the RTE_ETH_VF_MBOX event and does not affect the other events.

The struct rte_eth_mb_event_param{} should probably not be in rte_eth_dev.h, I will send a v4.

Regards,

Bernard.
Bernard Iremonger
2016-09-30 15:45:08 UTC
Permalink
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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 11 ++++++++++
2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..3c5bf38 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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 +676,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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 33b5b2d..212cc5d 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -181,4 +181,15 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Bernard Iremonger
2016-10-04 14:52:12 UTC
Permalink
This patchset contains new callback functions intended for VF management.

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

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16296/
[dpdk-dev,v6,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v4:
Rebased to latest master.
Moved the callback parameter structure from the ethdev to the ixgbe PMD.

Changes in v3:
Rebased to latest master.
Submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Changes in v2:
Rebased to latest master.

Bernard Iremonger (2):
librte_ether: add internal callback functions
net/ixgbe: add callback to user app on VF to PF mbox msg

drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++-----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 +++++++++++++
lib/librte_ether/rte_ethdev.c | 17 +++++++++++++
lib/librte_ether/rte_ethdev.h | 44 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 2 ++
5 files changed, 116 insertions(+), 6 deletions(-)
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:18 UTC
Permalink
This patchset modifies the callback function for VF management.

A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16296/
[dpdk-dev,v6,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v5:
Rebased to latest master.
Added parameter to the _rte_eth_dev_callback_process function
Removed two new callback functions which were added previously.
Updated all calls to the _rte_eth_dev_callback_process function.

Changes in v4:
Rebased to latest master.
Moved the callback parameter structure from the ethdev to the ixgbe PMD.

Changes in v3:
Rebased to latest master.
Submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Changes in v2:
Rebased to latest master.




















Bernard Iremonger (13):
librte_ether: modify internal callback function
net/ixgbe: add callback to user app on VF to PF mbox msg
app/test: add parameter to callback process function
net/bonding: add parameter to callback process function
net/e1000: add parameter to callback process function
net/i40e: update call to callback process function
net/mlx4: add parameter to callback process function
net/mlx5: add parameter to callback process function
net/nfp: add parameter to callback process function
net/thunderx: add parameter to callback process function
net/vhost: add parameter to callback process function
net/virtio: add parameter to callback process function
net/enic: add parameter to callback process function

app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 ++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++-----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 ++++++++++++++
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 ++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 +++-
lib/librte_ether/rte_ethdev.h | 7 +++++-
18 files changed, 86 insertions(+), 31 deletions(-)
--
2.9.0
Bernard Iremonger
2016-10-06 16:48:08 UTC
Permalink
This patchset modifies the callback function for VF management.

A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16296/
[dpdk-dev,v6,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v5:
Rebased to latest master.
Squashed patches down to two patches.
Renamed parameter to _rte_eth_dev_callback_process function.
Updated API descriptions.

Changes in v5:
Rebased to latest master.
Added parameter to the _rte_eth_dev_callback_process function
Removed two new callback functions which were added previously.
Updated all calls to the _rte_eth_dev_callback_process function.

Changes in v4:
Rebased to latest master.
Moved the callback parameter structure from the ethdev to the ixgbe PMD.

Changes in v3:
Rebased to latest master.
Submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Changes in v2:
Rebased to latest master.




















Bernard Iremonger (2):
librte_ether: modify internal callback function
net/ixgbe: add callback to user app on VF to PF mbox msg

app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 ++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++-----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 ++++++++++++++
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 ++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 +++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++-
18 files changed, 91 insertions(+), 31 deletions(-)
--
2.9.0
Bernard Iremonger
2016-10-07 16:46:22 UTC
Permalink
This patchset modifies the callback function for VF management.

A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16430/
[dpdk-dev,v7,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v7:
Rebased to latest master.
Move references to _rte_eth_dev_callback_process in ixgbe patch
to librte_ether patch.
Revised description of callback parameter.

Changes in v6:
Rebased to latest master.
Squashed patches down to two patches.
Renamed parameter to _rte_eth_dev_callback_process function.
Updated API descriptions.

Changes in v5:
Rebased to latest master.
Added parameter to the _rte_eth_dev_callback_process function
Removed two new callback functions which were added previously.
Updated all calls to the _rte_eth_dev_callback_process function.

Changes in v4:
Rebased to latest master.
Moved the callback parameter structure from the ethdev to the ixgbe PMD.

Changes in v3:
Rebased to latest master.
Submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Changes in v2:
Rebased to latest master.

Bernard Iremonger (2):
librte_ether: modify internal callback function
net/ixgbe: add callback to user app on VF to PF mbox msg

app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 ++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++-----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 20 ++++++++++++++++
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 ++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 +++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++-
18 files changed, 94 insertions(+), 31 deletions(-)
--
2.9.0
Thomas Monjalon
2016-10-07 22:52:49 UTC
Permalink
Post by Bernard Iremonger
This patchset modifies the callback function for VF management.
A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.
This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16430/
[dpdk-dev,v7,1/2] net/ixgbe: add API's for VF management
OK, this is probably a temporary solution.
I am OK to let it enter in DPDK 16.11 and starts some discussions.
That's why I'll try to sum up the situation for this patchset and
the other one (API for VF management).

The VF features are not yet enough standardized.
So the functions to manage them from the PF will be in some specific
headers (drivers/net/ixgbe/rte_pmd_ixgbe.h in this case).
They could be promoted in the generic ethdev API if it appears to be
generic enough.
There can be also some application callbacks called from the drivers
with a specific signature:
- a "generic" event type for VF
- a specific parameter defined in the driver
Obviously, we cannot have different meanings of this event depending
on the driver in use. So we must have something more robust when
implementing such feature in a second driver.

As there is no obvious solution, the pragmatic approach is to
accept this first specific implementation while waiting for a better idea.
Bernard Iremonger
2016-10-10 14:34:13 UTC
Permalink
This patchset modifies the callback function for VF management.

A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.

This patchset depends on the following patch.
http://dpdk.org/dev/patchwork/patch/16430/
[dpdk-dev,v7,1/2] net/ixgbe: add API's for VF management

These patches were part of the RFC PATCH v2 of the above patchset,
but were dropped from the v3 patchset.

Changes in v8:
Rebased to latest master.
Improve description of struct rte_pmd_ixgbe_mb_event_param,
rename member user_data to msg.

Changes in v7:
Rebased to latest master.
Move references to _rte_eth_dev_callback_process in ixgbe patch
to librte_ether patch.
Revised description of callback parameter.

Changes in v6:
Rebased to latest master.
Squashed patches down to two patches.
Renamed parameter to _rte_eth_dev_callback_process function.
Updated API descriptions.

Changes in v5:
Rebased to latest master.
Added parameter to the _rte_eth_dev_callback_process function
Removed two new callback functions which were added previously.
Updated all calls to the _rte_eth_dev_callback_process function.

Changes in v4:
Rebased to latest master.
Moved the callback parameter structure from the ethdev to the ixgbe PMD.

Changes in v3:
Rebased to latest master.
Submitted as a seperate patchset.
Moved the response enums from the ethdev to the ixgbe PMD.

Changes in v2:
Rebased to latest master.

Bernard Iremonger (2):
librte_ether: modify internal callback function
net/ixgbe: add callback to user app on VF to PF mbox msg

app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 ++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++-----
drivers/net/ixgbe/rte_pmd_ixgbe.h | 20 ++++++++++++++++
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 ++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 +++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++-
18 files changed, 94 insertions(+), 31 deletions(-)
--
2.9.0
Thomas Monjalon
2016-10-14 00:07:48 UTC
Permalink
Post by Bernard Iremonger
This patchset modifies the callback function for VF management.
A third parameter has been added to the _rte_eth_dev_callback_process
function. All references to this function have been updated.
Changes have been made to the ixgbe_rcv_msg_from_vf function to
use the new callback parameter.
Applied, thanks

Bernard Iremonger
2016-10-10 14:34:14 UTC
Permalink
add cb_arg parameter to the _rte_eth_dev_callback_process function.

Adding a parameter to this function allows passing information
to the application when an eth device event occurs such as
a VF to PF message.
This allows the application to decide if a particular function
is permitted.

drivers/net: add parameter to callback process function

add parameter to call of _rte_eth_dev_callback_process function
in the following PMD's:

net/bonding
net/e1000
net/i40e
net/enic
net/ixgbe
net/mlx4
net/mlx5
net/nfp
net/thunderx
net/vhost
net/virtio

app/test: add parameter to callback process function
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
Signed-off-by: Alex Zelezniak <***@att.com>
---
app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 +++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 +++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 ++++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++++-
16 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 4831113..65b44c6 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -485,7 +485,7 @@ virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,

vrtl_eth_dev->data->dev_link.link_status = link_status;

- _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb4050c..8d510e3 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1958,7 +1958,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg)
return;

_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

void
@@ -2079,7 +2079,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);

} else {
if (internals->link_down_delay_ms > 0)
@@ -2088,7 +2088,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}
}
}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index f767e1c..e13e858 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1599,7 +1599,7 @@ eth_em_interrupt_handler(__rte_unused struct rte_intr_handle *handle,

eth_em_interrupt_get_status(dev);
eth_em_interrupt_action(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 5a1a83e..d9ab2df 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2683,7 +2683,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
E1000_WRITE_FLUSH(hw);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

return 0;
@@ -2743,7 +2743,7 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == E1000_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15a05b4..fb72491 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -436,7 +436,7 @@ enic_intr_handler(__rte_unused struct rte_intr_handle *handle,
vnic_intr_return_all_credits(&enic->intr);

enic_link_update(enic);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
enic_log_q_error(enic);
}

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d0640b9..0dd396a 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5514,7 +5514,7 @@ i40e_dev_interrupt_delayed_handler(void *param)

/* handle the link up interrupt in an alarm callback */
i40e_dev_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

i40e_pf_enable_irq0(hw);
rte_intr_enable(&(dev->pci_dev->intr_handle));
@@ -5598,7 +5598,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
return;
else
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

done:
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 34eb274..bd89cd9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1341,7 +1341,7 @@ i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
switch (pf_msg->event) {
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event\n");
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
break;
case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event\n");
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 35281f9..b00aef3 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
@@ -7537,7 +7537,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 1553b2e..3e57cca 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5448,7 +5448,7 @@ mlx4_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -5471,7 +5471,7 @@ mlx4_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index bf4232a..c76e754 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1069,7 +1069,7 @@ mlx5_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -1092,7 +1092,7 @@ mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index d526f34..a2b9056 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1219,7 +1219,7 @@ nfp_net_dev_interrupt_delayed_handler(void *param)
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;

nfp_net_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

nfp_net_dev_link_status_print(dev);

diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b758c9f..c61e171 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -108,7 +108,7 @@ nicvf_interrupt(void *arg)
nicvf_set_eth_link_status(nic,
&nic->eth_dev->data->dev_link);
_rte_eth_dev_callback_process(nic->eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index c1d09a0..18a0c10 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -559,7 +559,7 @@ new_device(int vid)

RTE_LOG(INFO, PMD, "New connection established\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);

return 0;
}
@@ -626,7 +626,7 @@ destroy_device(int vid)

RTE_LOG(INFO, PMD, "Connection closed\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
@@ -655,7 +655,7 @@ vring_state_changed(int vid, uint16_t vring, int enable)
RTE_LOG(INFO, PMD, "vring%u is %s\n",
vring, enable ? "enabled" : "disabled");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE, NULL);

return 0;
}
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b4dfc0a..2f0065a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1103,7 +1103,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
if (isr & VIRTIO_PCI_ISR_CONFIG) {
if (virtio_dev_link_update(dev, 0) == 0)
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 88fa382..0d9d9c1 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t port_id,

void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *cb_arg)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
continue;
dev_cb = *cb_lst;
cb_lst->active = 1;
+ if (cb_arg != NULL)
+ dev_cb.cb_arg = (void *) cb_arg;
+
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 0a32ebb..351f972 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3030,6 +3030,7 @@ 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, /**< message from the VF received by PF */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};

@@ -3051,6 +3052,11 @@ typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
* @param cb_arg
* Pointer to the parameters for the registered callback.
*
+ * The user data is overwritten in the case of RTE_ETH_EVENT_VF_MBOX.
+ * This even occurs when a message from the VF is received by the PF.
+ * The user data is overwritten with struct rte_pmd_ixgbe_mb_event_param.
+ * This struct is defined in rte_pmd_ixgbe.h.
+ *
* @return
* - On success, zero.
* - On failure, a negative value.
@@ -3089,12 +3095,16 @@ int rte_eth_dev_callback_unregister(uint8_t port_id,
* Pointer to struct rte_eth_dev.
* @param event
* Eth device interrupt event type.
+ * @param cb_arg
+ * Update callback parameter to pass data back to user application.
+ * This allows the user application to decide if a particular function
+ * is permitted or not.
*
* @return
* void
*/
void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event);
+ enum rte_eth_event_type event, void *cb_arg);

/**
* When there is no rx packet coming in Rx Queue for a long time, we can
--
2.9.0
Bernard Iremonger
2016-10-10 14:34:15 UTC
Permalink
call _rte_eth_dev_callback_process 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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 20 +++++++++++++++++++
2 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..26395e4 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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_pmd_ixgbe_mb_event_param cb_param;

retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
if (retval) {
@@ -674,27 +676,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_PMD_IXGBE_MB_EVENT_PROCEED;
+ cb_param.vfid = vf;
+ cb_param.msg_type = msgbuf[0] & 0xFFFF;
+ cb_param.msg = (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(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_PMD_IXGBE_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(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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 2689668..74b64ad 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -179,4 +179,24 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
+/**
+ * Data sent to the user application when the callback is executed.
+ */
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid; /**< Virtual Function number */
+ uint16_t msg_type; /**< VF to PF message type, defined in ixgbe_mbx.h */
+ uint16_t retval; /**< return value */
+ void *msg; /**< pointer to message */
+};
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Bernard Iremonger
2016-10-12 15:03:14 UTC
Permalink
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 v8:
rebase to latest master branch.
add new API's to testpmd help command.
modify testpmd Makefile to build with and without ixgbe PMD,
in shared library mode and default mode.

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/Makefile | 11 +
app/test-pmd/cmdline.c | 699 +++++++++++++++++++++++++++-
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 +
7 files changed, 1206 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h
--
2.9.0
Bernard Iremonger
2016-10-12 17:54:10 UTC
Permalink
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 v8:
rebase to latest master branch.
fix testpmd Makefile.

Changes in v8:
rebase to latest master branch.
add new API's to testpmd help command.
modify testpmd Makefile to build with and without ixgbe PMD,
in shared library mode and default mode.

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/Makefile | 2 +
app/test-pmd/cmdline.c | 699 +++++++++++++++++++++++++++-
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 +
7 files changed, 1197 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/ixgbe/rte_pmd_ixgbe.h
--
2.9.0
Bruce Richardson
2016-10-13 13:47:26 UTC
Permalink
Post by 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.
Patchset applied to dpdk-next-net/rel_16_11

/Bruce
Bernard Iremonger
2016-10-12 17:54:11 UTC
Permalink
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 <***@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 <***@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
Bernard Iremonger
2016-10-12 17:54:12 UTC
Permalink
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 testpmd help command.

add new API's to the testpmd guide

modify Makefile, add library rte_pmd_ixgbe to _LDLIBS-y.

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

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 2a0b5a5..891b85a 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,8 @@ SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c

+_LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+
CFLAGS_cmdline.o := -D_GNU_SOURCE

# this application needs libraries first
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a1da8b8..41c7acf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -87,7 +87,9 @@
#ifdef RTE_LIBRTE_PMD_BOND
#include <rte_eth_bond.h>
#endif
-
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
#include "testpmd.h"

static struct cmdline *testpmd_cl;
@@ -260,12 +262,37 @@ static void cmd_help_long_parsed(void *parsed_result,
"set portlist (x[,y]*)\n"
" Set the list of forwarding ports.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set tx loopback (port_id) (on|off)\n"
+ " Enable or disable tx loopback.\n\n"
+
+ "set all queues drop (port_id) (on|off)\n"
+ " Set drop enable bit for all queues.\n\n"
+
+ "set vf split drop (port_id) (vf_id) (on|off)\n"
+ " Set split drop enable bit for a VF from the PF.\n\n"
+
+ "set vf mac antispoof (port_id) (vf_id) (on|off).\n"
+ " Set MAC antispoof for a VF from the PF.\n\n"
+#endif
+
"vlan set strip (on|off) (port_id)\n"
" Set the VLAN strip on a port.\n\n"

"vlan set stripq (on|off) (port_id,queue_id)\n"
" Set the VLAN strip for a queue on a port.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set vf vlan stripq (port_id) (vf_id) (on|off)\n"
+ " Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
+
+ "set vf vlan insert (port_id) (vf_id) (on|off)\n"
+ " Set VLAN insert for a VF from the PF.\n\n"
+
+ "set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
+ " Set VLAN antispoof for a VF from the PF.\n\n"
+#endif
+
"vlan set filter (on|off) (port_id)\n"
" Set the VLAN filter on a port.\n\n"

@@ -359,6 +386,11 @@ static void cmd_help_long_parsed(void *parsed_result,
"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
" Add a MAC address for a VF on the port.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
+ " Set the MAC address for a VF from the PF.\n\n"
+#endif
+
"set port (port_id) uta (mac_address|all) (on|off)\n"
" Add/Remove a or all unicast hash filter(s)"
"from port X.\n\n"
@@ -10700,6 +10732,661 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
NULL,
},
};
+#ifdef RTE_LIBRTE_IXGBE_PMD
+
+/* 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,
+ },
+};
+#endif

/* ******************************************************************************** */

@@ -10857,6 +11544,16 @@ 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,
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ (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,
+#endif
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
Bernard Iremonger
2016-10-12 15:03:15 UTC
Permalink
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 <***@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 <***@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
Bernard Iremonger
2016-10-12 15:03:16 UTC
Permalink
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 testpmd help command.

add new API's to the testpmd guide

modify Makefile, add library rte_pmd_ixgbe to LDLIBS.

Signed-off-by: Bernard Iremonger <***@intel.com>
---
app/test-pmd/Makefile | 11 +
app/test-pmd/cmdline.c | 699 +++++++++++++++++++++++++++-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 62 ++-
3 files changed, 768 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 2a0b5a5..472a016 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c

+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+endif
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
+
+
CFLAGS_cmdline.o := -D_GNU_SOURCE

# this application needs libraries first
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a1da8b8..41c7acf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -87,7 +87,9 @@
#ifdef RTE_LIBRTE_PMD_BOND
#include <rte_eth_bond.h>
#endif
-
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
#include "testpmd.h"

static struct cmdline *testpmd_cl;
@@ -260,12 +262,37 @@ static void cmd_help_long_parsed(void *parsed_result,
"set portlist (x[,y]*)\n"
" Set the list of forwarding ports.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set tx loopback (port_id) (on|off)\n"
+ " Enable or disable tx loopback.\n\n"
+
+ "set all queues drop (port_id) (on|off)\n"
+ " Set drop enable bit for all queues.\n\n"
+
+ "set vf split drop (port_id) (vf_id) (on|off)\n"
+ " Set split drop enable bit for a VF from the PF.\n\n"
+
+ "set vf mac antispoof (port_id) (vf_id) (on|off).\n"
+ " Set MAC antispoof for a VF from the PF.\n\n"
+#endif
+
"vlan set strip (on|off) (port_id)\n"
" Set the VLAN strip on a port.\n\n"

"vlan set stripq (on|off) (port_id,queue_id)\n"
" Set the VLAN strip for a queue on a port.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set vf vlan stripq (port_id) (vf_id) (on|off)\n"
+ " Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
+
+ "set vf vlan insert (port_id) (vf_id) (on|off)\n"
+ " Set VLAN insert for a VF from the PF.\n\n"
+
+ "set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
+ " Set VLAN antispoof for a VF from the PF.\n\n"
+#endif
+
"vlan set filter (on|off) (port_id)\n"
" Set the VLAN filter on a port.\n\n"

@@ -359,6 +386,11 @@ static void cmd_help_long_parsed(void *parsed_result,
"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
" Add a MAC address for a VF on the port.\n\n"

+#ifdef RTE_LIBRTE_IXGBE_PMD
+ "set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
+ " Set the MAC address for a VF from the PF.\n\n"
+#endif
+
"set port (port_id) uta (mac_address|all) (on|off)\n"
" Add/Remove a or all unicast hash filter(s)"
"from port X.\n\n"
@@ -10700,6 +10732,661 @@ cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
NULL,
},
};
+#ifdef RTE_LIBRTE_IXGBE_PMD
+
+/* 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,
+ },
+};
+#endif

/* ******************************************************************************** */

@@ -10857,6 +11544,16 @@ 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,
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ (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,
+#endif
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
Thomas Monjalon
2016-10-12 15:11:51 UTC
Permalink
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+endif
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
Sorry if I miss something, but I thought it was enough to do:
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
Iremonger, Bernard
2016-10-12 15:27:23 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for new
API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe endif
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .

There are 4 scenarios as follows:

CONFIG_RTE_LIBRTE_IXGBE_PMD=y with CONFIG_RTE_BUILD_SHARED_LIB=n

CONFIG_RTE_LIBRTE_IXGBE_PMD=y with CONFIG_RTE_BUILD_SHARED_LIB=y

CONFIG_RTE_LIBRTE_IXGBE_PMD=n with CONFIG_RTE_BUILD_SHARED_LIB=y

CONFIG_RTE_LIBRTE_IXGBE_PMD=n with CONFIG_RTE_BUILD_SHARED_LIB=n

I have been doing quite a bit of building today to get it to work in all 4 scenarios.

Regards,

Bernard.
Thomas Monjalon
2016-10-12 15:36:41 UTC
Permalink
Post by Iremonger, Bernard
Hi Thomas,
<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for new
API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe endif
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with CONFIG_RTE_BUILD_SHARED_LIB=n
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with CONFIG_RTE_BUILD_SHARED_LIB=y
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with CONFIG_RTE_BUILD_SHARED_LIB=y
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with CONFIG_RTE_BUILD_SHARED_LIB=n
I have been doing quite a bit of building today to get it to work in all 4 scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
But in the static case, you wrote:
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe endif
Please could you check?
Iremonger, Bernard
2016-10-12 15:48:11 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for new
API's
Post by Iremonger, Bernard
Hi Thomas,
<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for
new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
Do you want me to check the four scenarios with just the line below.

LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe

Regards,

Bernard.
Thomas Monjalon
2016-10-12 16:06:45 UTC
Permalink
Post by Iremonger, Bernard
Hi Thomas,
<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for new
API's
Post by Iremonger, Bernard
Hi Thomas,
<snip>
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests for
new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
I think I'm something obvious.
Please could you point the line where LDLIBS-y is used?
Post by Iremonger, Bernard
Do you want me to check the four scenarios with just the line below.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
Let's check the theory first :)
Iremonger, Bernard
2016-10-12 16:21:12 UTC
Permalink
Hi Thomas,

<snip>
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests
for new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
I think I'm something obvious.
Please could you point the line where LDLIBS-y is used?
Line 62 of latest Makefile;
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe

LDLIBS-y does not exist when CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Thomas Monjalon
Post by Iremonger, Bernard
Do you want me to check the four scenarios with just the line below.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
Let's check the theory first :)
Ok

Regards,

Bernard.
Thomas Monjalon
2016-10-12 16:31:10 UTC
Permalink
Post by Iremonger, Bernard
Hi Thomas,
<snip>
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add tests
for new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe
+endif
+endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios .
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
I think I'm something obvious.
Please could you point the line where LDLIBS-y is used?
Line 62 of latest Makefile;
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No, I mean where do you find LDLIBS- (without underscore) before your patch?
git grep '\<LDLIBS-' returns nothing.
Iremonger, Bernard
2016-10-12 16:50:45 UTC
Permalink
Hi Thomas,

<snip>
Post by Bernard Iremonger
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add
tests for new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -
lrte_pmd_ixgbe
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe endif endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No unfortunately not, the above line does not work for all scenarios
.
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to
work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
endif
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
I think I'm something obvious.
Please could you point the line where LDLIBS-y is used?
Line 62 of latest Makefile;
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No, I mean where do you find LDLIBS- (without underscore) before your patch?
git grep '\<LDLIBS-' returns nothing.
Before my patch LDLIBS was not used in the testpmd Makefile.

The linking was done in rte.app.mk, this uses LDLIBS and _LDLIBS-y.
I don't see LDLIBS-y either.

Regards,

Bernard.
Iremonger, Bernard
2016-10-12 17:20:18 UTC
Permalink
Hi Thomas,

<snip>
Post by Bernard Iremonger
Post by Bernard Iremonger
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Subject: Re: [dpdk-dev] [PATCH v8 2/2] app/test_pmd: add
tests for new API's
Post by Bernard Iremonger
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,6 +58,17 @@ SRCS-y += csumonly.c SRCS-y +=
icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -
lrte_pmd_ixgbe
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
endif
Post by Iremonger, Bernard
Post by Bernard Iremonger
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_PMD),y)
+LDLIBS += -lrte_pmd_ixgbe endif endif
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -
lrte_pmd_ixgbe
Post by Bernard Iremonger
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
No unfortunately not, the above line does not work for all
scenarios
.
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=y with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=y
Post by Iremonger, Bernard
CONFIG_RTE_LIBRTE_IXGBE_PMD=n with
CONFIG_RTE_BUILD_SHARED_LIB=n
Post by Iremonger, Bernard
I have been doing quite a bit of building today to get it to
work in all 4
scenarios.
I have a doubt about the tests because LDLIBS-y does not exist.
There is _LDLIBS-y and LDLIBS.
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -
lrte_pmd_ixgbe
Post by Bernard Iremonger
Post by Iremonger, Bernard
Post by Thomas Monjalon
endif
Post by Iremonger, Bernard
Post by Iremonger, Bernard
Please could you check?
LDLIBS-y exists in some of the scenarios but not all.
I think I'm something obvious.
Please could you point the line where LDLIBS-y is used?
Line 62 of latest Makefile;
LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
No, I mean where do you find LDLIBS- (without underscore) before your patch?
git grep '\<LDLIBS-' returns nothing.
Before my patch LDLIBS was not used in the testpmd Makefile.
The linking was done in rte.app.mk, this uses LDLIBS and _LDLIBS-y.
I don't see LDLIBS-y either.
Regards,
Bernard.
_LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe

Works in the 4 scenarios, I will send a v9

Regards,

Bernard.
Bernard Iremonger
2016-10-07 16:46:23 UTC
Permalink
add cb_arg parameter to the _rte_eth_dev_callback_process function.

Adding a parameter to this function allows passing information
to the application when an eth device event occurs such as
a VF to PF message.
This allows the application to decide if a particular function
is permitted.

drivers/net: add parameter to callback process function

add parameter to call of _rte_eth_dev_callback_process function
in the following PMD's:

net/bonding
net/e1000
net/i40e
net/enic
net/ixgbe
net/mlx4
net/mlx5
net/nfp
net/thunderx
net/vhost
net/virtio

app/test: add parameter to callback process function
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
Signed-off-by: Alex Zelezniak <***@att.com>
---
app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 +++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 +++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 ++++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++++-
16 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 4831113..65b44c6 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -485,7 +485,7 @@ virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,

vrtl_eth_dev->data->dev_link.link_status = link_status;

- _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb4050c..8d510e3 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1958,7 +1958,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg)
return;

_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

void
@@ -2079,7 +2079,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);

} else {
if (internals->link_down_delay_ms > 0)
@@ -2088,7 +2088,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}
}
}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index f767e1c..e13e858 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1599,7 +1599,7 @@ eth_em_interrupt_handler(__rte_unused struct rte_intr_handle *handle,

eth_em_interrupt_get_status(dev);
eth_em_interrupt_action(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 5a1a83e..d9ab2df 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2683,7 +2683,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
E1000_WRITE_FLUSH(hw);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

return 0;
@@ -2743,7 +2743,7 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == E1000_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15a05b4..fb72491 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -436,7 +436,7 @@ enic_intr_handler(__rte_unused struct rte_intr_handle *handle,
vnic_intr_return_all_credits(&enic->intr);

enic_link_update(enic);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
enic_log_q_error(enic);
}

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 697800e..d947760 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5510,7 +5510,7 @@ i40e_dev_interrupt_delayed_handler(void *param)

/* handle the link up interrupt in an alarm callback */
i40e_dev_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

i40e_pf_enable_irq0(hw);
rte_intr_enable(&(dev->pci_dev->intr_handle));
@@ -5594,7 +5594,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
return;
else
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

done:
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 34eb274..bd89cd9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1341,7 +1341,7 @@ i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
switch (pf_msg->event) {
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event\n");
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
break;
case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event\n");
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 35281f9..b00aef3 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
@@ -7537,7 +7537,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 1553b2e..3e57cca 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5448,7 +5448,7 @@ mlx4_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -5471,7 +5471,7 @@ mlx4_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index bf4232a..c76e754 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1069,7 +1069,7 @@ mlx5_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -1092,7 +1092,7 @@ mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index d526f34..a2b9056 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1219,7 +1219,7 @@ nfp_net_dev_interrupt_delayed_handler(void *param)
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;

nfp_net_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

nfp_net_dev_link_status_print(dev);

diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b758c9f..c61e171 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -108,7 +108,7 @@ nicvf_interrupt(void *arg)
nicvf_set_eth_link_status(nic,
&nic->eth_dev->data->dev_link);
_rte_eth_dev_callback_process(nic->eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index c1d09a0..18a0c10 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -559,7 +559,7 @@ new_device(int vid)

RTE_LOG(INFO, PMD, "New connection established\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);

return 0;
}
@@ -626,7 +626,7 @@ destroy_device(int vid)

RTE_LOG(INFO, PMD, "Connection closed\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
@@ -655,7 +655,7 @@ vring_state_changed(int vid, uint16_t vring, int enable)
RTE_LOG(INFO, PMD, "vring%u is %s\n",
vring, enable ? "enabled" : "disabled");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE, NULL);

return 0;
}
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b4dfc0a..2f0065a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1103,7 +1103,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
if (isr & VIRTIO_PCI_ISR_CONFIG) {
if (virtio_dev_link_update(dev, 0) == 0)
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c517e88..13ba70d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t port_id,

void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *cb_arg)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
continue;
dev_cb = *cb_lst;
cb_lst->active = 1;
+ if (cb_arg != NULL)
+ dev_cb.cb_arg = (void *) cb_arg;
+
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 7218b6f..6667655 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ 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, /**< message from the VF received by PF */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};

@@ -3047,6 +3048,11 @@ typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
* @param cb_arg
* Pointer to the parameters for the registered callback.
*
+ * The user data is overwritten in the case of RTE_ETH_EVENT_VF_MBOX.
+ * This even occurs when a message from the VF is received by the PF.
+ * The user data is overwritten with struct rte_pmd_ixgbe_mb_event_param.
+ * This struct is defined in rte_pmd_ixgbe.h.
+ *
* @return
* - On success, zero.
* - On failure, a negative value.
@@ -3085,12 +3091,16 @@ int rte_eth_dev_callback_unregister(uint8_t port_id,
* Pointer to struct rte_eth_dev.
* @param event
* Eth device interrupt event type.
+ * @param cb_arg
+ * Update callback parameter to pass data back to user application.
+ * This allows the user application to decide if a particular function
+ * is permitted or not.
*
* @return
* void
*/
void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event);
+ enum rte_eth_event_type event, void *cb_arg);

/**
* When there is no rx packet coming in Rx Queue for a long time, we can
--
2.9.0
Bernard Iremonger
2016-10-07 16:46:24 UTC
Permalink
call _rte_eth_dev_callback_process 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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 20 +++++++++++++++++++
2 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..2a177b8 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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_pmd_ixgbe_mb_event_param cb_param;

retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
if (retval) {
@@ -674,27 +676,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_PMD_IXGBE_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(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_PMD_IXGBE_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(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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 2689668..8665cea 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -179,4 +179,24 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
+/**
+ * Data sent to the user application when the callback is executed.
+ */
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid; /**< Virtual Function number */
+ uint16_t msg_type; /**< message type */
+ uint16_t retval; /**< return value */
+ void *userdata; /**< pointer to user data */
+};
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Thomas Monjalon
2016-10-07 22:44:19 UTC
Permalink
Post by Bernard Iremonger
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid; /**< Virtual Function number */
+ uint16_t msg_type; /**< message type */
+ uint16_t retval; /**< return value */
+ void *userdata; /**< pointer to user data */
Generally speaking, the user data is a pointer passed by the application
when registering the callback and must be untouched.
It should be the name of the parameter that you are overriding with
this structure.
So this "userdata" pointer could probably be better defined.

By the way, it is far from trivial to understand how to write the callback.
I think it deserves more explanations.
Iremonger, Bernard
2016-10-10 14:31:29 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v7 2/2] net/ixgbe: add callback to user app
on VF to PF mbox msg
Post by Bernard Iremonger
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid; /**< Virtual Function number */
+ uint16_t msg_type; /**< message type */
+ uint16_t retval; /**< return value */
+ void *userdata; /**< pointer to user data */
Generally speaking, the user data is a pointer passed by the application when
registering the callback and must be untouched.
It should be the name of the parameter that you are overriding with this
structure.
So this "userdata" pointer could probably be better defined.
By the way, it is far from trivial to understand how to write the callback.
I think it deserves more explanations.
I will clarify the description of the struct rte_pmd_ixgbe_mb_event_param, and rename the member userdate to msg in a v8 patchset.

Regards,

Bernard.
Bernard Iremonger
2016-10-06 16:48:09 UTC
Permalink
add cb_arg parameter to the _rte_eth_dev_callback_process function.

Adding a parameter to this function allows passing information
to the application when an eth device event occurs such as
a VF to PF message.
This allows the application to decide if a particular function
is permitted.

drivers/net: add parameter to callback process function

add parameter to call of _rte_eth_dev_callback_process function
in the following PMD's:

net/bonding
net/e1000
net/i40e
net/mlx4
net/mlx5
net/nfp
net/thunderx
net/vhost
net/virtio
net/enic

app/test: add parameter to callback process function
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
Signed-off-by: Alex Zelezniak <***@att.com>
---
app/test/virtual_pmd.c | 2 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 6 +++---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
drivers/net/enic/enic_main.c | 2 +-
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
drivers/net/mlx4/mlx4.c | 4 ++--
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
drivers/net/nfp/nfp_net.c | 2 +-
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
drivers/net/vhost/rte_eth_vhost.c | 6 +++---
drivers/net/virtio/virtio_ethdev.c | 2 +-
lib/librte_ether/rte_ethdev.c | 5 ++++-
lib/librte_ether/rte_ethdev.h | 12 +++++++++++-
15 files changed, 36 insertions(+), 23 deletions(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 4831113..65b44c6 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -485,7 +485,7 @@ virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,

vrtl_eth_dev->data->dev_link.link_status = link_status;

- _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb4050c..8d510e3 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1958,7 +1958,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg)
return;

_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

void
@@ -2079,7 +2079,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);

} else {
if (internals->link_down_delay_ms > 0)
@@ -2088,7 +2088,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}
}
}
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index f767e1c..e13e858 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1599,7 +1599,7 @@ eth_em_interrupt_handler(__rte_unused struct rte_intr_handle *handle,

eth_em_interrupt_get_status(dev);
eth_em_interrupt_action(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 5a1a83e..d9ab2df 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2683,7 +2683,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
E1000_WRITE_FLUSH(hw);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

return 0;
@@ -2743,7 +2743,7 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == E1000_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15a05b4..fb72491 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -436,7 +436,7 @@ enic_intr_handler(__rte_unused struct rte_intr_handle *handle,
vnic_intr_return_all_credits(&enic->intr);

enic_link_update(enic);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
enic_log_q_error(enic);
}

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 697800e..d947760 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5510,7 +5510,7 @@ i40e_dev_interrupt_delayed_handler(void *param)

/* handle the link up interrupt in an alarm callback */
i40e_dev_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

i40e_pf_enable_irq0(hw);
rte_intr_enable(&(dev->pci_dev->intr_handle));
@@ -5594,7 +5594,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
return;
else
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

done:
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 34eb274..bd89cd9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1341,7 +1341,7 @@ i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
switch (pf_msg->event) {
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event\n");
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
break;
case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event\n");
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 1553b2e..3e57cca 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5448,7 +5448,7 @@ mlx4_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -5471,7 +5471,7 @@ mlx4_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index bf4232a..c76e754 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1069,7 +1069,7 @@ mlx5_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -1092,7 +1092,7 @@ mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index d526f34..a2b9056 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1219,7 +1219,7 @@ nfp_net_dev_interrupt_delayed_handler(void *param)
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;

nfp_net_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

nfp_net_dev_link_status_print(dev);

diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b758c9f..c61e171 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -108,7 +108,7 @@ nicvf_interrupt(void *arg)
nicvf_set_eth_link_status(nic,
&nic->eth_dev->data->dev_link);
_rte_eth_dev_callback_process(nic->eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index c1d09a0..18a0c10 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -559,7 +559,7 @@ new_device(int vid)

RTE_LOG(INFO, PMD, "New connection established\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);

return 0;
}
@@ -626,7 +626,7 @@ destroy_device(int vid)

RTE_LOG(INFO, PMD, "Connection closed\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
@@ -655,7 +655,7 @@ vring_state_changed(int vid, uint16_t vring, int enable)
RTE_LOG(INFO, PMD, "vring%u is %s\n",
vring, enable ? "enabled" : "disabled");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE, NULL);

return 0;
}
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b4dfc0a..2f0065a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1103,7 +1103,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
if (isr & VIRTIO_PCI_ISR_CONFIG) {
if (virtio_dev_link_update(dev, 0) == 0)
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c517e88..13ba70d 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t port_id,

void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *cb_arg)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
continue;
dev_cb = *cb_lst;
cb_lst->active = 1;
+ if (cb_arg != NULL)
+ dev_cb.cb_arg = (void *) cb_arg;
+
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 7218b6f..775e899 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ 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, /**< message from the VF received by PF */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};

@@ -3047,6 +3048,11 @@ typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
* @param cb_arg
* Pointer to the parameters for the registered callback.
*
+ * The cb_arg must not be NULL if the application requires
+ * data to be returned when the callback is processed.
+ * For the RTE_ETH_EVENT_VF_MBOX data is returned to the
+ * application.
+ *
* @return
* - On success, zero.
* - On failure, a negative value.
@@ -3085,12 +3091,16 @@ int rte_eth_dev_callback_unregister(uint8_t port_id,
* Pointer to struct rte_eth_dev.
* @param event
* Eth device interrupt event type.
+ * @param cb_arg
+ * Update callback parameter to pass data back to user application.
+ * This allows the user application to decide if a particular function
+ * is permitted or not.
*
* @return
* void
*/
void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event);
+ enum rte_eth_event_type event, void *cb_arg);

/**
* When there is no rx packet coming in Rx Queue for a long time, we can
--
2.9.0
Thomas Monjalon
2016-10-07 12:29:42 UTC
Permalink
Post by Bernard Iremonger
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t port_id,
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *cb_arg)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,9 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
continue;
dev_cb = *cb_lst;
cb_lst->active = 1;
+ if (cb_arg != NULL)
+ dev_cb.cb_arg = (void *) cb_arg;
+
rte_spinlock_unlock(&rte_eth_dev_cb_lock);
dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
dev_cb.cb_arg);
[...]
Post by Bernard Iremonger
@@ -3047,6 +3048,11 @@ typedef void (*rte_eth_dev_cb_fn)(uint8_t port_id, \
* Pointer to the parameters for the registered callback.
*
+ * The cb_arg must not be NULL if the application requires
+ * data to be returned when the callback is processed.
+ * For the RTE_ETH_EVENT_VF_MBOX data is returned to the
+ * application.
This comment is wrong.
You should say that the user data is overwritten in the case of
RTE_ETH_EVENT_VF_MBOX. And you should point to where the meaning
of this parameter is documented (ixgbe.h) or document it here.
Iremonger, Bernard
2016-10-07 16:57:23 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v6 1/2] librte_ether: modify internal callback
function
Post by Bernard Iremonger
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t
port_id,
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *cb_arg)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,9 @@ _rte_eth_dev_callback_process(struct
rte_eth_dev *dev,
Post by Bernard Iremonger
continue;
dev_cb = *cb_lst;
cb_lst->active = 1;
+ if (cb_arg != NULL)
+ dev_cb.cb_arg = (void *) cb_arg;
+
rte_spinlock_unlock(&rte_eth_dev_cb_lock);
dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
dev_cb.cb_arg);
[...]
Post by Bernard Iremonger
@@ -3047,6 +3048,11 @@ typedef void (*rte_eth_dev_cb_fn)(uint8_t
port_id, \
Post by Bernard Iremonger
* Pointer to the parameters for the registered callback.
*
+ * The cb_arg must not be NULL if the application requires
+ * data to be returned when the callback is processed.
+ * For the RTE_ETH_EVENT_VF_MBOX data is returned to the
+ * application.
This comment is wrong.
You should say that the user data is overwritten in the case of
RTE_ETH_EVENT_VF_MBOX. And you should point to where the meaning of
this parameter is documented (ixgbe.h) or document it here.
This is corrected in the v7 patchset.

Regards.

Bernard.
Bernard Iremonger
2016-10-06 16:48:10 UTC
Permalink
call _rte_eth_dev_callback_process 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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 ++++++++++++++++
3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 55a82d3..91db2c3 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
@@ -7525,7 +7525,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..2a177b8 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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_pmd_ixgbe_mb_event_param cb_param;

retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
if (retval) {
@@ -674,27 +676,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_PMD_IXGBE_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(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_PMD_IXGBE_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(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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 33b5b2d..2f6cf46 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -181,4 +181,21 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid;
+ uint16_t msg_type;
+ uint16_t retval;
+ void *userdata;
+};
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Thomas Monjalon
2016-10-07 12:14:02 UTC
Permalink
Post by Bernard Iremonger
call _rte_eth_dev_callback_process 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_PMD_IXGBE_MB_EVENT_PROCEED then continue,
if 0, do nothing and send ACK to VF
if > 1, do nothing and send NAK to VF.
[...]
Post by Bernard Iremonger
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
@@ -7525,7 +7525,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}
This piece should go into the patch 1.
Iremonger, Bernard
2016-10-07 12:19:03 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v6 2/2] net/ixgbe: add callback to user app
on VF to PF mbox msg
Post by Bernard Iremonger
call _rte_eth_dev_callback_process from ixgbe_rcv_msg_from_vf
function.
Post by Bernard Iremonger
The callback asks the user application if it is allowed to perform the
function.
If the cb_param.retval is RTE_PMD_IXGBE_MB_EVENT_PROCEED then
continue, if 0, do nothing and send ACK to VF if > 1, do nothing and
send NAK to VF.
[...]
Post by Bernard Iremonger
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void
*param)
Post by Bernard Iremonger
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC);
Post by Bernard Iremonger
+ _rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC, NULL);
Post by Bernard Iremonger
}
PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]",
eicr);
Post by Bernard Iremonger
@@ -7525,7 +7525,7 @@ static void ixgbevf_mbx_process(struct
rte_eth_dev *dev)
/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_RESET);
Post by Bernard Iremonger
+ _rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_RESET, NULL);
Post by Bernard Iremonger
}
This piece should go into the patch 1.
Ok, I will send a v7.

Regards,

Bernard.
Bernard Iremonger
2016-10-06 11:26:19 UTC
Permalink
add parameter to the _rte_eth_dev_callback_process function.

Adding a parameter to this function allows passing information
to the application when an eth device event occurs such as
a VF to PF message.
This allows the application to decide if a particular function
is permitted.

Signed-off-by: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
lib/librte_ether/rte_ethdev.c | 5 ++++-
lib/librte_ether/rte_ethdev.h | 7 ++++++-
2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c517e88..416ca77 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2508,7 +2508,7 @@ rte_eth_dev_callback_unregister(uint8_t port_id,

void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
{
struct rte_eth_dev_callback *cb_lst;
struct rte_eth_dev_callback dev_cb;
@@ -2519,6 +2519,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 7218b6f..9fb34ca 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ 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 */
};

@@ -3085,12 +3086,16 @@ int rte_eth_dev_callback_unregister(uint8_t port_id,
* Pointer to struct rte_eth_dev.
* @param event
* Eth device interrupt event type.
+ * @param param
+ * Parameter to pass back to user application.
+ * Allows the user application to decide if a particular function
+ * is permitted.
*
* @return
* void
*/
void _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event);
+ enum rte_eth_event_type event, void *param);

/**
* When there is no rx packet coming in Rx Queue for a long time, we can
--
2.9.0
Thomas Monjalon
2016-10-06 12:56:04 UTC
Permalink
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.

[...]
Post by Bernard Iremonger
+ if (param != NULL)
+ dev_cb.cb_arg = (void *) param;
You are overriding the user parameter.
As it is only for a new event, it can be described in the register API
that the user param won't be returned for this event.
But a better design would be to add a new parameter to the callback.
However it will be an API breakage.
Post by Bernard Iremonger
+ RTE_ETH_EVENT_VF_MBOX, /**< PF mailbox processing callback */
Sorry I do not parse well this line.
The event name is VF_MBOX and the comment is about the callback
processing this event on PF side?
I would suggest this kind of comment: "message from VF received by PF"

[...]
Post by Bernard Iremonger
* Pointer to struct rte_eth_dev.
* Eth device interrupt event type.
+ * Parameter to pass back to user application.
+ * Allows the user application to decide if a particular function
+ * is permitted.
In a more generic case, the parameter gives some details about the event.
Iremonger, Bernard
2016-10-06 14:33:27 UTC
Permalink
Hi Thomas,
Subject: Re: [dpdk-dev] [PATCH v5 01/13] librte_ether: modify internal
callback function
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.
I will have to squash everything into one patch, separate patches will not compile.
[...]
Post by Bernard Iremonger
+ if (param != NULL)
+ dev_cb.cb_arg = (void *) param;
You are overriding the user parameter.
Yes, we want to update the user parameter for the RTE_ETH_EVENT_VF_MBOX
As it is only for a new event, it can be described in the register API that the
user param won't be returned for this event.
I will add a description in the rte_eth_dev_callback_register function.
But a better design would be to add a new parameter to the callback.
However it will be an API breakage.
I do not want to break the ABI at this point.
Post by Bernard Iremonger
+ RTE_ETH_EVENT_VF_MBOX, /**< PF mailbox processing callback */
Sorry I do not parse well this line.
The event name is VF_MBOX and the comment is about the callback
processing this event on PF side?
I would suggest this kind of comment: "message from VF received by PF"
Ok.
[...]
Post by Bernard Iremonger
* Pointer to struct rte_eth_dev.
* Eth device interrupt event type.
+ * Parameter to pass back to user application.
+ * Allows the user application to decide if a particular function
+ * is permitted.
In a more generic case, the parameter gives some details about the event.
Thomas Monjalon
2016-10-06 14:56:33 UTC
Permalink
Post by Iremonger, Bernard
Hi Thomas,
Subject: Re: [dpdk-dev] [PATCH v5 01/13] librte_ether: modify internal
callback function
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.
I will have to squash everything into one patch, separate patches will not compile.
No you can keep a separate patch for the VF event in ixgbe.
Post by Iremonger, Bernard
[...]
Post by Bernard Iremonger
+ if (param != NULL)
+ dev_cb.cb_arg = (void *) param;
You are overriding the user parameter.
Yes, we want to update the user parameter for the RTE_ETH_EVENT_VF_MBOX
As it is only for a new event, it can be described in the register API that the
user param won't be returned for this event.
I will add a description in the rte_eth_dev_callback_register function.
But a better design would be to add a new parameter to the callback.
However it will be an API breakage.
I do not want to break the ABI at this point.
Yes, but it can be considered for a later change.
Post by Iremonger, Bernard
Post by Bernard Iremonger
+ RTE_ETH_EVENT_VF_MBOX, /**< PF mailbox processing callback */
Sorry I do not parse well this line.
The event name is VF_MBOX and the comment is about the callback
processing this event on PF side?
I would suggest this kind of comment: "message from VF received by PF"
Ok.
[...]
Post by Bernard Iremonger
* Pointer to struct rte_eth_dev.
* Eth device interrupt event type.
+ * Parameter to pass back to user application.
+ * Allows the user application to decide if a particular function
+ * is permitted.
In a more generic case, the parameter gives some details about the event.
Please consider a rewording here, thanks.
Iremonger, Bernard
2016-10-06 15:32:35 UTC
Permalink
Hi Thomas,

<snip>
Post by Thomas Monjalon
Post by Iremonger, Bernard
Subject: Re: [dpdk-dev] [PATCH v5 01/13] librte_ether: modify
internal callback function
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.
I will have to squash everything into one patch, separate patches will not
compile.
No you can keep a separate patch for the VF event in ixgbe.
I have 4 patches at present

librte_ether
net/ixgbe
drivers/net
app/test

Would this be acceptable or do you just want everything squashed into librte_ether except for net/ixgbe?
Post by Thomas Monjalon
Post by Iremonger, Bernard
[...]
Post by Bernard Iremonger
+ if (param != NULL)
+ dev_cb.cb_arg = (void *) param;
You are overriding the user parameter.
Yes, we want to update the user parameter for the
RTE_ETH_EVENT_VF_MBOX
I have renamed param to cb_arg to make it clearer what is happening.
Post by Thomas Monjalon
Post by Iremonger, Bernard
As it is only for a new event, it can be described in the register
API that the user param won't be returned for this event.
I will add a description in the rte_eth_dev_callback_register function.
But a better design would be to add a new parameter to the callback.
However it will be an API breakage.
I do not want to break the ABI at this point.
Yes, but it can be considered for a later change.
Yes, ok
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Bernard Iremonger
+ RTE_ETH_EVENT_VF_MBOX, /**< PF mailbox processing callback */
Sorry I do not parse well this line.
The event name is VF_MBOX and the comment is about the callback
processing this event on PF side?
I would suggest this kind of comment: "message from VF received by PF"
Ok.
[...]
Post by Bernard Iremonger
* Pointer to struct rte_eth_dev.
* Eth device interrupt event type.
+ * Parameter to pass back to user application.
+ * Allows the user application to decide if a particular
+ function
+ * is permitted.
In a more generic case, the parameter gives some details about the
event.
Please consider a rewording here, thanks.
I have reworded here, I hope it is clearer.

Regards,

Bernard.
Thomas Monjalon
2016-10-06 15:41:28 UTC
Permalink
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.
I will have to squash everything into one patch, separate patches will not
compile.
No you can keep a separate patch for the VF event in ixgbe.
I have 4 patches at present
librte_ether
net/ixgbe
drivers/net
app/test
Would this be acceptable or do you just want everything squashed into librte_ether except for net/ixgbe?
You can test the compilation of each patch with this command:
git rebase -i origin/master -x scripts/test-build.sh
or just:
git rebase -i origin/master -x make

I think you need to squash drivers/net (adding just NULL param) and
app/test in ethdev patch.
Iremonger, Bernard
2016-10-06 15:45:53 UTC
Permalink
Hi Thomas,
Subject: Re: [dpdk-dev] [PATCH v5 01/13] librte_ether: modify internal
callback function
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Bernard Iremonger
void
_rte_eth_dev_callback_process(struct rte_eth_dev *dev,
- enum rte_eth_event_type event)
+ enum rte_eth_event_type event, void *param)
You need to squash the patches updating the calls to this function.
Otherwise, this patch does not compile.
I will have to squash everything into one patch, separate patches will not
compile.
No you can keep a separate patch for the VF event in ixgbe.
I have 4 patches at present
librte_ether
net/ixgbe
drivers/net
app/test
Would this be acceptable or do you just want everything squashed into
librte_ether except for net/ixgbe?
git rebase -i origin/master -x make
I think you need to squash drivers/net (adding just NULL param) and
app/test in ethdev patch.
They do not compile if applied one by one.
Ok, I will squash drivers/net and app/test into the librte_ether patch.

Regards,

Bernard.
Bernard Iremonger
2016-10-06 11:26:20 UTC
Permalink
call _rte_eth_dev_callback_process 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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 4 ++--
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 ++++++++++++++++
3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 55a82d3..91db2c3 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3559,7 +3559,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
ixgbe_dev_link_update(dev, 0);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
ixgbe_dev_link_status_print(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
@@ -7525,7 +7525,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == IXGBE_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..2a177b8 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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_pmd_ixgbe_mb_event_param cb_param;

retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
if (retval) {
@@ -674,27 +676,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_PMD_IXGBE_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(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_PMD_IXGBE_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(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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 33b5b2d..2f6cf46 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -181,4 +181,21 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid;
+ uint16_t msg_type;
+ uint16_t retval;
+ void *userdata;
+};
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:21 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
app/test/virtual_pmd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 4831113..65b44c6 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -485,7 +485,7 @@ virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,

vrtl_eth_dev->data->dev_link.link_status = link_status;

- _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(vrtl_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

int
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:22 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/bonding/rte_eth_bond_pmd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 292086a..0913020 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1958,7 +1958,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg)
return;

_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

void
@@ -2079,7 +2079,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);

} else {
if (internals->link_down_delay_ms > 0)
@@ -2088,7 +2088,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
(void *)bonded_eth_dev);
else
_rte_eth_dev_callback_process(bonded_eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}
}
}
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:23 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/e1000/em_ethdev.c | 2 +-
drivers/net/e1000/igb_ethdev.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index f767e1c..e13e858 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1599,7 +1599,7 @@ eth_em_interrupt_handler(__rte_unused struct rte_intr_handle *handle,

eth_em_interrupt_get_status(dev);
eth_em_interrupt_action(dev);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 5a1a83e..d9ab2df 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -2683,7 +2683,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
E1000_WRITE_FLUSH(hw);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

return 0;
@@ -2743,7 +2743,7 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)

/* PF reset VF event */
if (in_msg == E1000_PF_CONTROL_MSG)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
}

static int
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:24 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 4 ++--
drivers/net/i40e/i40e_ethdev_vf.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 697800e..d947760 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -5510,7 +5510,7 @@ i40e_dev_interrupt_delayed_handler(void *param)

/* handle the link up interrupt in an alarm callback */
i40e_dev_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

i40e_pf_enable_irq0(hw);
rte_intr_enable(&(dev->pci_dev->intr_handle));
@@ -5594,7 +5594,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
return;
else
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

done:
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 34eb274..bd89cd9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1341,7 +1341,7 @@ i40evf_handle_pf_event(__rte_unused struct rte_eth_dev *dev,
switch (pf_msg->event) {
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event\n");
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
break;
case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event\n");
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:25 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/mlx4/mlx4.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 1553b2e..3e57cca 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5448,7 +5448,7 @@ mlx4_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -5471,7 +5471,7 @@ mlx4_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:26 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/mlx5/mlx5_ethdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index bf4232a..c76e754 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1069,7 +1069,7 @@ mlx5_dev_link_status_handler(void *arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
@@ -1092,7 +1092,7 @@ mlx5_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
ret = priv_dev_link_status_handler(priv, dev);
priv_unlock(priv);
if (ret)
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

/**
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:27 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/nfp/nfp_net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index d526f34..a2b9056 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1219,7 +1219,7 @@ nfp_net_dev_interrupt_delayed_handler(void *param)
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;

nfp_net_link_update(dev, 0);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);

nfp_net_dev_link_status_print(dev);
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:28 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/thunderx/nicvf_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index b758c9f..c61e171 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -108,7 +108,7 @@ nicvf_interrupt(void *arg)
nicvf_set_eth_link_status(nic,
&nic->eth_dev->data->dev_link);
_rte_eth_dev_callback_process(nic->eth_dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

rte_eal_alarm_set(NICVF_INTR_POLL_INTERVAL_MS * 1000,
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:29 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/vhost/rte_eth_vhost.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 409e090..421cdba 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -559,7 +559,7 @@ new_device(int vid)

RTE_LOG(INFO, PMD, "New connection established\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);

return 0;
}
@@ -626,7 +626,7 @@ destroy_device(int vid)

RTE_LOG(INFO, PMD, "Connection closed\n");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}

static int
@@ -655,7 +655,7 @@ vring_state_changed(int vid, uint16_t vring, int enable)
RTE_LOG(INFO, PMD, "vring%u is %s\n",
vring, enable ? "enabled" : "disabled");

- _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE);
+ _rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_QUEUE_STATE, NULL);

return 0;
}
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:30 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b4dfc0a..2f0065a 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1103,7 +1103,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
if (isr & VIRTIO_PCI_ISR_CONFIG) {
if (virtio_dev_link_update(dev, 0) == 0)
_rte_eth_dev_callback_process(dev,
- RTE_ETH_EVENT_INTR_LSC);
+ RTE_ETH_EVENT_INTR_LSC, NULL);
}

}
--
2.9.0
Bernard Iremonger
2016-10-06 11:26:31 UTC
Permalink
add parameter to call of _rte_eth_dev_callback_process function

Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/enic/enic_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 15a05b4..fb72491 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -436,7 +436,7 @@ enic_intr_handler(__rte_unused struct rte_intr_handle *handle,
vnic_intr_return_all_credits(&enic->intr);

enic_link_update(enic);
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
enic_log_q_error(enic);
}
--
2.9.0
Bernard Iremonger
2016-10-04 14:52:13 UTC
Permalink
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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
lib/librte_ether/rte_ethdev.c | 17 +++++++++++++
lib/librte_ether/rte_ethdev.h | 44 ++++++++++++++++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 2 ++
3 files changed, 63 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index c517e88..e850d88 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2510,6 +2510,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;

@@ -2519,6 +2533,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 7218b6f..b418c5e 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ 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 */
};

@@ -3093,6 +3094,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 72be66d..6f97a8f 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -143,6 +143,8 @@ DPDK_16.07 {
DPDK_16.11 {
global:

+ _rte_eth_dev_callback_process_generic;
+ _rte_eth_dev_callback_process_vf;
rte_eth_dev_pci_probe;
rte_eth_dev_pci_remove;
--
2.9.0
Thomas Monjalon
2016-10-05 16:10:29 UTC
Permalink
Post by Bernard Iremonger
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.
I have some difficulties to parse this explanation.
Please could you reword it and precise the direction of the message
and the use case context?
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2510,6 +2510,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);
+}
This function is just adding a parameter, compared to the legacy
_rte_eth_dev_callback_process.
Why calling it process_vf?
And by the way, why not just replacing the legacy function?
As it is a driver interface, there is no ABI restriction.
Post by Bernard Iremonger
+
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+ enum rte_eth_event_type event, void *param)
+{
[...]
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ 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 */
};
Either we choose to have a "generic" VF event well documented,
or it is just a specific event with a tip on where to find the doc.
Here we need at least to know how to handle the argument.
Post by Bernard Iremonger
+/**
+ * _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.
+ *
+ * Pointer to struct rte_eth_dev.
+ * Eth device interrupt event type.
+ *
+ * parameters to pass back to user application.
+ *
+ * void
+ */
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+ enum rte_eth_event_type event, void *param);
This is really an internal function and should not be exported at all.
Iremonger, Bernard
2016-10-05 17:04:49 UTC
Permalink
Hi Thomas,

<snip>
Subject: Re: [dpdk-dev] [PATCH v4 1/2] librte_ether: add internal callback
functions
Post by Bernard Iremonger
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.
I have some difficulties to parse this explanation.
Please could you reword it and precise the direction of the message and the
use case context?
I will reword the explanation and add use case context.
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2510,6 +2510,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);
}
This function is just adding a parameter, compared to the legacy
_rte_eth_dev_callback_process.
Why calling it process_vf?
The parameter is just being added for the VF event, the handling of the other events is unchanged.
And by the way, why not just replacing the legacy function?
As it is a driver interface, there is no ABI restriction.
I thought there would be an ABI issue if the legacy function is replaced.
The _rte_eth_dev_callback_process is exported in DPDK 2.2 and used in the following PMD's, lib and app:

app/test/virtual_pmd
drivers/net/e1000
drivers/net/ixgbe
drivers/net/mlx5
drivers/net/vhost
drivers/net/virtio
lib/librte_ether

Adding a parameter to _rte_eth_dev_callback_process() will impact all of the above.
Will this cause an ABI issue?
Post by Bernard Iremonger
+
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+ enum rte_eth_event_type event, void *param) {
[...]
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ enum rte_eth_event_type {
/**< queue state event (enabled/disabled)
*/
Post by Bernard Iremonger
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 */
};
Either we choose to have a "generic" VF event well documented, or it is just
a specific event with a tip on where to find the doc.
Here we need at least to know how to handle the argument.
It is a specific event for VF to PF messages, details on the function and arguments are in the rte_ethdev.h file.
Post by Bernard Iremonger
+/**
+ * _rte_eth_dev_callback_process and
_rte_eth_dev_callback_process_vf
Post by Bernard Iremonger
+ * It is for DPDK internal user only. User application should not
+call it
+ * directly.
+ *
+ * Pointer to struct rte_eth_dev.
+ * Eth device interrupt event type.
+ *
+ * parameters to pass back to user application.
+ *
+ * void
+ */
+void
+_rte_eth_dev_callback_process_generic(struct rte_eth_dev *dev,
+ enum rte_eth_event_type event, void
*param);
This is really an internal function and should not be exported at all.
Both new functions are internal I will make them static and remove them from the map file.
When the functions are made static, should the function declarations be moved from rte_ethdev.h to rte_ethdev.c ?

Thanks for the review.

Regards,

Bernard.
Thomas Monjalon
2016-10-05 17:19:40 UTC
Permalink
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2510,6 +2510,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);
}
This function is just adding a parameter, compared to the legacy
_rte_eth_dev_callback_process.
Why calling it process_vf?
The parameter is just being added for the VF event, the handling of the other events is unchanged.
Post by Thomas Monjalon
And by the way, why not just replacing the legacy function?
As it is a driver interface, there is no ABI restriction.
I thought there would be an ABI issue if the legacy function is replaced.
app/test/virtual_pmd
drivers/net/e1000
drivers/net/ixgbe
drivers/net/mlx5
drivers/net/vhost
drivers/net/virtio
lib/librte_ether
Adding a parameter to _rte_eth_dev_callback_process() will impact all of the above.
Will this cause an ABI issue?
No because ABI is for applications (Application Binary Interface).
Here you are just changing the driver interface. And we have no commitment
to maintain the compatibility of this interface for external drivers.
Post by Iremonger, Bernard
Post by Thomas Monjalon
Post by Bernard Iremonger
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3026,6 +3026,7 @@ enum rte_eth_event_type {
/**< queue state event (enabled/disabled)
*/
Post by Bernard Iremonger
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 */
};
Either we choose to have a "generic" VF event well documented, or it is just
a specific event with a tip on where to find the doc.
Here we need at least to know how to handle the argument.
It is a specific event for VF to PF messages, details on the function and arguments are in the rte_ethdev.h file.
No I think it is only explained in the ixgbe code.
Bernard Iremonger
2016-10-04 14:52:14 UTC
Permalink
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_PMD_IXGBE_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: Alex Zelezniak <***@att.com>
Signed-off-by: Bernard Iremonger <***@intel.com>
---
drivers/net/ixgbe/ixgbe_pf.c | 42 +++++++++++++++++++++++++++++++++------
drivers/net/ixgbe/rte_pmd_ixgbe.h | 17 ++++++++++++++++
2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 56393ff..5277517 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -1,7 +1,7 @@
/*-
* 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
@@ -51,6 +51,7 @@

#include "base/ixgbe_common.h"
#include "ixgbe_ethdev.h"
+#include "rte_pmd_ixgbe.h"

#define IXGBE_MAX_VFTA (128)
#define IXGBE_VF_MSG_SIZE_DEFAULT 1
@@ -660,6 +661,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_pmd_ixgbe_mb_event_param cb_param;

retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
if (retval) {
@@ -674,27 +676,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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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_PMD_IXGBE_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 +733,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_PMD_IXGBE_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]);
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index 33b5b2d..2f6cf46 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -181,4 +181,21 @@ int rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on);
*/
int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Response sent back to ixgbe driver from user app after callback
+ */
+enum rte_pmd_ixgbe_mb_event_rsp {
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_IXGBE_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_IXGBE_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_IXGBE_MB_EVENT_MAX /**< max value of this enum */
+};
+
+struct rte_pmd_ixgbe_mb_event_param {
+ uint16_t vfid;
+ uint16_t msg_type;
+ uint16_t retval;
+ void *userdata;
+};
#endif /* _PMD_IXGBE_H_ */
--
2.9.0
Continue reading on narkive:
Loading...