All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add floating VEB support for i40e
@ 2016-01-21  7:24 Zhe Tao
  2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
  2016-01-21  7:24 ` [PATCH 2/2] i40e: Add floating VEB support in i40e Zhe Tao
  0 siblings, 2 replies; 79+ messages in thread
From: Zhe Tao @ 2016-01-21  7:24 UTC (permalink / raw)
  To: dev

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 drivers/net/i40e/Makefile                  |  2 +-
 drivers/net/i40e/i40e_ethdev.c             | 92 ++++++++++++++++++++++--------
 drivers/net/i40e/i40e_ethdev.h             |  3 +
 drivers/net/i40e/i40e_pf.c                 | 10 +++-
 lib/librte_eal/common/eal_common_options.c |  4 ++
 lib/librte_eal/common/eal_internal_cfg.h   |  1 +
 lib/librte_eal/common/eal_options.h        |  2 +
 7 files changed, 86 insertions(+), 28 deletions(-)

-- 
2.1.4

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

* PATCH 1/2] i40e: support floating VEB config
  2016-01-21  7:24 [PATCH 0/2] Add floating VEB support for i40e Zhe Tao
@ 2016-01-21  7:24 ` Zhe Tao
  2016-01-21  7:29   ` David Marchand
                     ` (2 more replies)
  2016-01-21  7:24 ` [PATCH 2/2] i40e: Add floating VEB support in i40e Zhe Tao
  1 sibling, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-01-21  7:24 UTC (permalink / raw)
  To: dev

Add the new floating related argument option in the EAL.
using this parameter, all the samples can decide whether to use legacy VEB/VEPA,
 or floating VEB.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..0dd303a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to disable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
-- 
2.1.4

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

* [PATCH 2/2] i40e: Add floating VEB support in i40e
  2016-01-21  7:24 [PATCH 0/2] Add floating VEB support for i40e Zhe Tao
  2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-01-21  7:24 ` Zhe Tao
  1 sibling, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-01-21  7:24 UTC (permalink / raw)
  To: dev

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/Makefile      |  2 +-
 drivers/net/i40e/i40e_ethdev.c | 92 ++++++++++++++++++++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h |  3 ++
 drivers/net/i40e/i40e_pf.c     | 10 ++++-
 4 files changed, 79 insertions(+), 28 deletions(-)

diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 033ee4a..2e01d45 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..b1605ca 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3592,21 +3592,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3618,9 +3624,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3632,11 +3638,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, false, &veb->seid, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false, false,
+				      &veb->seid, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      false, false, &veb->seid, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3688,20 +3702,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN) {
-		/* Remove vsi from parent's sibling list */
-		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
-			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
-			return I40E_ERR_PARAM;
-		}
-		TAILQ_REMOVE(&vsi->parent_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
-
 		/* Remove all switch element of the VSI */
 		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
 		if (ret != I40E_SUCCESS)
@@ -3837,7 +3852,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3849,11 +3865,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4022,7 +4055,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4130,8 +4167,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1f9792b..1ff57b6 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -203,6 +204,7 @@ struct i40e_tx_queue;
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -254,6 +256,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index cbf4e5b..cc315f6 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -223,9 +223,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (internal_config.floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: PATCH 1/2] i40e: support floating VEB config
  2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-01-21  7:29   ` David Marchand
  2016-01-21  7:53     ` Vincent JARDIN
  2016-02-03  8:53   ` Xu, Qian Q
  2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 1 reply; 79+ messages in thread
From: David Marchand @ 2016-01-21  7:29 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev

Hello,

On Thu, Jan 21, 2016 at 8:24 AM, Zhe Tao <zhe.tao@intel.com> wrote:
> Add the new floating related argument option in the EAL.
> using this parameter, all the samples can decide whether to use legacy VEB/VEPA,
>  or floating VEB.

Not familiar with this.
Can you confirm this stuff make sense for anything but i40e ?


Regards,
-- 
David Marchand

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

* Re: PATCH 1/2] i40e: support floating VEB config
  2016-01-21  7:29   ` David Marchand
@ 2016-01-21  7:53     ` Vincent JARDIN
  0 siblings, 0 replies; 79+ messages in thread
From: Vincent JARDIN @ 2016-01-21  7:53 UTC (permalink / raw)
  To: David Marchand, Zhe Tao; +Cc: dev

On 21/01/2016 08:29, David Marchand wrote:
> Hello,
>
> On Thu, Jan 21, 2016 at 8:24 AM, Zhe Tao <zhe.tao@intel.com> wrote:
>> Add the new floating related argument option in the EAL.
>> using this parameter, all the samples can decide whether to use legacy VEB/VEPA,
>>   or floating VEB.
>
> Not familiar with this.
> Can you confirm this stuff make sense for anything but i40e ?

+1 with David. On Linux kernel, only i40e includes this feature.

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

* Re: PATCH 1/2] i40e: support floating VEB config
  2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
  2016-01-21  7:29   ` David Marchand
@ 2016-02-03  8:53   ` Xu, Qian Q
  2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Xu, Qian Q @ 2016-02-03  8:53 UTC (permalink / raw)
  To: Tao, Zhe, dev

If test the feature by testpmd, how to set the parameter? Need testpmd document update also? 

Thanks
Qian

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
Sent: Thursday, January 21, 2016 3:24 PM
To: dev@dpdk.org
Subject: [dpdk-dev] PATCH 1/2] i40e: support floating VEB config

Add the new floating related argument option in the EAL.
using this parameter, all the samples can decide whether to use legacy VEB/VEPA,  or floating VEB.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..0dd303a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to disable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
--
2.1.4

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

* [PATCH 0/2 v2] i40e: Add floating VEB support for i40e
  2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
  2016-01-21  7:29   ` David Marchand
  2016-02-03  8:53   ` Xu, Qian Q
@ 2016-02-23  9:13   ` Zhe Tao
  2016-02-23  9:13     ` [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
                       ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-02-23  9:13 UTC (permalink / raw)
  To: dev

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 doc/guides/rel_notes/release_16_04.rst     |  2 +
 drivers/net/i40e/Makefile                  |  2 +-
 drivers/net/i40e/i40e_ethdev.c             | 92 ++++++++++++++++++++++--------
 drivers/net/i40e/i40e_ethdev.h             |  3 +
 drivers/net/i40e/i40e_pf.c                 | 10 +++-
 lib/librte_eal/common/eal_common_options.c |  4 ++
 lib/librte_eal/common/eal_internal_cfg.h   |  1 +
 lib/librte_eal/common/eal_options.h        |  2 +
 8 files changed, 88 insertions(+), 28 deletions(-)

V2: Added the release notes and changed commit log. 

-- 
2.1.4

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

* [PATCH 1/2 v2] i40e: support floating VEB config
  2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-02-23  9:13     ` Zhe Tao
  2016-02-25  0:55       ` Wu, Jingjing
  2016-02-23  9:13     ` [PATCH 2/2 v2] i40e: Add floating VEB support in i40e Zhe Tao
  2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-02-23  9:13 UTC (permalink / raw)
  To: dev

Add the new floating related argument option in the EAL.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA,
 or floating VEB.
Even the floating argument is provided in the EAL, but this floating
feature are only support for FVL so far.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..0dd303a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to disable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
-- 
2.1.4

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

* [PATCH 2/2 v2] i40e: Add floating VEB support in i40e
  2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
  2016-02-23  9:13     ` [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
@ 2016-02-23  9:13     ` Zhe Tao
  2016-02-25  1:15       ` Wu, Jingjing
  2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-02-23  9:13 UTC (permalink / raw)
  To: dev

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |  2 +
 drivers/net/i40e/Makefile              |  2 +-
 drivers/net/i40e/i40e_ethdev.c         | 92 +++++++++++++++++++++++++---------
 drivers/net/i40e/i40e_ethdev.h         |  3 ++
 drivers/net/i40e/i40e_pf.c             | 10 +++-
 5 files changed, 81 insertions(+), 28 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5786f74..446112c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 033ee4a..2e01d45 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..b75d929 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3592,21 +3592,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3618,9 +3624,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3632,11 +3638,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, false, &veb->seid, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false, false,
+				      &veb->seid, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      false, false, &veb->seid, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3688,20 +3702,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN) {
-		/* Remove vsi from parent's sibling list */
-		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
-			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
-			return I40E_ERR_PARAM;
-		}
-		TAILQ_REMOVE(&vsi->parent_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
-
 		/* Remove all switch element of the VSI */
 		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
 		if (ret != I40E_SUCCESS)
@@ -3837,7 +3852,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3849,11 +3865,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4022,7 +4055,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4130,8 +4167,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 6edd7dd..19246db 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -203,6 +204,7 @@ struct i40e_tx_queue;
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -254,6 +256,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index cbf4e5b..cc315f6 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -223,9 +223,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (internal_config.floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: [PATCH 1/2 v2] i40e: support floating VEB config
  2016-02-23  9:13     ` [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
@ 2016-02-25  0:55       ` Wu, Jingjing
  0 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-02-25  0:55 UTC (permalink / raw)
  To: Tao, Zhe, dev

> @@ -68,6 +68,7 @@ struct internal_config {
>  	volatile unsigned xen_dom0_support; /**< support app running on
> Xen Dom0*/
>  	volatile unsigned no_pci;         /**< true to disable PCI */
>  	volatile unsigned no_hpet;        /**< true to disable HPET */
> +	volatile unsigned floating;       /**< true to disable floating VEB */
true to disable( -> enable) floating VEB.
>  	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC
> mapping
> 
> 	* instead of native TSC */
>  	volatile unsigned no_shconf;      /**< true if there is no shared config
> */
> diff --git a/lib/librte_eal/common/eal_options.h
> b/lib/librte_eal/common/eal_options.h
> index a881c62..413c9e6 100644
> --- a/lib/librte_eal/common/eal_options.h
> +++ b/lib/librte_eal/common/eal_options.h
> @@ -83,6 +83,8 @@ enum {
>  	OPT_VMWARE_TSC_MAP_NUM,
>  #define OPT_XEN_DOM0          "xen-dom0"
>  	OPT_XEN_DOM0_NUM,
> +#define OPT_FLOATING          "floating"
> +	OPT_FLOATING_NUM,
>  	OPT_LONG_MAX_NUM
>  };
>
New option is added, any doc to update?
> --
> 2.1.4

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

* Re: [PATCH 2/2 v2] i40e: Add floating VEB support in i40e
  2016-02-23  9:13     ` [PATCH 2/2 v2] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-02-25  1:15       ` Wu, Jingjing
  0 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-02-25  1:15 UTC (permalink / raw)
  To: Tao, Zhe, dev

>  	if (ret != I40E_SUCCESS) {
>  		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d", @@ -
> 3688,20 +3702,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
>  		i40e_veb_release(vsi->veb);
>  	}
> 
> +	if (vsi->floating_veb) {
> +		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
> +			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
> +				return -1;
> +			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list,
> list);
> +		}
> +		i40e_veb_release(vsi->floating_veb);
> +	}
> +
>  	/* Remove all macvlan filters of the VSI */
>  	i40e_vsi_remove_all_macvlan_filter(vsi);
>  	TAILQ_FOREACH(f, &vsi->mac_list, next)
>  		rte_free(f);
> 
>  	if (vsi->type != I40E_VSI_MAIN) {
> -		/* Remove vsi from parent's sibling list */
> -		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL)
> {
> -			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
> -			return I40E_ERR_PARAM;
> -		}
> -		TAILQ_REMOVE(&vsi->parent_vsi->veb->head,
> -				&vsi->sib_vsi_list, list);
Why do you think these line is unnecessary? We need to remove it from vsi list.
> -
>  		/* Remove all switch element of the VSI */
>  		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
>  		if (ret != I40E_SUCCESS)
> @@ -3837,7 +3852,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
>  	struct ether_addr broadcast =
>  		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
> 
> -	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
> +	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
> +	    uplink_vsi == NULL) {
>  		PMD_DRV_LOG(ERR, "VSI setup failed, "
>  			    "VSI link shouldn't be NULL");
>  		return NULL;
> @@ -3849,11 +3865,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
>  		return NULL;
>  	}
> 
> -	/* If uplink vsi didn't setup VEB, create one first */
> -	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
> +	/* two situations
> +	 * 1.type is not MAIN and uplink vsi is not NULL
> +	 * If uplink vsi didn't setup VEB, create one first under veb field
> +	 * 2.type is SRIOV and the uplink is NULL
> +	 * If floating VEB is NULL, create one veb under floating veb field
> +	 */
> +
> +	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
> +	    uplink_vsi->veb == NULL) {
>  		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
> 
> -		if (NULL == uplink_vsi->veb) {
> +		if (uplink_vsi->veb == NULL) {
> +			PMD_DRV_LOG(ERR, "VEB setup failed");
> +			return NULL;
> +		}
> +	}
> +
> +	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
> +	    pf->main_vsi->floating_veb == NULL) {
> +		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
> +
> +		if (pf->main_vsi->floating_veb == NULL) {
>  			PMD_DRV_LOG(ERR, "VEB setup failed");
>  			return NULL;
>  		}
> @@ -4022,7 +4055,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
>  		 * For other VSI, the uplink_seid equals to uplink VSI's
>  		 * uplink_seid since they share same VEB
>  		 */
> -		vsi->uplink_seid = uplink_vsi->uplink_seid;
> +		if (uplink_vsi == NULL) {
> +			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
> +		} else {
> +			vsi->uplink_seid = uplink_vsi->uplink_seid;
> +		}
{} is not necessary.

>  		ctxt.pf_num = hw->pf_id;
>  		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
>  		ctxt.uplink_seid = vsi->uplink_seid;
> @@ -4130,8 +4167,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
>  		vsi->seid = ctxt.seid;
>  		vsi->vsi_id = ctxt.vsi_number;
>  		vsi->sib_vsi_list.vsi = vsi;
> -		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
> -				&vsi->sib_vsi_list, list);
> +		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
> +			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb-
> >head,
> +					  &vsi->sib_vsi_list, list);
> +		} else {
> +			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
> +					  &vsi->sib_vsi_list, list);
> +		}
>  	}
> 
>  	/* MAC/VLAN configuration */
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 6edd7dd..19246db 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -36,6 +36,7 @@
> 
>  #include <rte_eth_ctrl.h>
>  #include <rte_time.h>
> +#include <eal_internal_cfg.h>
> 
>  #define I40E_VLAN_TAG_SIZE        4
> 
> @@ -203,6 +204,7 @@ struct i40e_tx_queue;  struct i40e_veb {
>  	struct i40e_vsi_list_head head;
>  	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
> +	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
>  	uint16_t seid; /* The seid of VEB itself */
>  	uint16_t uplink_seid; /* The uplink seid of this VEB */
>  	uint16_t stats_idx;
> @@ -254,6 +256,7 @@ struct i40e_vsi {
>  	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
>  	struct i40e_vsi *parent_vsi;
>  	struct i40e_veb *veb;    /* Associated veb, could be null */
> +	struct i40e_veb *floating_veb; /* Associated floating veb */
>  	bool offset_loaded;
>  	enum i40e_vsi_type type; /* VSI types */
>  	uint16_t vlan_num;       /* Total VLAN number */
> diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c index
> cbf4e5b..cc315f6 100644
> --- a/drivers/net/i40e/i40e_pf.c
> +++ b/drivers/net/i40e/i40e_pf.c
> @@ -223,9 +223,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool
> do_hw_reset)
>  	vf->reset_cnt++;
>  	I40E_WRITE_FLUSH(hw);
> 
> +	if (internal_config.floating == true) {
> +		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
> +			NULL, vf->vf_idx);
> +	} else {
>  	/* Allocate resource again */
> -	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
> -			vf->pf->main_vsi, vf->vf_idx);
> +		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
> +				vf->pf->main_vsi, vf->vf_idx);
> +	}
{} is not necessary. How about to check the NVM version?

Thanks
Jingjing

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

* [PATCH 0/2 v3] i40e: Add floating VEB support for i40e
  2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
  2016-02-23  9:13     ` [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
  2016-02-23  9:13     ` [PATCH 2/2 v2] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-02-25  6:31     ` Zhe Tao
  2016-02-25  6:31       ` [PATCH 1/2 v3] i40e: support floating VEB config Zhe Tao
                         ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-02-25  6:31 UTC (permalink / raw)
  To: dev

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
 the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 doc/guides/rel_notes/release_16_04.rst     |   2 +
 doc/guides/testpmd_app_ug/run_app.rst      |   4 ++
 drivers/net/i40e/Makefile                  |   2 +-
 drivers/net/i40e/i40e_ethdev.c             | 105 ++++++++++++++++++++++++-----
 drivers/net/i40e/i40e_ethdev.h             |   4 ++
 drivers/net/i40e/i40e_pf.c                 |  11 ++-
 lib/librte_eal/common/eal_common_options.c |   4 ++
 lib/librte_eal/common/eal_internal_cfg.h   |   1 +
 lib/librte_eal/common/eal_options.h        |   2 +
 9 files changed, 114 insertions(+), 21 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 

-- 
2.1.4

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

* [PATCH 1/2 v3] i40e: support floating VEB config
  2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-02-25  6:31       ` Zhe Tao
  2016-02-25  6:31       ` [PATCH 2/2 v3] i40e: Add floating VEB support in i40e Zhe Tao
  2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-02-25  6:31 UTC (permalink / raw)
  To: dev

Add the new floating related argument option in the EAL.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA,
 or floating VEB.
Even the floating argument is provided in the EAL, but this floating
feature are only support for FVL so far.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index f605564..2f02f63 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--floating``
+
+    Enable floating feature for virtual ethernet switch in the NIC.
+    Now only Intel i40e NIC supports this feature.
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..19b321a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to enable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
-- 
2.1.4

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

* [PATCH 2/2 v3] i40e: Add floating VEB support in i40e
  2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
  2016-02-25  6:31       ` [PATCH 1/2 v3] i40e: support floating VEB config Zhe Tao
@ 2016-02-25  6:31       ` Zhe Tao
  2016-03-02  2:31         ` Xu, Qian Q
  2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-02-25  6:31 UTC (permalink / raw)
  To: dev

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
 the floating VEB. When connect to the floating VEB a new floating VEB is
 created. Now all the VFs need to connect to floating VEB or legacy VEB,
 cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/Makefile              |   2 +-
 drivers/net/i40e/i40e_ethdev.c         | 105 +++++++++++++++++++++++++++------
 drivers/net/i40e/i40e_ethdev.h         |   4 ++
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 103 insertions(+), 21 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5786f74..446112c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 033ee4a..2e01d45 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..f8554c9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -744,6 +744,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	pf->adapter->eth_dev = dev;
 	pf->dev_data = dev->data;
+	pf->floating = internal_config.floating;
 
 	hw->back = I40E_PF_TO_ADAPTER(pf);
 	hw->hw_addr = (uint8_t *)(pci_dev->mem_resource[0].addr);
@@ -3592,21 +3593,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3618,9 +3625,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3632,11 +3639,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, false, &veb->seid, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false, false,
+				      &veb->seid, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      false, false, &veb->seid, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3688,12 +3703,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3707,6 +3732,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -3837,7 +3879,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3849,11 +3892,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4022,7 +4082,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4130,8 +4194,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 6edd7dd..3bac60a 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -203,6 +204,7 @@ struct i40e_tx_queue;
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -254,6 +256,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
@@ -440,6 +443,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index cbf4e5b..7ce399b 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: [PATCH 2/2 v3] i40e: Add floating VEB support in i40e
  2016-02-25  6:31       ` [PATCH 2/2 v3] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-02  2:31         ` Xu, Qian Q
  0 siblings, 0 replies; 79+ messages in thread
From: Xu, Qian Q @ 2016-03-02  2:31 UTC (permalink / raw)
  To: Tao, Zhe, dev

Suggest to add document for why to have it, the basic usage and the sample of how to use it. 

Thanks
Qian

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
Sent: Thursday, February 25, 2016 2:32 PM
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 2/2 v3] i40e: Add floating VEB support in i40e

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or  the floating VEB. When connect to the floating VEB a new floating VEB is  created. Now all the VFs need to connect to floating VEB or legacy VEB,  cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the 802.1Qbg spec.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/Makefile              |   2 +-
 drivers/net/i40e/i40e_ethdev.c         | 105 +++++++++++++++++++++++++++------
 drivers/net/i40e/i40e_ethdev.h         |   4 ++
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 103 insertions(+), 21 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5786f74..446112c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile index 033ee4a..2e01d45 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a  CFLAGS += -O3  CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF  CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index ef24122..f8554c9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -744,6 +744,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	pf->adapter->eth_dev = dev;
 	pf->dev_data = dev->data;
+	pf->floating = internal_config.floating;
 
 	hw->back = I40E_PF_TO_ADAPTER(pf);
 	hw->hw_addr = (uint8_t *)(pci_dev->mem_resource[0].addr);
@@ -3592,21 +3593,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3618,9 +3625,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3632,11 +3639,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, false, &veb->seid, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false, false,
+				      &veb->seid, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      false, false, &veb->seid, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d", @@ -3688,12 +3703,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL"); @@ -3707,6 +3732,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -3837,7 +3879,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3849,11 +3892,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4022,7 +4082,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4130,8 +4194,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 6edd7dd..3bac60a 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -203,6 +204,7 @@ struct i40e_tx_queue;  struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -254,6 +256,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
@@ -440,6 +443,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c index cbf4e5b..7ce399b 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)  {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel; @@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
--
2.1.4

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

* [PATCH 0/2 v4] i40e: Add floating VEB support for i40e
  2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
  2016-02-25  6:31       ` [PATCH 1/2 v3] i40e: support floating VEB config Zhe Tao
  2016-02-25  6:31       ` [PATCH 2/2 v3] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-02  8:08       ` Zhe Tao
  2016-03-02  8:08         ` [PATCH 1/2 v4] i40e: support floating VEB config Zhe Tao
                           ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-02  8:08 UTC (permalink / raw)
  To: dev

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 doc/guides/rel_notes/release_16_04.rst     |   2 +
 doc/guides/testpmd_app_ug/run_app.rst      |   4 +
 drivers/net/i40e/Makefile                  |   2 +-
 drivers/net/i40e/i40e_ethdev.c             | 115 ++++++++++++++++++++++++-----
 drivers/net/i40e/i40e_ethdev.h             |   8 ++
 drivers/net/i40e/i40e_pf.c                 |  11 ++-
 lib/librte_eal/common/eal_common_options.c |   4 +
 lib/librte_eal/common/eal_internal_cfg.h   |   1 +
 lib/librte_eal/common/eal_options.h        |   2 +
 9 files changed, 126 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Add the FW version check otherwise it will cause the segment fault.
-- 
2.1.4

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

* [PATCH 1/2 v4] i40e: support floating VEB config
  2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-03-02  8:08         ` Zhe Tao
  2016-03-02  8:08         ` [PATCH 2/2 v4] i40e: Add floating VEB support in i40e Zhe Tao
  2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-02  8:08 UTC (permalink / raw)
  To: dev

Add the new floating related argument option in the EAL.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
Even the floating argument is provided in the EAL, but this floating
feature are only support for FVL so far.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index f605564..2f02f63 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--floating``
+
+    Enable floating feature for virtual ethernet switch in the NIC.
+    Now only Intel i40e NIC supports this feature.
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..19b321a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to enable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
-- 
2.1.4

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

* [PATCH 2/2 v4] i40e: Add floating VEB support in i40e
  2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-02  8:08         ` [PATCH 1/2 v4] i40e: support floating VEB config Zhe Tao
@ 2016-03-02  8:08         ` Zhe Tao
  2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-02  8:08 UTC (permalink / raw)
  To: dev

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable in the specific version of FW.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/Makefile              |   2 +-
 drivers/net/i40e/i40e_ethdev.c         | 115 +++++++++++++++++++++++++++------
 drivers/net/i40e/i40e_ethdev.h         |   8 +++
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 115 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 5786f74..446112c 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -46,6 +46,8 @@ This section should contain new features added in this release. Sample format:
 
 * **Added vhost-user live migration support.**
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 033ee4a..2e01d45 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..cf3c346 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -802,6 +802,13 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if ((hw->aq.fw_maj_ver == FLOATING_FW_MAJ) &&
+	    (hw->aq.fw_min_ver == FLOATING_FW_MIN)) {
+		pf->floating = internal_config.floating;
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
@@ -3592,21 +3599,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3618,9 +3631,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3632,11 +3645,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, false, &veb->seid, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false, false,
+				      &veb->seid, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, false, &veb->seid, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3652,10 +3673,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3688,12 +3709,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3707,6 +3738,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -3837,7 +3885,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3849,11 +3898,28 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4022,7 +4088,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4130,8 +4200,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 6edd7dd..9ace7af 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -168,6 +169,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 0
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -203,6 +208,7 @@ struct i40e_tx_queue;
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -254,6 +260,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
@@ -440,6 +447,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index cbf4e5b..7ce399b 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH 0/2 v5] i40e: Add floating VEB support for i40e
  2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-02  8:08         ` [PATCH 1/2 v4] i40e: support floating VEB config Zhe Tao
  2016-03-02  8:08         ` [PATCH 2/2 v4] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-23 12:27         ` Zhe Tao
  2016-03-23 12:27           ` [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
                             ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-23 12:27 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 doc/guides/rel_notes/release_16_04.rst     |   2 +
 doc/guides/testpmd_app_ug/run_app.rst      |   4 +
 drivers/net/i40e/Makefile                  |   2 +-
 drivers/net/i40e/i40e_ethdev.c             | 116 +++++++++++++++++++++++------
 drivers/net/i40e/i40e_ethdev.h             |   8 ++
 drivers/net/i40e/i40e_pf.c                 |  11 ++-
 lib/librte_eal/common/eal_common_options.c |   4 +
 lib/librte_eal/common/eal_internal_cfg.h   |   1 +
 lib/librte_eal/common/eal_options.h        |   2 +
 9 files changed, 126 insertions(+), 24 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
-- 
2.1.4

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

* [PATCH 1/2 v5] i40e: support floating VEB config
  2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-03-23 12:27           ` Zhe Tao
  2016-03-23 12:51             ` Thomas Monjalon
  2016-03-23 12:27           ` [PATCH 2/2 v5] i40e: Add floating VEB support in i40e Zhe Tao
  2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-03-23 12:27 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the EAL.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
Even the floating argument is provided in the EAL, but this floating
feature are only support for FVL so far.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
 lib/librte_eal/common/eal_common_options.c | 4 ++++
 lib/librte_eal/common/eal_internal_cfg.h   | 1 +
 lib/librte_eal/common/eal_options.h        | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index f605564..2f02f63 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Use malloc instead of hugetlbfs.
 
+*   ``--floating``
+
+    Enable floating feature for virtual ethernet switch in the NIC.
+    Now only Intel i40e NIC supports this feature.
 
 Testpmd Command-line Options
 ----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 29942ea..29ed7bf 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,7 @@ eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_FLOATING,          0, NULL, OPT_FLOATING_NUM         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -896,6 +897,9 @@ eal_parse_common_option(int opt, const char *optarg,
 			return -1;
 		}
 		break;
+	case OPT_FLOATING_NUM:
+		conf->floating = 1;
+		break;
 
 	/* don't know what to do, leave this to caller */
 	default:
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..19b321a 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -68,6 +68,7 @@ struct internal_config {
 	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
+	volatile unsigned floating;       /**< true to enable floating VEB */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
 										* instead of native TSC */
 	volatile unsigned no_shconf;      /**< true if there is no shared config */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..413c9e6 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,8 @@ enum {
 	OPT_VMWARE_TSC_MAP_NUM,
 #define OPT_XEN_DOM0          "xen-dom0"
 	OPT_XEN_DOM0_NUM,
+#define OPT_FLOATING          "floating"
+	OPT_FLOATING_NUM,
 	OPT_LONG_MAX_NUM
 };
 
-- 
2.1.4

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

* [PATCH 2/2 v5] i40e: Add floating VEB support in i40e
  2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-23 12:27           ` [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
@ 2016-03-23 12:27           ` Zhe Tao
  2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-23 12:27 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable in the specific version of FW.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/Makefile              |   2 +-
 drivers/net/i40e/i40e_ethdev.c         | 116 +++++++++++++++++++++++++++------
 drivers/net/i40e/i40e_ethdev.h         |   8 +++
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 115 insertions(+), 24 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9922bcb..1545872 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -248,6 +248,8 @@ This section should contain new features added in this release. Sample format:
 
   New application implementing an IPsec Security Gateway.
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 6dd6eaa..8f7146f 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -39,7 +39,7 @@ LIB = librte_pmd_i40e.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -DPF_DRIVER -DVF_DRIVER -DINTEGRATED_VF
 CFLAGS += -DX722_SUPPORT -DX722_A0_SUPPORT
-
+CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
 EXPORT_MAP := rte_pmd_i40e_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6fdae57..00f2da8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -829,6 +829,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = internal_config.floating;
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
@@ -3690,21 +3696,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3716,9 +3728,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3730,11 +3742,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3750,10 +3770,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3786,12 +3806,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3805,6 +3835,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -3973,7 +4020,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -3985,11 +4033,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -3997,6 +4052,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4006,7 +4071,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4160,7 +4225,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4268,8 +4337,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1c75672..1dc2607 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <eal_internal_cfg.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -219,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -259,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
@@ -446,6 +453,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: [PATCH 1/2 v5] i40e: support floating VEB config
  2016-03-23 12:27           ` [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
@ 2016-03-23 12:51             ` Thomas Monjalon
  2016-03-24  2:31               ` Zhe Tao
  0 siblings, 1 reply; 79+ messages in thread
From: Thomas Monjalon @ 2016-03-23 12:51 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

2016-03-23 20:27, Zhe Tao:
> Add the new floating related argument option in the EAL.
> Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
> or floating VEB.
> Even the floating argument is provided in the EAL, but this floating
> feature are only support for FVL so far.
> 
> Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> ---
>  doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
>  lib/librte_eal/common/eal_common_options.c | 4 ++++
>  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
>  lib/librte_eal/common/eal_options.h        | 2 ++
>  4 files changed, 11 insertions(+)

The label of this patch is "i40e" but it doesn't touch i40e.
Actually it is an EAL change but there should not be related to EAL.
It seems to be a config option of the device.
Please check how ftag has been enabled in fm10k:
	dpdk.org/browse/dpdk/commit/?id=7958b1310d5e

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

* Re: [PATCH 1/2 v5] i40e: support floating VEB config
  2016-03-23 12:51             ` Thomas Monjalon
@ 2016-03-24  2:31               ` Zhe Tao
  0 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-24  2:31 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, jingjing.wu

On Wed, Mar 23, 2016 at 01:51:09PM +0100, Thomas Monjalon wrote:
> 2016-03-23 20:27, Zhe Tao:
> > Add the new floating related argument option in the EAL.
> > Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
> > or floating VEB.
> > Even the floating argument is provided in the EAL, but this floating
> > feature are only support for FVL so far.
> > 
> > Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> > ---
> >  doc/guides/testpmd_app_ug/run_app.rst      | 4 ++++
> >  lib/librte_eal/common/eal_common_options.c | 4 ++++
> >  lib/librte_eal/common/eal_internal_cfg.h   | 1 +
> >  lib/librte_eal/common/eal_options.h        | 2 ++
> >  4 files changed, 11 insertions(+)
> 
> The label of this patch is "i40e" but it doesn't touch i40e.
> Actually it is an EAL change but there should not be related to EAL.
> It seems to be a config option of the device.
> Please check how ftag has been enabled in fm10k:
> 	dpdk.org/browse/dpdk/commit/?id=7958b1310d5e
very good suggestion, thanks for the advice

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

* [PATCH 0/2 v6] i40e: Add floating VEB support for i40e
  2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-23 12:27           ` [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
  2016-03-23 12:27           ` [PATCH 2/2 v5] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-24 10:48           ` Zhe Tao
  2016-03-24 10:48             ` [PATCH 1/2 v6] i40e: support floating VEB config Zhe Tao
                               ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-24 10:48 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W.

Zhe Tao (2):
  support floating VEB config
  Add floating VEB support in i40e

 doc/guides/nics/i40e.rst               |   7 ++
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/i40e_ethdev.c         | 154 ++++++++++++++++++++++++++++-----
 drivers/net/i40e/i40e_ethdev.h         |   8 ++
 drivers/net/i40e/i40e_pf.c             |  11 ++-
 5 files changed, 159 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 

-- 
2.1.4

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

* [PATCH 1/2 v6] i40e: support floating VEB config
  2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-03-24 10:48             ` Zhe Tao
  2016-03-24 10:48             ` [PATCH 2/2 v6] i40e: Add floating VEB support in i40e Zhe Tao
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-24 10:48 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6fdae57..01f1d3d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -739,6 +739,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floating";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -829,6 +867,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1c75672..7dc6936 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -446,6 +451,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH 2/2 v6] i40e: Add floating VEB support in i40e
  2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-24 10:48             ` [PATCH 1/2 v6] i40e: support floating VEB config Zhe Tao
@ 2016-03-24 10:48             ` Zhe Tao
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-24 10:48 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable in the specific version of FW.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |   7 +++
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/i40e_ethdev.c         | 110 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 109 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 4019b41..520ea09 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,10 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
+will use the floating VEB feature for all the VFs created by this PF device.
+
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9922bcb..1545872 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -248,6 +248,8 @@ This section should contain new features added in this release. Sample format:
 
   New application implementing an IPsec Security Gateway.
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 01f1d3d..87801d3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3734,21 +3734,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3760,9 +3766,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3774,11 +3780,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3794,10 +3808,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3830,12 +3844,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3849,6 +3873,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4017,7 +4058,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4029,11 +4071,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4041,6 +4090,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4050,7 +4109,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4204,7 +4263,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4312,8 +4375,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 7dc6936..09fb6e2 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH 0/3 v7] i40e: Add floating VEB support for i40e
  2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-24 10:48             ` [PATCH 1/2 v6] i40e: support floating VEB config Zhe Tao
  2016-03-24 10:48             ` [PATCH 2/2 v6] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-25  8:41             ` Zhe Tao
  2016-03-25  8:41               ` [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
                                 ` (5 more replies)
  2 siblings, 6 replies; 79+ messages in thread
From: Zhe Tao @ 2016-03-25  8:41 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W.

Zhe Tao (2):
  Support floating VEB config
  Add floating VEB support in i40e
  Add global reset support for i40e

 doc/guides/nics/i40e.rst               |   7 ++
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/i40e_ethdev.c         | 189 +++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h         |  38 +++++++
 drivers/net/i40e/i40e_pf.c             |  11 +-
 5 files changed, 223 insertions(+), 24 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
-- 
2.1.4

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

* [PATCH 1/3 v7] i40e: support floating VEB config
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
@ 2016-03-25  8:41               ` Zhe Tao
  2016-03-28  2:23                 ` Xu, Qian Q
  2016-03-25  8:41               ` [PATCH 2/3 v7] i40e: Add floating VEB support in i40e Zhe Tao
                                 ` (4 subsequent siblings)
  5 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-03-25  8:41 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6fdae57..01f1d3d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -739,6 +739,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floating";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -829,6 +867,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 1c75672..7dc6936 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -446,6 +451,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH 2/3 v7] i40e: Add floating VEB support in i40e
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-25  8:41               ` [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
@ 2016-03-25  8:41               ` Zhe Tao
  2016-04-20  7:31                 ` Wu, Jingjing
  2016-03-25  8:42               ` [PATCH 3/3 v7] i40e: Add global reset support for i40e Zhe Tao
                                 ` (3 subsequent siblings)
  5 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-03-25  8:41 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable in the specific version of FW.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |   7 +++
 doc/guides/rel_notes/release_16_04.rst |   2 +
 drivers/net/i40e/i40e_ethdev.c         | 110 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 109 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 4019b41..520ea09 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,10 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
+will use the floating VEB feature for all the VFs created by this PF device.
+
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 9922bcb..1545872 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -248,6 +248,8 @@ This section should contain new features added in this release. Sample format:
 
   New application implementing an IPsec Security Gateway.
 
+* **Added floating VEB support for FVL.**
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 01f1d3d..87801d3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3734,21 +3734,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3760,9 +3766,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3774,11 +3780,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3794,10 +3808,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3830,12 +3844,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+		i40e_veb_release(vsi->floating_veb);
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3849,6 +3873,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4017,7 +4058,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4029,11 +4071,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4041,6 +4090,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4050,7 +4109,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4204,7 +4263,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4312,8 +4375,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 7dc6936..09fb6e2 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH 3/3 v7] i40e: Add global reset support for i40e
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
  2016-03-25  8:41               ` [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
  2016-03-25  8:41               ` [PATCH 2/3 v7] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-03-25  8:42               ` Zhe Tao
  2016-04-20 10:15                 ` Wu, Jingjing
  2016-03-25 15:28               ` [PATCH 0/3 v7] i40e: Add floating VEB " Bruce Richardson
                                 ` (2 subsequent siblings)
  5 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-03-25  8:42 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add global reset support in i40e.
Sometimes the PF reset will fail, and the PF software reset cannot ensure
all the status and components are reset. So added the global reset to fix
this issue.
The essential difference for the new global reset and PF reset is that the
PF Reset doesn't clear the packet buffers, doesn't reset the PE
firmware, and doesn't bother the other PFs on the chip.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 35 ++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 87801d3..8336321 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -437,6 +437,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
+static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags);
+
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
 #include "rte_pci_dev_ids.h"
@@ -836,7 +838,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	ret = i40e_pf_reset(hw);
 	if (ret) {
 		PMD_INIT_LOG(ERR, "Failed to reset pf: %d", ret);
-		return ret;
+		i40e_do_reset(hw, BIT(__I40E_GLOBAL_RESET_REQUESTED));
 	}
 
 	/* Initialize the shared code (base driver) */
@@ -9117,3 +9119,34 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 	/* Flags: 0x3 updates port address */
 	i40e_aq_mac_address_write(hw, 0x3, mac_addr->addr_bytes, NULL);
 }
+
+/**
+ * i40e_do_reset - Start a PF or Core Reset sequence
+ * @pf: board private structure
+ * @reset_flags: which reset is requested
+ *
+ * The essential difference in resets is that the PF Reset
+ * doesn't clear the packet buffers, doesn't reset the PE
+ * firmware, and doesn't bother the other PFs on the chip.
+ **/
+static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags)
+{
+	u32 val;
+
+	/* do the biggest reset indicated */
+	if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) {
+		/* Request a Global Reset
+		 *
+		 * This will start the chip's countdown to the actual full
+		 * chip reset event, and a warning interrupt to be sent
+		 * to all PFs, including the requestor.  Our handler
+		 * for the warning interrupt will deal with the shutdown
+		 * and recovery of the switch setup.
+		 */
+		PMD_INIT_LOG(NOTICE, "GlobalR requested\n");
+		val = rd32(hw, I40E_GLGEN_RTRIG);
+		val |= I40E_GLGEN_RTRIG_GLOBR_MASK;
+		wr32(hw, I40E_GLGEN_RTRIG, val);
+	}
+	/* other reset operations are not supported now */
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 09fb6e2..f2a2fcc 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -108,6 +108,36 @@ enum i40e_flxpld_layer_idx {
 	I40E_FLXPLD_L4_IDX    = 2,
 	I40E_MAX_FLXPLD_LAYER = 3,
 };
+
+/* driver state flags */
+enum i40e_state_t {
+	__I40E_TESTING,
+	__I40E_CONFIG_BUSY,
+	__I40E_CONFIG_DONE,
+	__I40E_DOWN,
+	__I40E_NEEDS_RESTART,
+	__I40E_SERVICE_SCHED,
+	__I40E_ADMINQ_EVENT_PENDING,
+	__I40E_MDD_EVENT_PENDING,
+	__I40E_VFLR_EVENT_PENDING,
+	__I40E_RESET_RECOVERY_PENDING,
+	__I40E_RESET_INTR_RECEIVED,
+	__I40E_REINIT_REQUESTED,
+	__I40E_PF_RESET_REQUESTED,
+	__I40E_CORE_RESET_REQUESTED,
+	__I40E_GLOBAL_RESET_REQUESTED,
+	__I40E_EMP_RESET_REQUESTED,
+	__I40E_EMP_RESET_INTR_RECEIVED,
+	__I40E_FILTER_OVERFLOW_PROMISC,
+	__I40E_SUSPENDED,
+	__I40E_BAD_EEPROM,
+	__I40E_DEBUG_MODE,
+	__I40E_DOWN_REQUESTED,
+	__I40E_FD_FLUSH_REQUESTED,
+	__I40E_RESET_FAILED,
+	__I40E_PORT_TX_SUSPENDED,
+	__I40E_VF_DISABLE,
+};
 #define I40E_MAX_FLXPLD_FIED        3  /* max number of flex payload fields */
 #define I40E_FDIR_BITMASK_NUM_WORD  2  /* max number of bitmask words */
 #define I40E_FDIR_MAX_FLEXWORD_NUM  8  /* max number of flexpayload words */
-- 
2.1.4

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

* Re: [PATCH 0/3 v7] i40e: Add floating VEB support for i40e
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
                                 ` (2 preceding siblings ...)
  2016-03-25  8:42               ` [PATCH 3/3 v7] i40e: Add global reset support for i40e Zhe Tao
@ 2016-03-25 15:28               ` Bruce Richardson
  2016-04-20 14:22               ` Bruce Richardson
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
  5 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-03-25 15:28 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Fri, Mar 25, 2016 at 04:41:57PM +0800, Zhe Tao wrote:
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W.
> 
> Zhe Tao (2):
>   Support floating VEB config
>   Add floating VEB support in i40e
>   Add global reset support for i40e
> 
Thanks for these patches, but at this stage in the development process we are
past the feature-freeze deadline, so these patches need to be deferred until the
16.07 release.

Regards,
/Bruce

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

* Re: [PATCH 1/3 v7] i40e: support floating VEB config
  2016-03-25  8:41               ` [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
@ 2016-03-28  2:23                 ` Xu, Qian Q
  0 siblings, 0 replies; 79+ messages in thread
From: Xu, Qian Q @ 2016-03-28  2:23 UTC (permalink / raw)
  To: Tao, Zhe, dev; +Cc: Tao, Zhe, Wu, Jingjing

Tested-by: Qian Xu <qian.q.xu@intel.com>

- Test Commit: 8f6f24342281f59de0df7bd976a32f714d39b9a9
- OS/Kernel: Fedora 21/4.1.13
- GCC: gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)
- CPU: Intel(R) Xeon(R) CPU E5-2695 v4 @ 2.10
- NIC: Intel(R) Ethernet Controller X710 for 10GbE SFP+
- Total 2 cases, 2 passed, 0 failed. 

Test Case5: Floating VEB Inter-VM VF-VF 
=======================================

Summary: DPDK PF, then create 2VFs and 2VMs, assign one VF to one VM, say VF1 in VM1, VF2 in VM2, and make PF link down(the cable can be pluged out). VFs in VMs are running dpdk testpmd, send traffic to VF1, and set the packet's DEST MAC to VF2, check if VF2 can receive the packets. Check Inter-VM VF-VF MAC switch when PF is link down as well as up.

Details: 

1. Start VM1 with VF1, VM2 with VF2, see the prerequisite part. 
2. In the host, run testpmd with floating parameters and make the link down::

    ./testpmd -c 0x3 -n 4 -w 8c:00.0,enable_floating=1 -- -i
    testpmd> port stop all
    testpmd> show port info all

3. In VM1, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>set mac fwd
    testpmd>set promisc off all
    testpmd>start
   
   In VM2, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0, VF1's MAC
    testpmd>set mac fwd
    testpmd>set promisc off all
    testpmd>start

   
4. Send 100 packets to VF1's MAC address, check if VF2 can get 100 packets. Also check the PF's port stats, and there should be no packets RX/TX at PF port. 

5. In the host, run testpmd with floating parameters and keep the link up, then do step3 and step4, PF should have no RX/TX packets even when link is up::
   
    ./testpmc -c 0xc0000 -n 4 --floating -- -i
    testpmd> port start all
    testpmd> show port info all
    

Test Case6: Floating VEB Inter-VM VF traffic can't be out of NIC
================================================================

DPDK PF, then create 1VF, assign VF1 to VM1, send traffic from VF1 to outside world, then check outside world will not see any traffic.

Details: 

1. Start VM1 with VF1, see the prerequisite part. 
2. In the host, run testpmd with floating parameters.
   
   ./testpmd -c 0x3 -n 4 -w 8c:00.0,enable_floating=1 -- -i
3. In VM1, run testpmd, ::

   ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,pf_mac_addr
   testpmd>set fwd txonly
   testpmd>start
   
  
4. At PF side, check the port stats to see if there is any RX/TX packets, and also check the traffic generator side(e.g: IXIA ports or another port connected to the DUT port) to ensure no packets. 


Thanks
Qian


-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
Sent: Friday, March 25, 2016 4:42 PM
To: dev@dpdk.org
Cc: Tao, Zhe; Wu, Jingjing
Subject: [dpdk-dev] [PATCH 1/3 v7] i40e: support floating VEB config

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD will use the floating VEB feature for all the VFs created by this PF device.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 6fdae57..01f1d3d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -739,6 +739,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs) {
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floating";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)  { @@ -829,6 +867,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 1c75672..7dc6936 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {  #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */ #define 
+FLOATING_FW_MAJ 5 #define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -446,6 +451,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
--
2.1.4

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

* Re: [PATCH 2/3 v7] i40e: Add floating VEB support in i40e
  2016-03-25  8:41               ` [PATCH 2/3 v7] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-04-20  7:31                 ` Wu, Jingjing
  0 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-04-20  7:31 UTC (permalink / raw)
  To: Tao, Zhe, dev

> @@ -3830,12 +3844,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
>  		i40e_veb_release(vsi->veb);
>  	}
> 
> +	if (vsi->floating_veb) {
> +		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
> +			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
> +				return -1;
It will be better to continue but not return error.

> +			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list,
> list);
> +		}
> +		i40e_veb_release(vsi->floating_veb);
> +	}
> +



> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 7dc6936..09fb6e2 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -224,6 +224,7 @@ struct i40e_bw_info {  struct i40e_veb {
>  	struct i40e_vsi_list_head head;
>  	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
> +	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
>  	uint16_t seid; /* The seid of VEB itself */
>  	uint16_t uplink_seid; /* The uplink seid of this VEB */
>  	uint16_t stats_idx;
> @@ -264,6 +265,7 @@ struct i40e_vsi {
>  	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
>  	struct i40e_vsi *parent_vsi;
>  	struct i40e_veb *veb;    /* Associated veb, could be null */
> +	struct i40e_veb *floating_veb; /* Associated floating veb */

For vsi->veb, the VEB associated with uplink vsi, but as I know, floating_veb
Has no uplink vsis. Can I understand the floating_veb in vsi indicates floating veb
Of the device/pf, and only main vsi will have it? If so, why not put in in the pf structure?

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

* Re: [PATCH 3/3 v7] i40e: Add global reset support for i40e
  2016-03-25  8:42               ` [PATCH 3/3 v7] i40e: Add global reset support for i40e Zhe Tao
@ 2016-04-20 10:15                 ` Wu, Jingjing
  0 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-04-20 10:15 UTC (permalink / raw)
  To: Tao, Zhe, dev


Hi, zhe

Beside hein's global reset concern. I have another comment:
Do you copy the following codes from i40e kernel driver? Have
You done the Protext IP scan for it?
Just let you know that linux kernel is GPL liscense, we can
Not just copy code from it without any modification.

Thanks
Jingjing

> +
> +/**
> + * i40e_do_reset - Start a PF or Core Reset sequence
> + * @pf: board private structure
> + * @reset_flags: which reset is requested
> + *
> + * The essential difference in resets is that the PF Reset
> + * doesn't clear the packet buffers, doesn't reset the PE
> + * firmware, and doesn't bother the other PFs on the chip.
> + **/
> +static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags) {
> +	u32 val;
> +
> +	/* do the biggest reset indicated */
> +	if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) {
> +		/* Request a Global Reset
> +		 *
> +		 * This will start the chip's countdown to the actual full
> +		 * chip reset event, and a warning interrupt to be sent
> +		 * to all PFs, including the requestor.  Our handler
> +		 * for the warning interrupt will deal with the shutdown
> +		 * and recovery of the switch setup.
> +		 */
> +		PMD_INIT_LOG(NOTICE, "GlobalR requested\n");
> +		val = rd32(hw, I40E_GLGEN_RTRIG);
> +		val |= I40E_GLGEN_RTRIG_GLOBR_MASK;
> +		wr32(hw, I40E_GLGEN_RTRIG, val);
> +	}
> +	/* other reset operations are not supported now */ }
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 09fb6e2..f2a2fcc 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -108,6 +108,36 @@ enum i40e_flxpld_layer_idx {
>  	I40E_FLXPLD_L4_IDX    = 2,
>  	I40E_MAX_FLXPLD_LAYER = 3,
>  };
> +
> +/* driver state flags */
> +enum i40e_state_t {
> +	__I40E_TESTING,
> +	__I40E_CONFIG_BUSY,
> +	__I40E_CONFIG_DONE,
> +	__I40E_DOWN,
> +	__I40E_NEEDS_RESTART,
> +	__I40E_SERVICE_SCHED,
> +	__I40E_ADMINQ_EVENT_PENDING,
> +	__I40E_MDD_EVENT_PENDING,
> +	__I40E_VFLR_EVENT_PENDING,
> +	__I40E_RESET_RECOVERY_PENDING,
> +	__I40E_RESET_INTR_RECEIVED,
> +	__I40E_REINIT_REQUESTED,
> +	__I40E_PF_RESET_REQUESTED,
> +	__I40E_CORE_RESET_REQUESTED,
> +	__I40E_GLOBAL_RESET_REQUESTED,
> +	__I40E_EMP_RESET_REQUESTED,
> +	__I40E_EMP_RESET_INTR_RECEIVED,
> +	__I40E_FILTER_OVERFLOW_PROMISC,
> +	__I40E_SUSPENDED,
> +	__I40E_BAD_EEPROM,
> +	__I40E_DEBUG_MODE,
> +	__I40E_DOWN_REQUESTED,
> +	__I40E_FD_FLUSH_REQUESTED,
> +	__I40E_RESET_FAILED,
> +	__I40E_PORT_TX_SUSPENDED,
> +	__I40E_VF_DISABLE,
> +};
>  #define I40E_MAX_FLXPLD_FIED        3  /* max number of flex payload fields
> */
>  #define I40E_FDIR_BITMASK_NUM_WORD  2  /* max number of bitmask
> words */  #define I40E_FDIR_MAX_FLEXWORD_NUM  8  /* max number of
> flexpayload words */
> --
> 2.1.4

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

* Re: [PATCH 0/3 v7] i40e: Add floating VEB support for i40e
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
                                 ` (3 preceding siblings ...)
  2016-03-25 15:28               ` [PATCH 0/3 v7] i40e: Add floating VEB " Bruce Richardson
@ 2016-04-20 14:22               ` Bruce Richardson
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
  5 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-04-20 14:22 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Fri, Mar 25, 2016 at 04:41:57PM +0800, Zhe Tao wrote:
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W.
> 
> Zhe Tao (2):
>   Support floating VEB config
>   Add floating VEB support in i40e
>   Add global reset support for i40e
> 
>  doc/guides/nics/i40e.rst               |   7 ++
>  doc/guides/rel_notes/release_16_04.rst |   2 +
>  drivers/net/i40e/i40e_ethdev.c         | 189 +++++++++++++++++++++++++++++----
>  drivers/net/i40e/i40e_ethdev.h         |  38 +++++++
>  drivers/net/i40e/i40e_pf.c             |  11 +-
>  5 files changed, 223 insertions(+), 24 deletions(-)
> 
> V2: Added the release notes and changed commit log. 
> V3: Changed the VSI release operation. 
> V4: Added the FW version check otherwise it will cause the segment fault.
> V5: Edited the code for new share code APIs
> V6: Changed the floating VEB configuration method 
> V7: Added global reset for i40e 

BTW: When doing additional revisions of the patch, feel free to use the "-v N" 
parameter to "git format-patch", which will create the PATCH titles in the 
correct form for you. It's normal to have the v7,v8 etc. appear before the patch
number in the series, not after as in your series.

Regards,
/Bruce

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

* [PATCH v8 0/3] i40e: Add floating VEB support for i40e
  2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
                                 ` (4 preceding siblings ...)
  2016-04-20 14:22               ` Bruce Richardson
@ 2016-05-24 17:28               ` Zhe Tao
  2016-05-24 17:28                 ` [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
                                   ` (5 more replies)
  5 siblings, 6 replies; 79+ messages in thread
From: Zhe Tao @ 2016-05-24 17:28 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W.

Zhe Tao (3):
  Support floating VEB config
  Add floating VEB support in i40e
  Add floating VEB extention support for i40e

 doc/guides/nics/i40e.rst               |  10 ++
 doc/guides/rel_notes/release_16_07.rst |   6 +
 drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h         |   9 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 219 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V7: removed global reset and added floating VEB extension support 

-- 
2.1.4

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

* [PATCH v8 1/3] i40e: support floating VEB config
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
@ 2016-05-24 17:28                 ` Zhe Tao
  2016-06-09 15:50                   ` Bruce Richardson
  2016-05-24 17:28                 ` [PATCH v8 2/3] i40e: Add floating VEB support in i40e Zhe Tao
                                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-05-24 17:28 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..e558c63 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floating";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -843,6 +881,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..8297c5f 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -450,6 +455,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v8 2/3] i40e: Add floating VEB support in i40e
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
  2016-05-24 17:28                 ` [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
@ 2016-05-24 17:28                 ` Zhe Tao
  2016-06-09 15:55                   ` Bruce Richardson
  2016-05-24 17:28                 ` [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
                                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-05-24 17:28 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable in the specific version of FW.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |   7 +++
 doc/guides/rel_notes/release_16_07.rst |   6 ++
 drivers/net/i40e/i40e_ethdev.c         | 109 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 112 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..49a0598 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,10 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
+will use the floating VEB feature for all the VFs created by this PF device.
+
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..8485b08 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,12 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  Now VFs for i40e can connect to the floating VEB.
+  With this feature, VFs can communicate with each other, but cannot access
+  outside network. When PF is down, and VFs can still forward pkts between each
+  other.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index e558c63..8859936 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3762,21 +3762,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3788,9 +3794,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3802,11 +3808,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3822,10 +3836,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3858,12 +3872,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3877,6 +3900,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4045,7 +4085,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4057,11 +4098,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4069,6 +4117,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4078,7 +4136,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4232,7 +4290,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4340,8 +4402,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 8297c5f..deef0ce 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v8 3/3] i40e: add floating VEB extension support
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
  2016-05-24 17:28                 ` [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
  2016-05-24 17:28                 ` [PATCH v8 2/3] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-05-24 17:28                 ` Zhe Tao
  2016-05-30 15:49                   ` Peng, Yuan
  2016-06-09 15:57                   ` Bruce Richardson
  2016-05-24 19:22                 ` [PATCH v8 0/3] i40e: Add floating VEB support for i40e Stephen Hemminger
                                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 79+ messages in thread
From: Zhe Tao @ 2016-05-24 17:28 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Also you can specifiy which VF need to connect to this floating veb using
"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the VF0 connect
to the floating VEB, VF1 connect to the legacy VEB.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst       |  5 +++-
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.h |  1 +
 drivers/net/i40e/i40e_pf.c     |  3 ++-
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 49a0598..0919a96 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -372,4 +372,7 @@ FVL can support floating VEB feature.
 To enable this feature, the user should pass a devargs parameter to the EAL
 like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
 will use the floating VEB feature for all the VFs created by this PF device.
-
+Also you can specify which VF need to connect to this floating veb using
+"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
+Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the VF0 connect
+to the floating VEB, VF1 connect to the legacy VEB.
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8859936..39da1e0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,52 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_fbitmap_handler(__rte_unused const char *key,
+				      const char *value,
+				      void *opaque)
+{
+	errno = 0;
+	*(uint16_t *)opaque = strtoul(value, NULL, 0);
+	if (errno)
+		return -1;
+	return 0;
+}
+
+static uint16_t i40e_check_fbitmap(struct rte_devargs *devargs,
+				   uint16_t floating)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_bitmap = "floating_bitmap";
+	/* default value for vf floating bitmap is -1 */
+	uint16_t vf_fbitmap = (uint16_t)-1;
+	uint16_t new_vf_fbitmap;
+
+	if (floating == false)
+		return 0;
+
+	if (devargs == NULL)
+		return vf_fbitmap;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return vf_fbitmap;
+
+	if (!rte_kvargs_count(kvlist, floating_bitmap)) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_bitmap,
+			       i40e_check_fbitmap_handler,
+			       &new_vf_fbitmap) < 0) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	rte_kvargs_free(kvlist);
+
+	return new_vf_fbitmap;
+}
+
 static int i40e_check_floating_handler(__rte_unused const char *key,
 				       const char *value,
 				       __rte_unused void *opaque)
@@ -884,8 +930,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	/* Need the special FW version support floating VEB */
 	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
 		pf->floating = i40e_check_floating(pci_dev->devargs);
+		pf->vf_fbitmap = i40e_check_fbitmap(pci_dev->devargs,
+						    pf->floating);
 	} else {
 		pf->floating = false;
+		pf->vf_fbitmap = 0;
 	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
@@ -3855,6 +3904,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3886,7 +3936,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
-	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !(pf->vf_fbitmap && 1 << user_param))) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3901,7 +3952,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
 
-	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    (pf->vf_fbitmap && 1 << user_param)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL ||
 		    vsi->parent_vsi->floating_veb == NULL) {
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index deef0ce..39c3664 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -458,6 +458,7 @@ struct i40e_pf {
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
 	uint16_t floating; /* The flag to use the floating VEB */
+	uint16_t vf_fbitmap; /* The floating enable flag for the specific VF */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 9adfad2..312e1f8 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -224,7 +224,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
-	if (pf->floating == true) {
+	if (pf->floating == true &&
+	    (pf->vf_fbitmap & 1 << vf_id)) {
 		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
 			NULL, vf->vf_idx);
 	} else {
-- 
2.1.4

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

* Re: [PATCH v8 0/3] i40e: Add floating VEB support for i40e
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
                                   ` (2 preceding siblings ...)
  2016-05-24 17:28                 ` [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
@ 2016-05-24 19:22                 ` Stephen Hemminger
  2016-05-25 10:05                   ` Thomas Monjalon
  2016-05-31  2:25                 ` Wu, Jingjing
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
  5 siblings, 1 reply; 79+ messages in thread
From: Stephen Hemminger @ 2016-05-24 19:22 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Wed, 25 May 2016 01:28:03 +0800
Zhe Tao <zhe.tao@intel.com> wrote:

> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W.
> 
> Zhe Tao (3):
>   Support floating VEB config
>   Add floating VEB support in i40e
>   Add floating VEB extention support for i40e
> 
>  doc/guides/nics/i40e.rst               |  10 ++
>  doc/guides/rel_notes/release_16_07.rst |   6 +
>  drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
>  drivers/net/i40e/i40e_ethdev.h         |   9 ++
>  drivers/net/i40e/i40e_pf.c             |  12 +-
>  5 files changed, 219 insertions(+), 23 deletions(-)
> 
> V2: Added the release notes and changed commit log. 
> V3: Changed the VSI release operation. 
> V4: Added the FW version check otherwise it will cause the segment fault.
> V5: Edited the code for new share code APIs
> V6: Changed the floating VEB configuration method 
> V7: Added global reset for i40e 
> V7: removed global reset and added floating VEB extension support 
> 

kvargs are a very awkward API to use in a portable application.
Good for Intel testing NIC's bad for DPDK users.

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

* Re: [PATCH v8 0/3] i40e: Add floating VEB support for i40e
  2016-05-24 19:22                 ` [PATCH v8 0/3] i40e: Add floating VEB support for i40e Stephen Hemminger
@ 2016-05-25 10:05                   ` Thomas Monjalon
  0 siblings, 0 replies; 79+ messages in thread
From: Thomas Monjalon @ 2016-05-25 10:05 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, Zhe Tao, jingjing.wu

2016-05-24 12:22, Stephen Hemminger:
> kvargs are a very awkward API to use in a portable application.
> Good for Intel testing NIC's bad for DPDK users.

Yes. The alternative would be to have some driver-specific API.
We can live with devargs until driver API is introduced.

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

* Re: [PATCH v8 3/3] i40e: add floating VEB extension support
  2016-05-24 17:28                 ` [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
@ 2016-05-30 15:49                   ` Peng, Yuan
  2016-06-09 15:57                   ` Bruce Richardson
  1 sibling, 0 replies; 79+ messages in thread
From: Peng, Yuan @ 2016-05-30 15:49 UTC (permalink / raw)
  To: Tao, Zhe, dev; +Cc: Tao, Zhe, Wu, Jingjing

[-- Attachment #1: Type: text/plain, Size: 9222 bytes --]

Tested-by: Peng Yuan <yuan.peng@intel.com>

- Test Commit: f3625976474a595bfbdb44ad1c881b07d722a226
			15ef663c2acb7ed576083f97cd2555fc9900c724
			d0e57ebaf63fe240391dfafebd28f8e6559da899
- OS/Kernel: Fedora 23/4.2.3
- GCC: gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
- CPU: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz
- NIC: Fortville 2*40G
- Total 6 cases,6 passed, 0 failed.

There are three patch about the floating VEB feature, I put all of them, and just send one test-by.
Here I listed the test case summary,  you can get the detail steps from attachment.
I run test cases according to my test plan, all the test cases passed.


Test Case1: Floating VEB Inter-VM VF-VF  
=======================================================
Summary: DPDK PF, then create 2VFs and 2VMs, assign one VF to one VM, say VF1 in VM1, VF2 in VM2, and make PF link down(the cable can be pluged out). VFs in VMs are running dpdk testpmd, VF1 send traffic, and set the packet's DEST MAC to VF2, check VF2 can receive the packets. Check Inter-VM VF-VF MAC switch when PF is link down as well as up.

Test Case2: Floating VEB PF can't get traffic from VF    
================================================================
DPDK PF, then create 1VF, assign VF1 to VM1, send traffic from VF1 to PF, then check PF will not see any traffic.


Test Case3: Floating VEB VF can't receive traffic from outside world   
======================================================
DPDK PF, then create 1VF, assign VF1 to VM1, send traffic from tester to VF1, in floating mode, check VF1 can't receive traffic from tester.

Test Case4: Floating VEB VF can not communicate with legacy VEB VF inter-VM
======================================================
Summary: DPDK PF, then create 3VFs and 3VMs, assign one VF to one VM, say VF1 in VM1, VF3 in VM3, floating VEB; VF2 in VM2, lagecy VEB. Make PF link down(port stop all), VFs in VMs are running dpdk testpmd.
1. VF1 send traffic, and set the packet's DEST MAC to VF2, check VF2 can not receive the packets. 
2. VF1 send traffic, and set the packet's DEST MAC to VF3, check VF3 can receive the packets. 
3. VF2 send traffic, and set the packet's DEST MAC to VF1, check VF1 can not receive the packets. 
Check Inter-VM VF-VF MAC switch when PF is link down as well as up.

Test Case5: PF can't get traffic from Floating VEB VF, but PF can get traffic from legacy VEB VF.
================================================================
DPDK PF, then create 2VF, assign VF1 to VM1, VF2 to VM2, set VF1 in floating VEB, VF2 in legacy VEB.
1. Send traffic from VF1 to PF, then check PF will not see any traffic; 
2. Send traffic from VF2 to PF, then check PF will receive all the packets.


Test Case6: Floating VEB VF can't receive traffic from outside world, while legacy VEB VF can receive traffic from outside world.
======================================================
DPDK PF, then create 2VF, assign VF1 to VM1, assign VF2 to VM2, set VF1 in floating VEB, set VF2 in legacy VEB
1. send traffic from tester to VF1, check VF1 can't receive traffic from tester.
2. send traffic from tester to VF2, check VF2 can receive all the traffic from tester.


Thanks!
Yuan.

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
Sent: Wednesday, May 25, 2016 1:28 AM
To: dev@dpdk.org
Cc: Tao, Zhe <zhe.tao@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
Subject: [dpdk-dev] [PATCH v8 3/3] i40e: add floating VEB extension support

To enable this feature, the user should pass a devargs parameter to the EAL like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD will use the floating VEB feature for all the VFs created by this PF device.

Also you can specifiy which VF need to connect to this floating veb using "floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the VF0 connect to the floating VEB, VF1 connect to the legacy VEB.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst       |  5 +++-
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.h |  1 +
 drivers/net/i40e/i40e_pf.c     |  3 ++-
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst index 49a0598..0919a96 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -372,4 +372,7 @@ FVL can support floating VEB feature.
 To enable this feature, the user should pass a devargs parameter to the EAL  like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD  will use the floating VEB feature for all the VFs created by this PF device.
-
+Also you can specify which VF need to connect to this floating veb 
+using "floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
+Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the 
+VF0 connect to the floating VEB, VF1 connect to the legacy VEB.
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 8859936..39da1e0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,52 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_fbitmap_handler(__rte_unused const char *key,
+				      const char *value,
+				      void *opaque)
+{
+	errno = 0;
+	*(uint16_t *)opaque = strtoul(value, NULL, 0);
+	if (errno)
+		return -1;
+	return 0;
+}
+
+static uint16_t i40e_check_fbitmap(struct rte_devargs *devargs,
+				   uint16_t floating)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_bitmap = "floating_bitmap";
+	/* default value for vf floating bitmap is -1 */
+	uint16_t vf_fbitmap = (uint16_t)-1;
+	uint16_t new_vf_fbitmap;
+
+	if (floating == false)
+		return 0;
+
+	if (devargs == NULL)
+		return vf_fbitmap;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return vf_fbitmap;
+
+	if (!rte_kvargs_count(kvlist, floating_bitmap)) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	/* Floating is enabled when there's key-value pair: enable_floating=1 */
+	if (rte_kvargs_process(kvlist, floating_bitmap,
+			       i40e_check_fbitmap_handler,
+			       &new_vf_fbitmap) < 0) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	rte_kvargs_free(kvlist);
+
+	return new_vf_fbitmap;
+}
+
 static int i40e_check_floating_handler(__rte_unused const char *key,
 				       const char *value,
 				       __rte_unused void *opaque)
@@ -884,8 +930,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	/* Need the special FW version support floating VEB */
 	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
 		pf->floating = i40e_check_floating(pci_dev->devargs);
+		pf->vf_fbitmap = i40e_check_fbitmap(pci_dev->devargs,
+						    pf->floating);
 	} else {
 		pf->floating = false;
+		pf->vf_fbitmap = 0;
 	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
@@ -3855,6 +3904,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3886,7 +3936,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
-	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !(pf->vf_fbitmap && 1 << user_param))) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL"); @@ -3901,7 +3952,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
 
-	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    (pf->vf_fbitmap && 1 << user_param)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL ||
 		    vsi->parent_vsi->floating_veb == NULL) { diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index deef0ce..39c3664 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -458,6 +458,7 @@ struct i40e_pf {
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
 	uint16_t floating; /* The flag to use the floating VEB */
+	uint16_t vf_fbitmap; /* The floating enable flag for the specific VF 
+*/
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c index 9adfad2..312e1f8 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -224,7 +224,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
-	if (pf->floating == true) {
+	if (pf->floating == true &&
+	    (pf->vf_fbitmap & 1 << vf_id)) {
 		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
 			NULL, vf->vf_idx);
 	} else {
--
2.1.4


[-- Attachment #2: floating-VEB-testplan - attach.txt --]
[-- Type: text/plain, Size: 12119 bytes --]

Prerequisites for floating VEB testing
 =============================

1. Get the pci device id of DUT, for example::

./dpdk_nic_bind.py --st

0000:82:00.0 'Ethernet Controller X710 for 10GbE SFP+' if=enp130s0f0 drv=i40e unused=

2. Host PF in DPDK driver. Create 2VFs from 1 PF with dpdk driver. 

./dpdk_nic_bind.py -b igb_uio 82:00.0 
 echo 2 >/sys/bus/pci/devices/0000\:82\:00.0/max_vfs
 ./dpdk_nic_bind.py --st
 0000:82:02.0 'XL710/X710 Virtual Function' unused=i40evf,igb_uio
 0000:82:02.1 'XL710/X710 Virtual Function' unused=i40evf,igb_uio

3. Detach VFs from the host, bind them to pci-stub driver::

modprobe pci-stub

using `lspci -nn|grep -i ethernet` got VF device id, for example "8086 154c",

echo "8086 154c" > /sys/bus/pci/drivers/pci-stub/new_id
 echo "0000:82:02.0" > /sys/bus/pci/drivers/i40evf/unbind
 echo "0000:82:02.0" > /sys/bus/pci/drivers/pci-stub/bind

echo "8086 154c" > /sys/bus/pci/drivers/pci-stub/new_id
 echo "0000:82:02.1" > /sys/bus/pci/drivers/i40evf/unbind
 echo "0000:82:02.1" > /sys/bus/pci/drivers/pci-stub/bind

4. Lauch the VM with the VF PCI passthrough. 

taskset -c 18-19 qemu-system-x86_64 \
 -enable-kvm -m 2048 -smp cores=2,sockets=1 -cpu host -name dpdk1-vm0 \
 -device pci-assign,host=0000:82:02.0 \
 -drive file=/home/image/vm0.img \
 -netdev tap,id=ipvm0,ifname=tap1,script=/etc/qemu-ifup -device rtl8139,netdev=ipvm0,id=net1,mac=00:00:00:00:00:01 \
 -localtime -vnc :1 -daemonize

taskset -c 18-19 qemu-system-x86_64 \
 -enable-kvm -m 2048 -smp cores=2,sockets=1 -cpu host -name dpdk1-vm1 \
 -device pci-assign,host=0000:82:02.1 \
 -drive file=/home/image/vm1.img \
 -netdev tap,id=ipvm1,ifname=tap2,script=/etc/qemu-ifup -device rtl8139,netdev=ipvm1,id=net2,mac=00:00:00:00:00:02 \
 -localtime -vnc :2 -daemonize


Test Case1: Floating VEB Inter-VM VF-VF  
=======================================================

Summary: DPDK PF, then create 2VFs and 2VMs, assign one VF to one VM, say VF1 in VM1, VF2 in VM2, and make PF link down(the cable can be pluged out). VFs in VMs are running dpdk testpmd, VF1 send traffic, and set the packet's DEST MAC to VF2, check if VF2 can receive the packets. Check Inter-VM VF-VF MAC switch when PF is link down as well as up.

Launch PF testpmd: ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1 -- -i

1. Start VM1 with VF1, VM2 with VF2, see the prerequisite part. put the patch in the VM's dpdk

1.1  Reserve huge pages memory on host and VM(before using DPDK):

     echo 4096 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages 
     mkdir /mnt/huge   
     mount -t hugetlbfs nodev /mnt/huge  

1.2  VF bind to dpdk driver

     cd /root/dpdk/tools
     ./dpdk_nic_bind --st
     ./dpdk_nic_bind -b igb_uio ethernet   
   
2. In the host, run testpmd with floating parameters and make the link down::

     ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1 -- -i
    testpmd> port stop all
    testpmd> show port info all

3. In VM1, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>set fwd rxonly
    testpmd>show port info all     //get the vf1_mac_address
    testpmd>start
    testpmd>show port stats all
   
   In VM2, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,vf1_mac_address
    testpmd>set fwd txonly
    testpmd>start
    testpmd>show port stats all

4. check if VF1 can get all the packets. Check the packet content is no corrupted. 

5. Set "testpmd> port start all" and "testpmd> start" in step2, then run the step3-4 again. same result.


Test Case2: Floating VEB PF can't get traffic from VF    
================================================================

DPDK PF, then create 1VF, assign VF1 to VM1, send traffic from VF1 to PF, then check PF will not see any traffic. 

1. Start VM1 with VF1, see the prerequisite part.

2. In host, launch testpmd::

   ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1 -- -i
   testpmd> set fwd rxonly
   testpmd> port start all
   testpmd> start
   testpmd> show port stats all

3. In VM1, run testpmd::

   ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,pf_mac_addr
   testpmd>set fwd txonly
   testpmd>start
   testpmd>show port stats all

4. Check if PF can not get any packets, so VF1->PF is not working. 

5. Set "testpmd> port stop all" in step2, then run the test case again. Same result.



Test Case3: Floating VEB VF can't receive traffic from outside world   
======================================================

DPDK PF, then create 1VF, assign VF1 to VM1, send traffic from tester to VF1, in floating mode, check VF1 can't receive traffic from tester.

1. Start VM1 with VF1, see the prerequisite part.

2. In host, launch testpmd::

   ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1 -- -i 
   testpmd> set fwd mac
   testpmd> port start all
   testpmd> start
   testpmd> show port stats all
   

   In VM1, run testpmd:

   ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>show port info all    //get VF_mac_address
    testpmd>set fwd rxonly
    testpmd>start
    testpmd>show port stats all

   In tester, run scapy

   packet=Ether(dst="VF_mac_address")/IP()/UDP()/Raw('x'*20)
   sendp(packet,iface="enp132s0f0")
   

3. Check if VF1 can not get any packets, so tester->VF1 is not working. 
4. Set "testpmd> port stop all" in step2 in Host, then run the test case again. same result.


Test Case4: Floating VEB VF can not communicate with legacy VEB VF inter-VM
======================================================

Summary: DPDK PF, then create 3VFs and 3VMs, assign one VF to one VM, say VF1 in VM1, VF3 in VM3, floating VEB; VF2 in VM2, lagecy VEB. Make PF link down(port stop all), VFs in VMs are running dpdk testpmd.
1. VF1 send traffic, and set the packet's DEST MAC to VF2, check VF2 can not receive the packets. 
2. VF1 send traffic, and set the packet's DEST MAC to VF3, check VF3 can receive the packets. 
3. VF2 send traffic, and set the packet's DEST MAC to VF1, check VF1 can not receive the packets. 
Check Inter-VM VF-VF MAC switch when PF is link down as well as up.

Launch PF testpmd: ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1,floating_bitmap=0x5 -- -i

1. Start VM1 with VF1, VM2 with VF2, VM3 with VF3, see the prerequisite part.

2. In the host, run testpmd with floating parameters and make the link down::

    ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1,floating_bitmap=0x5 -- -i     //VF1 and VF3 in floating VEB, VF2 in legacy VEB
    testpmd> port stop all
    testpmd> show port info all

3. VF1 send traffic, and set the packet's DEST MAC to VF2, check VF2 can not receive the packets.

    In VM2, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>set fwd rxonly
    testpmd>show port info all     //get the vf2_mac_address
    testpmd>start
    testpmd>show port stats all
   
    In VM1, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,vf2_mac_address
    testpmd>set fwd txonly
    testpmd>start
    testpmd>show port stats all

    Check VF2 can not get any packets, so VF1->VF2 is not working.

4. VF1 send traffic, and set the packet's DEST MAC to VF3, check VF3 can receive the packets.

    In VM3, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>set fwd rxonly
    testpmd>show port info all     //get the vf3_mac_address
    testpmd>start
    testpmd>show port stats all

    In VM1, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,vf3_mac_address
    testpmd>set fwd txonly
    testpmd>start
    testpmd>show port stats all

    Check VF3 can get all the packets. Check the packet content is no corrupted., so VF1->VF2 is working.

5. VF2 send traffic, and set the packet's DEST MAC to VF1, check VF1 can not receive the packets. 

    In VM1, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>set fwd rxonly
    testpmd>show port info all     //get the vf1_mac_address
    testpmd>start
    testpmd>show port stats all

    In VM2, run testpmd::

    ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,vf1_mac_address
    testpmd>set fwd txonly
    testpmd>start
    testpmd>show port stats all

    Check VF1 can not get any packets, so VF2->VF1 is not working.

6. Set "testpmd> port start all" and "testpmd> start" in step2, then run the step3-5 again. same result.


Test Case5: PF can't get traffic from Floating VEB VF, but PF can get traffic from legacy VEB VF.
================================================================

DPDK PF, then create 2VF, assign VF1 to VM1, VF2 to VM2, set VF1 in floating VEB, VF2 in legacy VEB. 
1. Send traffic from VF1 to PF, then check PF will not see any traffic; 
2. Send traffic from VF2 to PF, then check PF will receive all the packets.

Note:The direction can't be reversed. because you must run testpmd in PF first, then you can run testpmd in vf. so when you run testpmd in pf, you don't know the vf's mac_address, you can't set the --eth-peer. if there is not "-eth-peer", vf can't receive the the packet sent by "txonly". even if there is not floatingVEB, vf still can't receive the packet sent by "txonly" without the "-eth-peer".

1. Start VM1 with VF1, VM2 with VF2, see the prerequisite part.

2. In host, launch testpmd::

   ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1,floating_bitmap=0x1 -- -i   //VF1 in floating VEB, VF2 in legacy VEB
   testpmd> set fwd rxonly
   testpmd> port start all
   testpmd> start
   testpmd> show port stats all

3. In VM1, run testpmd:

   ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,pf_mac_addr
   testpmd>set fwd txonly
   testpmd>start
   testpmd>show port stats all

   Check PF can not get any packets, so VF1->PF is not working. (I have verified that if it's not floating VEB, PF can get packets, there is some RX-missed)

4. In VM2, run testpmd:

   ./testpmd -c 0x3 -n 4 -- -i --eth-peer=0,pf_mac_addr
   testpmd>set fwd txonly
   testpmd>start
   testpmd>show port stats all

   Check PF can get all the packets, so VF2->PF is working.

5. Set "testpmd> port stop all" in step2 in Host, then run the test case again. same result.


Test Case6: Floating VEB VF can't receive traffic from outside world, while legacy VEB VF can receive traffic from outside world.
======================================================

DPDK PF, then create 2VF, assign VF1 to VM1, assign VF2 to VM2, set VF1 in floating VEB, set VF2 in legacy VEB
1. send traffic from tester to VF1, check VF1 can't receive traffic from tester.
2. send traffic from tester to VF2, check VF2 can receive all the traffic from tester.

1. Start VM1 with VF1, VM2 with VF2, see the prerequisite part.

2. In host, launch testpmd::

   ./testpmd -c 0x3 -n 4 -w 82:00.0,enable_floating=1,floating_bitmap=0x1 -- -i   //VF1 in floating VEB, VF2 in legacy VEB 
   testpmd> set fwd mac
   testpmd> port start all
   testpmd> start
   testpmd> show port stats all
   

3. In VM1, run testpmd:

   ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>show port info all    //get VF1_mac_address
    testpmd>set fwd rxonly
    testpmd>start
    testpmd>show port stats all

   In tester, run scapy

   packet=Ether(dst="VF1_mac_address")/IP()/UDP()/Raw('x'*20)
   sendp(packet,iface="enp132s0f0")
   
   Check VF1 can not get any packets, so tester->VF1 is not working. PF can receive packets and forwording it.

4. In VM2, run testpmd:

   ./testpmd -c 0x3 -n 4 -- -i 
    testpmd>show port info all    //get VF2_mac_address
    testpmd>set fwd rxonly
    testpmd>start
    testpmd>show port stats all

   In tester, run scapy

   packet=Ether(dst="VF2_mac_address")/IP()/UDP()/Raw('x'*20)
   sendp(packet,iface="enp132s0f0")
   
   Check VF1 can get all the packets, so tester->VF2 is working.

5. Set "testpmd> port stop all" in step2 in Host, then run the test case again. VF1 and VF2 cannot receive any packets. (because PF link down, and PF can't receive any packets. so even if VF2 can't receive any packets.)




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

* Re: [PATCH v8 0/3] i40e: Add floating VEB support for i40e
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
                                   ` (3 preceding siblings ...)
  2016-05-24 19:22                 ` [PATCH v8 0/3] i40e: Add floating VEB support for i40e Stephen Hemminger
@ 2016-05-31  2:25                 ` Wu, Jingjing
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
  5 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-05-31  2:25 UTC (permalink / raw)
  To: Tao, Zhe, dev



> -----Original Message-----
> From: Tao, Zhe
> Sent: Wednesday, May 25, 2016 1:28 AM
> To: dev@dpdk.org
> Cc: Tao, Zhe <zhe.tao@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v8 0/3] i40e: Add floating VEB support for i40e
> 
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W.
> 

Acked-by: Jingjing Wu <jingjing.wu@intel.com>

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

* Re: [PATCH v8 1/3] i40e: support floating VEB config
  2016-05-24 17:28                 ` [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
@ 2016-06-09 15:50                   ` Bruce Richardson
  0 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-09 15:50 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Wed, May 25, 2016 at 01:28:04AM +0800, Zhe Tao wrote:
> Add the new floating related argument option in the devarg.
> Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
> or floating VEB.
> To enable this feature, the user should pass a devargs parameter to the EAL
> like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
> will use the floating VEB feature for all the VFs created by this PF device.
> 
> Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/i40e/i40e_ethdev.h |  6 ++++++
>  2 files changed, 50 insertions(+)

I don't think we should ever use the word "floating" in this context without the
word "VEB" on it as well, because it's really meaningless - being an adjective,
it always requires a noun will it. This applies both to cmdline arguments and to
commit messages.

Secondly, these patches really could do with an explanation of what a floating
VEB is and what it can do vs a non-floating VEB. I know that in the second patch
you refer to standards which define VEBs, but:
a) why is that reference not in patch 1?
b) when I tried looking it up the spec requires a login for the IEEE site, and
a google search for "floating VEB" only brings up links to these patches in
patchwork.

Regards,
/Bruce

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

* Re: [PATCH v8 2/3] i40e: Add floating VEB support in i40e
  2016-05-24 17:28                 ` [PATCH v8 2/3] i40e: Add floating VEB support in i40e Zhe Tao
@ 2016-06-09 15:55                   ` Bruce Richardson
  0 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-09 15:55 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Wed, May 25, 2016 at 01:28:05AM +0800, Zhe Tao wrote:
> This patch add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
copy reference to patch 1.

> 
> Now the floating VEB feature is only avaiable in the specific version of FW.
Please list the firmware versions rather than making the reader read through
the patch.

> 
> Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> ---
>  doc/guides/nics/i40e.rst               |   7 +++
>  doc/guides/rel_notes/release_16_07.rst |   6 ++
>  drivers/net/i40e/i40e_ethdev.c         | 109 ++++++++++++++++++++++++++-------
>  drivers/net/i40e/i40e_ethdev.h         |   2 +
>  drivers/net/i40e/i40e_pf.c             |  11 +++-
>  5 files changed, 112 insertions(+), 23 deletions(-)
> 
> diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
> index 934eb02..49a0598 100644
> --- a/doc/guides/nics/i40e.rst
> +++ b/doc/guides/nics/i40e.rst
> @@ -366,3 +366,10 @@ Delete all flow director rules on a port:
>  
>     testpmd> flush_flow_director 0
>  
> +Floating VEB
> +~~~~~~~~~~~~~
> +FVL can support floating VEB feature.
> +To enable this feature, the user should pass a devargs parameter to the EAL
> +like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
> +will use the floating VEB feature for all the VFs created by this PF device.
> +

I think this documentation part really need to be expanded to explain what a
floating VEB is and why you'd use it. If this is well documented elsewhere, e.g.
in the relevant datasheets for NICs using the i40e driver, by all means refer to
that, but keep a summarised account of what it is here in the DPDK docs. Perhaps
you can reuse the description from the release note below, just with an extra
sentence or two about why the PF being down makes a difference, etc.

> diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
> index 30e78d4..8485b08 100644
> --- a/doc/guides/rel_notes/release_16_07.rst
> +++ b/doc/guides/rel_notes/release_16_07.rst
> @@ -47,6 +47,12 @@ New Features
>    * Dropped specific Xen Dom0 code.
>    * Dropped specific anonymous mempool code in testpmd.
>  
> +* **Added floating VEB support for i40e PF driver.**
> +
> +  Now VFs for i40e can connect to the floating VEB.
> +  With this feature, VFs can communicate with each other, but cannot access
> +  outside network. When PF is down, and VFs can still forward pkts between each
> +  other.

This expanation belongs more in the i40e.rst document above. I think the release
notes only needs a mention that the feature was added and then a link to the
fuller description in the i40e doc.

Regards,
/Bruce

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

* Re: [PATCH v8 3/3] i40e: add floating VEB extension support
  2016-05-24 17:28                 ` [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
  2016-05-30 15:49                   ` Peng, Yuan
@ 2016-06-09 15:57                   ` Bruce Richardson
  1 sibling, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-09 15:57 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Wed, May 25, 2016 at 01:28:06AM +0800, Zhe Tao wrote:
> To enable this feature, the user should pass a devargs parameter to the EAL
> like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
> will use the floating VEB feature for all the VFs created by this PF device.
> 
> Also you can specifiy which VF need to connect to this floating veb using
> "floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
> Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the VF0 connect
> to the floating VEB, VF1 connect to the legacy VEB.

Is there only ever one floating VEB inside a PF? That perhaps needs to be called
out in the explanation of what the floating VEB is?

/Bruce

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

* [PATCH v9 0/3] i40e: add floating VEB support for i40e
  2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
                                   ` (4 preceding siblings ...)
  2016-05-31  2:25                 ` Wu, Jingjing
@ 2016-06-13  6:45                 ` Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 1/3] i40e: support floating VEB config Zhe Tao
                                     ` (3 more replies)
  5 siblings, 4 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  6:45 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (3):
  Support floating VEB config
  Add floating VEB support in i40e
  Add floating VEB extention support for i40e

 doc/guides/nics/i40e.rst               |  25 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h         |   9 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 232 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 

-- 
2.1.4

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

* [PATCH v9 1/3] i40e: support floating VEB config
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
@ 2016-06-13  6:45                   ` Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 2/3] i40e: add floating VEB support in i40e Zhe Tao
                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  6:45 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

But for floating VEB, it has two major difference.
1. doesn't has a up link connection which means
the traffic cannot go to ouside world.
2. doesn't need to connect to the phsical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..8c4ae1c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floatingVEB";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -843,6 +881,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..8297c5f 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -450,6 +455,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v9 2/3] i40e: add floating VEB support in i40e
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 1/3] i40e: support floating VEB config Zhe Tao
@ 2016-06-13  6:45                   ` Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 3/3] i40e: add floating VEB extension support Zhe Tao
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
  3 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  6:45 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable for the FW version which
newer than 5.0 (FW major version number > 5).

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  17 +++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 109 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 120 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..aae78ca 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,20 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
+PMD will use the floating VEB feature for all the VFs created by this PF device.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..686b683 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst. 
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8c4ae1c..025d498 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3762,21 +3762,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3788,9 +3794,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3802,11 +3808,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3822,10 +3836,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3858,12 +3872,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3877,6 +3900,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4045,7 +4085,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4057,11 +4098,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4069,6 +4117,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4078,7 +4136,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4232,7 +4290,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4340,8 +4402,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 8297c5f..deef0ce 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v9 3/3] i40e: add floating VEB extension support
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 1/3] i40e: support floating VEB config Zhe Tao
  2016-06-13  6:45                   ` [PATCH v9 2/3] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-13  6:45                   ` Zhe Tao
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
  3 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  6:45 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floating=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Also you can specifiy which VF need to connect to this floating veb using
"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
Like "-w 84:00.0,enable_floating=1,floating_bitmap=1", means only the VF0 connect
to the floating VEB, VF1 connect to the legacy VEB.

The current implementation only support one floating VEB and one legacy
VEB. VF can connect to floating VEB or legacy VEB according to the
configuration.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst       |  8 ++++++
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.h |  1 +
 drivers/net/i40e/i40e_pf.c     |  3 ++-
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index aae78ca..d3196ad 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -372,6 +372,14 @@ FVL can support floating VEB feature.
 To enable this feature, the user should pass a devargs parameter to the EAL
 like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
 PMD will use the floating VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
+Like "-w 84:00.0,enable_floatingVEB=1,floating_bitmap=1", means only the VF0
+connect to the floating VEB, VF1 connect to the legacy VEB.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration. 
 
 The floating VEB means the VEB doesn't has some uplink connection to the outside
 world, so all the switching belong to this VEB cannot go to outside, the
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 025d498..17aaa08 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,52 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_fbitmap_handler(__rte_unused const char *key,
+				      const char *value,
+				      void *opaque)
+{
+	errno = 0;
+	*(uint16_t *)opaque = strtoul(value, NULL, 0);
+	if (errno)
+		return -1;
+	return 0;
+}
+
+static uint16_t i40e_check_fbitmap(struct rte_devargs *devargs,
+				   uint16_t floating)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_bitmap = "floating_bitmap";
+	/* default value for vf floating bitmap is -1 */
+	uint16_t vf_fbitmap = (uint16_t)-1;
+	uint16_t new_vf_fbitmap;
+
+	if (floating == false)
+		return 0;
+
+	if (devargs == NULL)
+		return vf_fbitmap;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return vf_fbitmap;
+
+	if (!rte_kvargs_count(kvlist, floating_bitmap)) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_bitmap,
+			       i40e_check_fbitmap_handler,
+			       &new_vf_fbitmap) < 0) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	rte_kvargs_free(kvlist);
+
+	return new_vf_fbitmap;
+}
+
 static int i40e_check_floating_handler(__rte_unused const char *key,
 				       const char *value,
 				       __rte_unused void *opaque)
@@ -884,8 +930,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	/* Need the special FW version support floating VEB */
 	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
 		pf->floating = i40e_check_floating(pci_dev->devargs);
+		pf->vf_fbitmap = i40e_check_fbitmap(pci_dev->devargs,
+						    pf->floating);
 	} else {
 		pf->floating = false;
+		pf->vf_fbitmap = 0;
 	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
@@ -3855,6 +3904,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3886,7 +3936,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
-	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !(pf->vf_fbitmap && 1 << user_param))) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3901,7 +3952,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
 
-	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    (pf->vf_fbitmap && 1 << user_param)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL ||
 		    vsi->parent_vsi->floating_veb == NULL) {
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index deef0ce..39c3664 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -458,6 +458,7 @@ struct i40e_pf {
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
 	uint16_t floating; /* The flag to use the floating VEB */
+	uint16_t vf_fbitmap; /* The floating enable flag for the specific VF */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 9adfad2..312e1f8 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -224,7 +224,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
-	if (pf->floating == true) {
+	if (pf->floating == true &&
+	    (pf->vf_fbitmap & 1 << vf_id)) {
 		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
 			NULL, vf->vf_idx);
 	} else {
-- 
2.1.4

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

* [PATCH v10 0/3] i40e: add floating VEB support for i40e
  2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
                                     ` (2 preceding siblings ...)
  2016-06-13  6:45                   ` [PATCH v9 3/3] i40e: add floating VEB extension support Zhe Tao
@ 2016-06-13  8:02                   ` Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 1/3] i40e: support floating VEB config Zhe Tao
                                       ` (4 more replies)
  3 siblings, 5 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  8:02 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (3):
  Support floating VEB config
  Add floating VEB support in i40e
  Add floating VEB extention support for i40e

 doc/guides/nics/i40e.rst               |  25 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h         |   9 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 232 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 

-- 
2.1.4

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

* [PATCH v10 1/3] i40e: support floating VEB config
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
@ 2016-06-13  8:02                     ` Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 2/3] i40e: add floating VEB support in i40e Zhe Tao
                                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  8:02 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy VEB/VEPA
or floating VEB.
To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

But for floating VEB, it has two major difference.
1. doesn't has a up link connection which means
the traffic cannot go to ouside world.
2. doesn't need to connect to the phsical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..8c4ae1c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floatingVEB";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -843,6 +881,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..8297c5f 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -450,6 +455,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v10 2/3] i40e: add floating VEB support in i40e
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 1/3] i40e: support floating VEB config Zhe Tao
@ 2016-06-13  8:02                     ` Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 3/3] i40e: add floating VEB extension support Zhe Tao
                                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  8:02 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

Now the floating VEB feature is only avaiable for the FW version which
newer than 5.0 (FW major version number > 5).

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  17 +++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 109 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 120 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..aae78ca 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,20 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
+PMD will use the floating VEB feature for all the VFs created by this PF device.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..686b683 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst. 
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8c4ae1c..025d498 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3762,21 +3762,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3788,9 +3794,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3802,11 +3808,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3822,10 +3836,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3858,12 +3872,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3877,6 +3900,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4045,7 +4085,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4057,11 +4098,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4069,6 +4117,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4078,7 +4136,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4232,7 +4290,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4340,8 +4402,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 8297c5f..deef0ce 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v10 3/3] i40e: add floating VEB extension support
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 1/3] i40e: support floating VEB config Zhe Tao
  2016-06-13  8:02                     ` [PATCH v10 2/3] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-13  8:02                     ` Zhe Tao
  2016-06-14  3:38                     ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Wu, Jingjing
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13  8:02 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

To enable this feature, the user should pass a devargs parameter to the EAL
like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the PMD
will use the floating VEB feature for all the VFs created by this PF device.

Also you can specifiy which VF need to connect to this floating veb using
"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
Like "-w 84:00.0,enable_floatingVEB=1,floating_bitmap=1", means only the VF0 connect
to the floating VEB, VF1 connect to the legacy VEB.

The current implementation only support one floating VEB and one legacy
VEB. VF can connect to floating VEB or legacy VEB according to the
configuration.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst       |  8 ++++++
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.h |  1 +
 drivers/net/i40e/i40e_pf.c     |  3 ++-
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index aae78ca..d3196ad 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -372,6 +372,14 @@ FVL can support floating VEB feature.
 To enable this feature, the user should pass a devargs parameter to the EAL
 like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
 PMD will use the floating VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
+Like "-w 84:00.0,enable_floatingVEB=1,floating_bitmap=1", means only the VF0
+connect to the floating VEB, VF1 connect to the legacy VEB.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration. 
 
 The floating VEB means the VEB doesn't has some uplink connection to the outside
 world, so all the switching belong to this VEB cannot go to outside, the
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 025d498..17aaa08 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,52 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_fbitmap_handler(__rte_unused const char *key,
+				      const char *value,
+				      void *opaque)
+{
+	errno = 0;
+	*(uint16_t *)opaque = strtoul(value, NULL, 0);
+	if (errno)
+		return -1;
+	return 0;
+}
+
+static uint16_t i40e_check_fbitmap(struct rte_devargs *devargs,
+				   uint16_t floating)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_bitmap = "floating_bitmap";
+	/* default value for vf floating bitmap is -1 */
+	uint16_t vf_fbitmap = (uint16_t)-1;
+	uint16_t new_vf_fbitmap;
+
+	if (floating == false)
+		return 0;
+
+	if (devargs == NULL)
+		return vf_fbitmap;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return vf_fbitmap;
+
+	if (!rte_kvargs_count(kvlist, floating_bitmap)) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_bitmap,
+			       i40e_check_fbitmap_handler,
+			       &new_vf_fbitmap) < 0) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	rte_kvargs_free(kvlist);
+
+	return new_vf_fbitmap;
+}
+
 static int i40e_check_floating_handler(__rte_unused const char *key,
 				       const char *value,
 				       __rte_unused void *opaque)
@@ -884,8 +930,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	/* Need the special FW version support floating VEB */
 	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
 		pf->floating = i40e_check_floating(pci_dev->devargs);
+		pf->vf_fbitmap = i40e_check_fbitmap(pci_dev->devargs,
+						    pf->floating);
 	} else {
 		pf->floating = false;
+		pf->vf_fbitmap = 0;
 	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
@@ -3855,6 +3904,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3886,7 +3936,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
-	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !(pf->vf_fbitmap && 1 << user_param))) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3901,7 +3952,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
 
-	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    (pf->vf_fbitmap && 1 << user_param)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL ||
 		    vsi->parent_vsi->floating_veb == NULL) {
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index deef0ce..39c3664 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -458,6 +458,7 @@ struct i40e_pf {
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
 	uint16_t floating; /* The flag to use the floating VEB */
+	uint16_t vf_fbitmap; /* The floating enable flag for the specific VF */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 9adfad2..312e1f8 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -224,7 +224,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
-	if (pf->floating == true) {
+	if (pf->floating == true &&
+	    (pf->vf_fbitmap & 1 << vf_id)) {
 		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
 			NULL, vf->vf_idx);
 	} else {
-- 
2.1.4

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

* Re: [PATCH v11 0/3] i40e: add floating VEB support for i40e
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
@ 2016-06-13 21:44                       ` Zhe Tao
  2016-06-14  5:57                       ` [PATCH v11 1/3] i40e: support floating VEB config Zhe Tao
                                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-13 21:44 UTC (permalink / raw)
  To: dev; +Cc: jingjing.wu

On Tue, Jun 14, 2016 at 01:57:11PM +0800, Zhe Tao wrote:
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W which newer
> than 5.0.
> 
> Zhe Tao (3):
>   i40e: support floating VEB config
>   i40e: add floating VEB support in i40e
>   i40e: add floating VEB extension support
> 
>  doc/guides/nics/i40e.rst               |  25 ++++
>  doc/guides/rel_notes/release_16_07.rst |   4 +
>  drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
>  drivers/net/i40e/i40e_ethdev.h         |   9 ++
>  drivers/net/i40e/i40e_pf.c             |  12 +-
>  5 files changed, 232 insertions(+), 23 deletions(-)
> 
> V2: Added the release notes and changed commit log. 
> V3: Changed the VSI release operation. 
> V4: Added the FW version check otherwise it will cause the segment fault.
> V5: Edited the code for new share code APIs
> V6: Changed the floating VEB configuration method 
> V7: Added global reset for i40e 
> V8: removed global reset and added floating VEB extension support 
> V9: Added floating VEB related explanation into commit log 
> V10: Changed third patch commit log 
> V11: Fixed the issues reported by check-git-log.sh 
> 
> -- 
> 2.1.4
Acked-by: Jingjing Wu <jingjing.wu@intel.com>

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

* Re: [PATCH v10 0/3] i40e: add floating VEB support for i40e
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
                                       ` (2 preceding siblings ...)
  2016-06-13  8:02                     ` [PATCH v10 3/3] i40e: add floating VEB extension support Zhe Tao
@ 2016-06-14  3:38                     ` Wu, Jingjing
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Wu, Jingjing @ 2016-06-14  3:38 UTC (permalink / raw)
  To: Tao, Zhe, dev



> -----Original Message-----
> From: Tao, Zhe
> Sent: Monday, June 13, 2016 4:03 PM
> To: dev@dpdk.org
> Cc: Tao, Zhe <zhe.tao@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v10 0/3] i40e: add floating VEB support for i40e
> 
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W which newer
> than 5.0.
> 
> Zhe Tao (3):
>   Support floating VEB config
>   Add floating VEB support in i40e
>   Add floating VEB extention support for i40e
> 
>  doc/guides/nics/i40e.rst               |  25 ++++
>  doc/guides/rel_notes/release_16_07.rst |   4 +
>  drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
>  drivers/net/i40e/i40e_ethdev.h         |   9 ++
>  drivers/net/i40e/i40e_pf.c             |  12 +-
>  5 files changed, 232 insertions(+), 23 deletions(-)
> 
> V2: Added the release notes and changed commit log.
> V3: Changed the VSI release operation.
> V4: Added the FW version check otherwise it will cause the segment fault.
> V5: Edited the code for new share code APIs
> V6: Changed the floating VEB configuration method
> V7: Added global reset for i40e
> V8: removed global reset and added floating VEB extension support
> V9: Added floating VEB related explanation into commit log
> V10: Changed third patch commit log
> 
> --
> 2.1.4

Acked-by: Jingjing Wu <jingjing.wu@intel.com>

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

* [PATCH v11 0/3] i40e: add floating VEB support for i40e
  2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
                                       ` (3 preceding siblings ...)
  2016-06-14  3:38                     ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Wu, Jingjing
@ 2016-06-14  5:57                     ` Zhe Tao
  2016-06-13 21:44                       ` Zhe Tao
                                         ` (4 more replies)
  4 siblings, 5 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-14  5:57 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (3):
  i40e: support floating VEB config
  i40e: add floating VEB support in i40e
  i40e: add floating VEB extension support

 doc/guides/nics/i40e.rst               |  25 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 205 +++++++++++++++++++++++++++++----
 drivers/net/i40e/i40e_ethdev.h         |   9 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 232 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 
V11: Fixed the issues reported by check-git-log.sh 

-- 
2.1.4

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

* [PATCH v11 1/3] i40e: support floating VEB config
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
  2016-06-13 21:44                       ` Zhe Tao
@ 2016-06-14  5:57                       ` Zhe Tao
  2016-06-14  5:57                       ` [PATCH v11 2/3] i40e: add floating VEB support in i40e Zhe Tao
                                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-14  5:57 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the samples can decide whether to use legacy
VEB/VEPA or floating VEB.
To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floatingVEB=1", and the application will make
sure the PMD will use the floating VEB feature for all the VFs created by
this PF device.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

But for floating VEB, it has two major difference.
1. doesn't has a up link connection which means
the traffic cannot go to ouside world.
2. doesn't need to connect to the phsical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  6 ++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..8c4ae1c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,44 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+i40e_check_floating(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_key = "enable_floatingVEB";
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -843,6 +881,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
+		pf->floating = i40e_check_floating(pci_dev->devargs);
+	} else {
+		pf->floating = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..8297c5f 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_FW_MAJ 5
+#define FLOATING_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -450,6 +455,7 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	uint16_t floating; /* The flag to use the floating VEB */
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v11 2/3] i40e: add floating VEB support in i40e
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
  2016-06-13 21:44                       ` Zhe Tao
  2016-06-14  5:57                       ` [PATCH v11 1/3] i40e: support floating VEB config Zhe Tao
@ 2016-06-14  5:57                       ` Zhe Tao
  2016-06-14  5:57                       ` [PATCH v11 3/3] i40e: add floating VEB extension support Zhe Tao
  2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-14  5:57 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

Now the floating VEB feature is only avaiable for the FW version which
newer than 5.0 (FW major version number > 5).

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  17 +++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 109 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  11 +++-
 5 files changed, 120 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..aae78ca 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,20 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
+PMD will use the floating VEB feature for all the VFs created by this PF device.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..1752c40 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8c4ae1c..025d498 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3762,21 +3762,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3788,9 +3794,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3802,11 +3808,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3822,10 +3836,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3858,12 +3872,21 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3877,6 +3900,23 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4045,7 +4085,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4057,11 +4098,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4069,6 +4117,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4078,7 +4136,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4232,7 +4290,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4340,8 +4402,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 8297c5f..deef0ce 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..9adfad2 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,15 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating == true) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v11 3/3] i40e: add floating VEB extension support
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
                                         ` (2 preceding siblings ...)
  2016-06-14  5:57                       ` [PATCH v11 2/3] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-14  5:57                       ` Zhe Tao
  2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-14  5:57 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floatingVEB=1", and the application will make
sure the PMD will use the floating VEB feature for all the VFs created by
this PF device.

Also you can specifiy which VF need to connect to this floating veb using
"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
Like "-w 84:00.0,enable_floatingVEB=1,floating_bitmap=1", means only the
VF0 connect to the floating VEB, VF1 connect to the legacy VEB.

The current implementation only support one floating VEB and one legacy
VEB. VF can connect to floating VEB or legacy VEB according to the
configuration.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst       |  8 ++++++
 drivers/net/i40e/i40e_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/i40e/i40e_ethdev.h |  1 +
 drivers/net/i40e/i40e_pf.c     |  3 ++-
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index aae78ca..a34d91a 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -372,6 +372,14 @@ FVL can support floating VEB feature.
 To enable this feature, the user should pass a devargs parameter to the EAL
 like "-w 84:00.0,enable_floatingVEB=1", and the application will make sure the
 PMD will use the floating VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_bitmap", every bit corresponding to one VF (e.g. bitn for VFn).
+Like "-w 84:00.0,enable_floatingVEB=1,floating_bitmap=1", means only the VF0
+connect to the floating VEB, VF1 connect to the legacy VEB.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration.
 
 The floating VEB means the VEB doesn't has some uplink connection to the outside
 world, so all the switching belong to this VEB cannot go to outside, the
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 025d498..17aaa08 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -750,6 +750,52 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int i40e_check_fbitmap_handler(__rte_unused const char *key,
+				      const char *value,
+				      void *opaque)
+{
+	errno = 0;
+	*(uint16_t *)opaque = strtoul(value, NULL, 0);
+	if (errno)
+		return -1;
+	return 0;
+}
+
+static uint16_t i40e_check_fbitmap(struct rte_devargs *devargs,
+				   uint16_t floating)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_bitmap = "floating_bitmap";
+	/* default value for vf floating bitmap is -1 */
+	uint16_t vf_fbitmap = (uint16_t)-1;
+	uint16_t new_vf_fbitmap;
+
+	if (floating == false)
+		return 0;
+
+	if (devargs == NULL)
+		return vf_fbitmap;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return vf_fbitmap;
+
+	if (!rte_kvargs_count(kvlist, floating_bitmap)) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	/* Floating is enabled when there's key-value: enable_floatingVEB=1 */
+	if (rte_kvargs_process(kvlist, floating_bitmap,
+			       i40e_check_fbitmap_handler,
+			       &new_vf_fbitmap) < 0) {
+		rte_kvargs_free(kvlist);
+		return vf_fbitmap;
+	}
+	rte_kvargs_free(kvlist);
+
+	return new_vf_fbitmap;
+}
+
 static int i40e_check_floating_handler(__rte_unused const char *key,
 				       const char *value,
 				       __rte_unused void *opaque)
@@ -884,8 +930,11 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 	/* Need the special FW version support floating VEB */
 	if (hw->aq.fw_maj_ver >= FLOATING_FW_MAJ) {
 		pf->floating = i40e_check_floating(pci_dev->devargs);
+		pf->vf_fbitmap = i40e_check_fbitmap(pci_dev->devargs,
+						    pf->floating);
 	} else {
 		pf->floating = false;
+		pf->vf_fbitmap = 0;
 	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
@@ -3855,6 +3904,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3886,7 +3936,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		rte_free(f);
 
 	if (vsi->type != I40E_VSI_MAIN &&
-	    ((vsi->type != I40E_VSI_SRIOV) || !pf->floating)) {
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !(pf->vf_fbitmap && 1 << user_param))) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3901,7 +3952,8 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
 
-	if ((vsi->type == I40E_VSI_SRIOV) && pf->floating) {
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    (pf->vf_fbitmap && 1 << user_param)) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL ||
 		    vsi->parent_vsi->floating_veb == NULL) {
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index deef0ce..39c3664 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -458,6 +458,7 @@ struct i40e_pf {
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
 	uint16_t floating; /* The flag to use the floating VEB */
+	uint16_t vf_fbitmap; /* The floating enable flag for the specific VF */
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 9adfad2..312e1f8 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -224,7 +224,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
-	if (pf->floating == true) {
+	if (pf->floating == true &&
+	    (pf->vf_fbitmap & 1 << vf_id)) {
 		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
 			NULL, vf->vf_idx);
 	} else {
-- 
2.1.4

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

* [PATCH v12 0/2] i40e: add floating VEB support for i40e
  2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
                                         ` (3 preceding siblings ...)
  2016-06-14  5:57                       ` [PATCH v11 3/3] i40e: add floating VEB extension support Zhe Tao
@ 2016-06-24  8:29                       ` Zhe Tao
  2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
                                           ` (2 more replies)
  4 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-24  8:29 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (2):
  i40e: support floating VEB config
  i40e: add floating VEB support in i40e

 doc/guides/nics/i40e.rst               |  27 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 254 ++++++++++++++++++++++++++++++---
 drivers/net/i40e/i40e_ethdev.h         |  12 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 286 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 
V11: Fixed the issues reported by check-git-log.sh 
V12: Changed the floating VEB VF bitmask to VF list 

-- 
2.1.4

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

* [PATCH v12 1/2] i40e: support floating VEB config
  2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
@ 2016-06-24  8:29                         ` Zhe Tao
  2016-06-24  9:27                           ` Bruce Richardson
  2016-06-24 11:14                           ` Ferruh Yigit
  2016-06-24  8:29                         ` [PATCH v12 2/2] i40e: add floating VEB support in i40e Zhe Tao
  2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2 siblings, 2 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-24  8:29 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating VEB related arguments option in the devarg.
Using this parameter, all the applications can decide whether to use legacy
VEB/VEPA or floating VEB.
To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
tell PMD whether to use the floating VEB feature or not.
Once the floating VEB feature is enabled, all the VFs created by
this PF device are connected to the floating VEB.

Also user can specify which VF need to connect to this floating veb using
"floating_veb_list".
Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
is used for delimiter of the floating VEB list.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

But for floating VEB, it has two major difference.
1. doesn't has a up link connection which means
the traffic cannot go to outside world.
2. doesn't need to connect to the physical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 142 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  10 +++
 2 files changed, 152 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..b304fc3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -63,6 +63,9 @@
 #include "i40e_pf.h"
 #include "i40e_regs.h"
 
+#define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
+#define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
+
 #define I40E_CLEAR_PXE_WAIT_MS     200
 
 /* Maximun number of capability elements */
@@ -750,6 +753,136 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 				  " frames from VSIs.");
 }
 
+static int vf_floating_veb_handler(__rte_unused const char *key,
+				   const char *floating_veb_value,
+				   void *opaque)
+{
+	int idx = 0;
+	unsigned count = 0;
+	char *end = NULL;
+	int min, max;
+	bool *vf_floating_veb = opaque;
+
+	while (isblank(*floating_veb_value))
+		floating_veb_value++;
+
+	/* Reset floating VEB configuration for VFs */
+	for (idx = 0; idx < I40E_MAX_VF; idx++)
+		vf_floating_veb[idx] = false;
+
+	min = I40E_MAX_VF;
+	do {
+		while (isblank(*floating_veb_value))
+			floating_veb_value++;
+		if (*floating_veb_value == '\0')
+			return -1;
+		errno = 0;
+		idx = strtoul(floating_veb_value, &end, 10);
+		if (errno || end == NULL)
+			return -1;
+		while (isblank(*end))
+			end++;
+		if (*end == '-') {
+			min = idx;
+		} else if ((*end == '/') || (*end == '\0')) {
+			max = idx;
+			if (min == I40E_MAX_VF)
+				min = idx;
+			if (max >= I40E_MAX_VF)
+				max = I40E_MAX_VF - 1;
+			for (idx = min; idx <= max; idx++) {
+				vf_floating_veb[idx] = true;
+				count++;
+			}
+			min = I40E_MAX_VF;
+		} else {
+			return -1;
+		}
+		floating_veb_value = end + 1;
+	} while (*end != '\0');
+
+	if (count == 0)
+		return -1;
+
+	return 0;
+}
+
+static void config_vf_floating_veb(struct rte_devargs *devargs,
+				   uint16_t floating,
+				   bool *vf_floating_veb)
+{
+	struct rte_kvargs *kvlist;
+	int i;
+	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
+
+	if (floating == false)
+		return;
+	for (i = 0; i < I40E_MAX_VF; i++)
+		vf_floating_veb[i] = true;
+
+	if (devargs == NULL)
+		return;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+
+	if (rte_kvargs_process(kvlist, floating_veb_list,
+			       vf_floating_veb_handler,
+			       vf_floating_veb) < 0) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	rte_kvargs_free(kvlist);
+
+	return;
+}
+
+static int i40e_check_floating_handler(__rte_unused const char *key,
+				       const char *value,
+				       __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+floating_veb_supported(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating VEB is enabled when there's key-value:
+	 * enable_floating_veb=1
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -843,6 +976,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version support floating VEB */
+	memset(pf->vf_floating_veb, 0, sizeof(pf->vf_floating_veb));
+	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
+		pf->floating_veb = floating_veb_supported(pci_dev->devargs);
+		config_vf_floating_veb(pci_dev->devargs, pf->floating_veb,
+				       pf->vf_floating_veb);
+	} else {
+		pf->floating_veb = false;
+	}
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..71bca65 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_VEB_SUPPORTED_FW_MAJ 5
+#define FLOATING_VEB_SUPPORTED_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -398,6 +403,8 @@ struct i40e_mirror_rule {
 
 TAILQ_HEAD(i40e_mirror_rule_list, i40e_mirror_rule);
 
+#define I40E_MAX_VF		128
+
 /*
  * Structure to store private data specific for PF instance.
  */
@@ -450,6 +457,9 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	bool floating_veb; /* The flag to use the floating VEB */
+	/* The floating enable flag for the specific VF */
+	bool vf_floating_veb[I40E_MAX_VF];
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v12 2/2] i40e: add floating VEB support in i40e
  2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-06-24  8:29                         ` Zhe Tao
  2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-24  8:29 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

The floating VEB feature is only available for the FW version which
newer than 5.0 (FW major version number > 5).

To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floating_veb=1", and the application use
this method to tell PMD to connect all the VFs created by
this PF device to the floating VEB.

Also you can specify which VF need to connect to this floating veb using
"floating_veb_list".
Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
is used for delimiter of the floating VEB list.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  27 ++++++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 112 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  12 +++-
 5 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..1ce60ab 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,30 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
+
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating_veb=1", and then the PMD will use the floating
+VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_veb_list".
+Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
+VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
+is used for delimiter of the floating VEB list.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..1752c40 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index b304fc3..4673619 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3860,21 +3860,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3886,9 +3892,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3900,11 +3906,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3920,10 +3934,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3939,6 +3953,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3956,12 +3971,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !pf->vf_floating_veb[user_param])) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3975,6 +4000,24 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    pf->vf_floating_veb[user_param]) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4143,7 +4186,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4155,11 +4199,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4167,6 +4218,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4176,7 +4237,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4330,7 +4391,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4438,8 +4503,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 71bca65..d8a7832 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..ac27070 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,16 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating_veb == true &&
+	    pf->vf_floating_veb[vf_id]) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: [PATCH v12 1/2] i40e: support floating VEB config
  2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-06-24  9:27                           ` Bruce Richardson
  2016-06-24 11:14                           ` Ferruh Yigit
  1 sibling, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-24  9:27 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Fri, Jun 24, 2016 at 04:29:38PM +0800, Zhe Tao wrote:
> Add the new floating VEB related arguments option in the devarg.
> Using this parameter, all the applications can decide whether to use legacy
> VEB/VEPA or floating VEB.
> To enable this feature, the user should pass a devargs parameter to the
> EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
> tell PMD whether to use the floating VEB feature or not.
> Once the floating VEB feature is enabled, all the VFs created by
> this PF device are connected to the floating VEB.
> 
> Also user can specify which VF need to connect to this floating veb using
> "floating_veb_list".
> Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
> VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
> is used for delimiter of the floating VEB list.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in
> the 802.1Qbg spec.
> 
> But for floating VEB, it has two major difference.
> 1. doesn't has a up link connection which means
> the traffic cannot go to outside world.
> 2. doesn't need to connect to the physical port which means
> when the physical link is down the floating VEB can still works
> fine.

Does the term "floating VEB" come from the spec you quote above? If not, I think
a more meaningful name might be found for it, given the description of what it
does. I'm not sure how the term "floating" applies to the concept. It seems
more like an "internal VEB".

/Bruce

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

* Re: [PATCH v12 1/2] i40e: support floating VEB config
  2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
  2016-06-24  9:27                           ` Bruce Richardson
@ 2016-06-24 11:14                           ` Ferruh Yigit
  2016-06-26 20:28                             ` Zhe Tao
  1 sibling, 1 reply; 79+ messages in thread
From: Ferruh Yigit @ 2016-06-24 11:14 UTC (permalink / raw)
  To: Zhe Tao, dev; +Cc: jingjing.wu

Hi Zhe,

On 6/24/2016 9:29 AM, Zhe Tao wrote:
> Add the new floating VEB related arguments option in the devarg.
> Using this parameter, all the applications can decide whether to use legacy
> VEB/VEPA or floating VEB.
> To enable this feature, the user should pass a devargs parameter to the
> EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
> tell PMD whether to use the floating VEB feature or not.
Is providing the enable_floating_veb=1 devarg enough, or should
application call an driver API to enable this feature, if so documenting
what application needs to do helps app developers.

> Once the floating VEB feature is enabled, all the VFs created by
> this PF device are connected to the floating VEB.
Technically there can be multiple floating VEBs, right? And with this
param only one floating VEB created and all VFs connected to it. Is
there any use case to create multiple VEBs with selective VFs connected
to them?

> 
> Also user can specify which VF need to connect to this floating veb using
> "floating_veb_list".
> Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
> VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
> is used for delimiter of the floating VEB list.
Is there a use case to change VF VEB connection on runtime?

> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in
> the 802.1Qbg spec.
> 
> But for floating VEB, it has two major difference.
> 1. doesn't has a up link connection which means
> the traffic cannot go to outside world.
> 2. doesn't need to connect to the physical port which means
> when the physical link is down the floating VEB can still works
> fine.
> 
> Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> ---

...

>  
> +static int vf_floating_veb_handler(__rte_unused const char *key,
What about floating_veb_list_handler, to be consistent with argument name?

> +				   const char *floating_veb_value,
> +				   void *opaque)
> +{
> +	int idx = 0;
> +	unsigned count = 0;
> +	char *end = NULL;
> +	int min, max;
> +	bool *vf_floating_veb = opaque;
> +
> +	while (isblank(*floating_veb_value))
> +		floating_veb_value++;
> +
> +	/* Reset floating VEB configuration for VFs */
> +	for (idx = 0; idx < I40E_MAX_VF; idx++)
> +		vf_floating_veb[idx] = false;
> +
> +	min = I40E_MAX_VF;
> +	do {
> +		while (isblank(*floating_veb_value))
> +			floating_veb_value++;
> +		if (*floating_veb_value == '\0')
> +			return -1;
> +		errno = 0;
> +		idx = strtoul(floating_veb_value, &end, 10);
> +		if (errno || end == NULL)
> +			return -1;
> +		while (isblank(*end))
> +			end++;
> +		if (*end == '-') {
> +			min = idx;
> +		} else if ((*end == '/') || (*end == '\0')) {
> +			max = idx;
> +			if (min == I40E_MAX_VF)
> +				min = idx;
> +			if (max >= I40E_MAX_VF)
> +				max = I40E_MAX_VF - 1;
> +			for (idx = min; idx <= max; idx++) {
> +				vf_floating_veb[idx] = true;
> +				count++;
> +			}
> +			min = I40E_MAX_VF;
> +		} else {
> +			return -1;
> +		}
> +		floating_veb_value = end + 1;
> +	} while (*end != '\0');
> +
> +	if (count == 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void config_vf_floating_veb(struct rte_devargs *devargs,
According DPDK coding convention, return type should be in a separate line

> +				   uint16_t floating,
floating itself confusing, what about floating_veb?

> +				   bool *vf_floating_veb)
> +{
> +	struct rte_kvargs *kvlist;
> +	int i;
> +	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
> +
> +	if (floating == false)
> +		return;
> +	for (i = 0; i < I40E_MAX_VF; i++)
> +		vf_floating_veb[i] = true;
> +
> +	if (devargs == NULL)
> +		return;
> +
> +	kvlist = rte_kvargs_parse(devargs->args, NULL);
> +	if (kvlist == NULL)
> +		return;
> +
> +	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
> +		rte_kvargs_free(kvlist);
> +		return;
> +	}
> +
> +	if (rte_kvargs_process(kvlist, floating_veb_list,
> +			       vf_floating_veb_handler,
> +			       vf_floating_veb) < 0) {
A comment can be good to say, here floating VEB disabled for all VFs

> +		rte_kvargs_free(kvlist);
> +		return;
> +	}
> +	rte_kvargs_free(kvlist);
> +
> +	return;
not required

> +}
> +
> +static int i40e_check_floating_handler(__rte_unused const char *key,
i40e_check_floating_veb_handler?

> +				       const char *value,
> +				       __rte_unused void *opaque)
> +{
> +	if (strcmp(value, "1"))
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int
> +floating_veb_supported(struct rte_devargs *devargs)
It can be good add a verb to the function name,

> +{
> +	struct rte_kvargs *kvlist;
> +	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
> +
> +	if (devargs == NULL)
> +		return 0;
> +
> +	kvlist = rte_kvargs_parse(devargs->args, NULL);
> +	if (kvlist == NULL)
> +		return 0;
> +
> +	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
> +		rte_kvargs_free(kvlist);
> +		return 0;
> +	}
> +	/* Floating VEB is enabled when there's key-value:
> +	 * enable_floating_veb=1
> +	 */
> +	if (rte_kvargs_process(kvlist, floating_veb_key,
> +			       i40e_check_floating_handler, NULL) < 0) {
> +		rte_kvargs_free(kvlist);
> +		return 0;
> +	}
> +	rte_kvargs_free(kvlist);
> +
> +	return 1;
> +}
> +
>  static int
>  eth_i40e_dev_init(struct rte_eth_dev *dev)
>  {
> @@ -843,6 +976,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>  		     ((hw->nvm.version >> 4) & 0xff),
>  		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
>  
> +	/* Need the special FW version support floating VEB */
> +	memset(pf->vf_floating_veb, 0, sizeof(pf->vf_floating_veb));
> +	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
Does it make sense to move this check into a function, like
is_floating_veb_supported()? This makes what the criteria of floating
veb support more clear, and hides that detail from this piece of code.


> +		pf->floating_veb = floating_veb_supported(pci_dev->devargs);
> +		config_vf_floating_veb(pci_dev->devargs, pf->floating_veb,
> +				       pf->vf_floating_veb);
> +	} else {
> +		pf->floating_veb = false;
> +	}
>  	/* Clear PXE mode */
>  	i40e_clear_pxe_mode(hw);
>  
> diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
> index cfd2399..71bca65 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -36,6 +36,7 @@
>  
>  #include <rte_eth_ctrl.h>
>  #include <rte_time.h>
> +#include <rte_kvargs.h>
>  
>  #define I40E_VLAN_TAG_SIZE        4
>  
> @@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
>  #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
>  #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
>  
> +/* Special FW support this floating VEB feature */
> +#define FLOATING_VEB_SUPPORTED_FW_MAJ 5
> +#define FLOATING_VEB_SUPPORTED_FW_MIN 0
> +
>  struct i40e_adapter;
>  
>  /**
> @@ -398,6 +403,8 @@ struct i40e_mirror_rule {
>  
>  TAILQ_HEAD(i40e_mirror_rule_list, i40e_mirror_rule);
>  
> +#define I40E_MAX_VF		128
> +
>  /*
>   * Structure to store private data specific for PF instance.
>   */
> @@ -450,6 +457,9 @@ struct i40e_pf {
>  	struct i40e_fc_conf fc_conf; /* Flow control conf */
>  	struct i40e_mirror_rule_list mirror_list;
>  	uint16_t nb_mirror_rule;   /* The number of mirror rules */
> +	bool floating_veb; /* The flag to use the floating VEB */
> +	/* The floating enable flag for the specific VF */
> +	bool vf_floating_veb[I40E_MAX_VF];
what about floating_veb_list, to be consistent with argument name?

>  };
>  
>  enum pending_msg {
> 

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

* Re: [PATCH v12 1/2] i40e: support floating VEB config
  2016-06-24 11:14                           ` Ferruh Yigit
@ 2016-06-26 20:28                             ` Zhe Tao
  0 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-26 20:28 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, jingjing.wu

On Fri, Jun 24, 2016 at 12:14:14PM +0100, Ferruh Yigit wrote:
> Hi Zhe,
> 
> On 6/24/2016 9:29 AM, Zhe Tao wrote:
> > Add the new floating VEB related arguments option in the devarg.
> > Using this parameter, all the applications can decide whether to use legacy
> > VEB/VEPA or floating VEB.
> > To enable this feature, the user should pass a devargs parameter to the
> > EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
> > tell PMD whether to use the floating VEB feature or not.
> Is providing the enable_floating_veb=1 devarg enough, or should
> application call an driver API to enable this feature, if so documenting
> what application needs to do helps app developers.
yes only provide the devarg is enough, the APP don't need to modify.
> 
> > Once the floating VEB feature is enabled, all the VFs created by
> > this PF device are connected to the floating VEB.
> Technically there can be multiple floating VEBs, right? And with this
> param only one floating VEB created and all VFs connected to it. Is
> there any use case to create multiple VEBs with selective VFs connected
> to them?
discuss this feature internally with Walter and FAE team, have an agreement
for this release we only implement one floating VEB.
> 
> > 
> > Also user can specify which VF need to connect to this floating veb using
> > "floating_veb_list".
> > Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
> > VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
> > is used for delimiter of the floating VEB list.
> Is there a use case to change VF VEB connection on runtime?
maybe there is a case, but from the customer requirement, we only support the static
configuration for floating VEB.

> 
> > 
> > All the VEB/VEPA concepts are not specific for FVL, they are defined in
> > the 802.1Qbg spec.
> > 
> > But for floating VEB, it has two major difference.
> > 1. doesn't has a up link connection which means
> > the traffic cannot go to outside world.
> > 2. doesn't need to connect to the physical port which means
> > when the physical link is down the floating VEB can still works
> > fine.
> > 
> > Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> > ---
> 
> ...
> 
> >  
> > +static int vf_floating_veb_handler(__rte_unused const char *key,
> What about floating_veb_list_handler, to be consistent with argument name?
> 
> > +				   const char *floating_veb_value,
> > +				   void *opaque)
> > +{
> > +	int idx = 0;
> > +	bool floating_veb; /* The flag to use the floating VEB */
> > +	/* The floating enable flag for the specific VF */
> > +	bool vf_floating_veb[I40E_MAX_VF];
> what about floating_veb_list, to be consistent with argument name?
> 
> >  };
> >  
> >  enum pending_msg {
> > 
All the comments in the code is great, I changed the code according to your
comments,
thanks again
Zhe 

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

* [PATCH v13 0/2] i40e: add floating VEB support for i40e
  2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
  2016-06-24  8:29                         ` [PATCH v12 2/2] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-27  5:12                         ` Zhe Tao
  2016-06-27  5:12                           ` [PATCH v13 1/2] i40e: support floating VEB config Zhe Tao
                                             ` (2 more replies)
  2 siblings, 3 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  5:12 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (2):
  i40e: support floating VEB config
  i40e: add floating VEB support in i40e

 doc/guides/nics/i40e.rst               |  27 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 272 ++++++++++++++++++++++++++++++---
 drivers/net/i40e/i40e_ethdev.h         |  12 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 304 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 
V11: Fixed the issues reported by check-git-log.sh 
V12: Changed the floating VEB VF bitmask to VF list 
V13: Changed some internal functions'names to make it more clear 

-- 
2.1.4

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

* [PATCH v13 1/2] i40e: support floating VEB config
  2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
@ 2016-06-27  5:12                           ` Zhe Tao
  2016-06-27  5:12                           ` [PATCH v13 2/2] i40e: add floating VEB support in i40e Zhe Tao
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  5:12 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the applications can decide whether to use legacy
VEB/VEPA or floating VEB.
To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
tell PMD whether to use the floating VEB feature or not.
Once the floating VEB feature is enabled, all the VFs created by
this PF device are connected to the floating VEB.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec. But the floating VEB concept is from i40e data sheet.

The standard VEB definition in 1Qbg is a bridge which has a uplink port
to the outside world (maybe another bridge), but floating means this
special VEB has no uplink port to the outside.

For floating VEB, it has two major difference comparing to
the standard VEB:
1. doesn't has a up link connection which means
the traffic cannot go to outside world.
2. doesn't need to connect to the physical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 160 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  10 +++
 2 files changed, 170 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..553ef56 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -63,6 +63,9 @@
 #include "i40e_pf.h"
 #include "i40e_regs.h"
 
+#define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
+#define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
+
 #define I40E_CLEAR_PXE_WAIT_MS     200
 
 /* Maximun number of capability elements */
@@ -751,6 +754,161 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 }
 
 static int
+floating_veb_list_handler(__rte_unused const char *key,
+			  const char *floating_veb_value,
+			  void *opaque)
+{
+	int idx = 0;
+	unsigned count = 0;
+	char *end = NULL;
+	int min, max;
+	bool *vf_floating_veb = opaque;
+
+	while (isblank(*floating_veb_value))
+		floating_veb_value++;
+
+	/* Reset floating VEB configuration for VFs */
+	for (idx = 0; idx < I40E_MAX_VF; idx++)
+		vf_floating_veb[idx] = false;
+
+	min = I40E_MAX_VF;
+	do {
+		while (isblank(*floating_veb_value))
+			floating_veb_value++;
+		if (*floating_veb_value == '\0')
+			return -1;
+		errno = 0;
+		idx = strtoul(floating_veb_value, &end, 10);
+		if (errno || end == NULL)
+			return -1;
+		while (isblank(*end))
+			end++;
+		if (*end == '-') {
+			min = idx;
+		} else if ((*end == '/') || (*end == '\0')) {
+			max = idx;
+			if (min == I40E_MAX_VF)
+				min = idx;
+			if (max >= I40E_MAX_VF)
+				max = I40E_MAX_VF - 1;
+			for (idx = min; idx <= max; idx++) {
+				vf_floating_veb[idx] = true;
+				count++;
+			}
+			min = I40E_MAX_VF;
+		} else {
+			return -1;
+		}
+		floating_veb_value = end + 1;
+	} while (*end != '\0');
+
+	if (count == 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+config_vf_floating_veb(struct rte_devargs *devargs,
+		       uint16_t floating_veb,
+		       bool *vf_floating_veb)
+{
+	struct rte_kvargs *kvlist;
+	int i;
+	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
+
+	if (floating_veb == false)
+		return;
+	/* All the VFs attach to the floating VEB by default
+	 * when the floating VEB is enabled.
+	 */
+	for (i = 0; i < I40E_MAX_VF; i++)
+		vf_floating_veb[i] = true;
+
+	if (devargs == NULL)
+		return;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	/* When the floating_veb_list parameter exists, all the VFs
+	 * will attach to the legacy VEB firstly, then configure VFs
+	 * to the floating VEB according to the floating_veb_list.
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_list,
+			       floating_veb_list_handler,
+			       vf_floating_veb) < 0) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	rte_kvargs_free(kvlist);
+}
+
+static int
+i40e_check_floating_handler(__rte_unused const char *key,
+			    const char *value,
+			    __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+is_floating_veb_supported(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating VEB is enabled when there's key-value:
+	 * enable_floating_veb=1
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
+static void
+config_floating_veb(struct rte_eth_dev *dev)
+{
+	struct rte_pci_device *pci_dev = dev->pci_dev;
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	memset(pf->floating_veb_list, 0, sizeof(pf->floating_veb_list));
+
+	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
+		pf->floating_veb = is_floating_veb_supported(pci_dev->devargs);
+		config_vf_floating_veb(pci_dev->devargs, pf->floating_veb,
+				       pf->floating_veb_list);
+	} else {
+		pf->floating_veb = false;
+	}
+}
+
+static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
 	struct rte_pci_device *pci_dev;
@@ -843,6 +1001,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version to support floating VEB */
+	config_floating_veb(dev);
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..e246eb9 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_VEB_SUPPORTED_FW_MAJ 5
+#define FLOATING_VEB_SUPPORTED_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -398,6 +403,8 @@ struct i40e_mirror_rule {
 
 TAILQ_HEAD(i40e_mirror_rule_list, i40e_mirror_rule);
 
+#define I40E_MAX_VF		128
+
 /*
  * Structure to store private data specific for PF instance.
  */
@@ -450,6 +457,9 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	bool floating_veb; /* The flag to use the floating VEB */
+	/* The floating enable flag for the specific VF */
+	bool floating_veb_list[I40E_MAX_VF];
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v13 2/2] i40e: add floating VEB support in i40e
  2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-27  5:12                           ` [PATCH v13 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-06-27  5:12                           ` Zhe Tao
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  5:12 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

The floating VEB feature is only available for the FW version which
newer than 5.0 (FW major version number > 5).

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  27 ++++++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 112 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  12 +++-
 5 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..1ce60ab 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,30 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
+
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating_veb=1", and then the PMD will use the floating
+VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_veb_list".
+Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
+VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
+is used for delimiter of the floating VEB list.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..1752c40 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 553ef56..52c6b9f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3878,21 +3878,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3904,9 +3910,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3918,11 +3924,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3938,10 +3952,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3957,6 +3971,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3974,12 +3989,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !pf->vf_floating_veb[user_param])) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3993,6 +4018,24 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    pf->vf_floating_veb[user_param]) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4161,7 +4204,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4173,11 +4217,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4185,6 +4236,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4194,7 +4255,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4348,7 +4409,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4456,8 +4521,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index e246eb9..1633607 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..ac27070 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,16 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating_veb == true &&
+	    pf->vf_floating_veb[vf_id]) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v14 0/2] i40e: add floating VEB support for i40e
  2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-27  5:12                           ` [PATCH v13 1/2] i40e: support floating VEB config Zhe Tao
  2016-06-27  5:12                           ` [PATCH v13 2/2] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-27  7:20                           ` Zhe Tao
  2016-06-27  7:20                             ` [PATCH v14 1/2] i40e: support floating VEB config Zhe Tao
                                               ` (4 more replies)
  2 siblings, 5 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  7:20 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (2):
  i40e: support floating VEB config
  i40e: add floating VEB support in i40e

 doc/guides/nics/i40e.rst               |  27 ++++
 doc/guides/rel_notes/release_16_07.rst |   4 +
 drivers/net/i40e/i40e_ethdev.c         | 272 ++++++++++++++++++++++++++++++---
 drivers/net/i40e/i40e_ethdev.h         |  12 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 304 insertions(+), 23 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 
V11: Fixed the issues reported by check-git-log.sh 
V12: Changed the floating VEB VF bitmask to VF list 
V13: Changed some internal functions'names to make it more clear 
V14: Changed some internal variable names 

-- 
2.1.4

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

* [PATCH v14 1/2] i40e: support floating VEB config
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
@ 2016-06-27  7:20                             ` Zhe Tao
  2016-06-27  7:20                             ` [PATCH v14 2/2] i40e: add floating VEB support in i40e Zhe Tao
                                               ` (3 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  7:20 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

Add the new floating related argument option in the devarg.
Using this parameter, all the applications can decide whether to use legacy
VEB/VEPA or floating VEB.
To enable this feature, the user should pass a devargs parameter to the
EAL like "-w 84:00.0,enable_floating_veb=1", and the application will
tell PMD whether to use the floating VEB feature or not.
Once the floating VEB feature is enabled, all the VFs created by
this PF device are connected to the floating VEB.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec. But the floating VEB concept is from i40e data sheet.

The standard VEB definition in 1Qbg is a bridge which has a uplink port
to the outside world (maybe another bridge), but floating means this
special VEB has no uplink port to the outside.

For floating VEB, it has two major difference comparing to
the standard VEB:
1. doesn't has a up link connection which means
the traffic cannot go to outside world.
2. doesn't need to connect to the physical port which means
when the physical link is down the floating VEB can still works
fine.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 160 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h |  10 +++
 2 files changed, 170 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24777d5..553ef56 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -63,6 +63,9 @@
 #include "i40e_pf.h"
 #include "i40e_regs.h"
 
+#define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
+#define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
+
 #define I40E_CLEAR_PXE_WAIT_MS     200
 
 /* Maximun number of capability elements */
@@ -751,6 +754,161 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 }
 
 static int
+floating_veb_list_handler(__rte_unused const char *key,
+			  const char *floating_veb_value,
+			  void *opaque)
+{
+	int idx = 0;
+	unsigned count = 0;
+	char *end = NULL;
+	int min, max;
+	bool *vf_floating_veb = opaque;
+
+	while (isblank(*floating_veb_value))
+		floating_veb_value++;
+
+	/* Reset floating VEB configuration for VFs */
+	for (idx = 0; idx < I40E_MAX_VF; idx++)
+		vf_floating_veb[idx] = false;
+
+	min = I40E_MAX_VF;
+	do {
+		while (isblank(*floating_veb_value))
+			floating_veb_value++;
+		if (*floating_veb_value == '\0')
+			return -1;
+		errno = 0;
+		idx = strtoul(floating_veb_value, &end, 10);
+		if (errno || end == NULL)
+			return -1;
+		while (isblank(*end))
+			end++;
+		if (*end == '-') {
+			min = idx;
+		} else if ((*end == '/') || (*end == '\0')) {
+			max = idx;
+			if (min == I40E_MAX_VF)
+				min = idx;
+			if (max >= I40E_MAX_VF)
+				max = I40E_MAX_VF - 1;
+			for (idx = min; idx <= max; idx++) {
+				vf_floating_veb[idx] = true;
+				count++;
+			}
+			min = I40E_MAX_VF;
+		} else {
+			return -1;
+		}
+		floating_veb_value = end + 1;
+	} while (*end != '\0');
+
+	if (count == 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+config_vf_floating_veb(struct rte_devargs *devargs,
+		       uint16_t floating_veb,
+		       bool *vf_floating_veb)
+{
+	struct rte_kvargs *kvlist;
+	int i;
+	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
+
+	if (floating_veb == false)
+		return;
+	/* All the VFs attach to the floating VEB by default
+	 * when the floating VEB is enabled.
+	 */
+	for (i = 0; i < I40E_MAX_VF; i++)
+		vf_floating_veb[i] = true;
+
+	if (devargs == NULL)
+		return;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	/* When the floating_veb_list parameter exists, all the VFs
+	 * will attach to the legacy VEB firstly, then configure VFs
+	 * to the floating VEB according to the floating_veb_list.
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_list,
+			       floating_veb_list_handler,
+			       vf_floating_veb) < 0) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	rte_kvargs_free(kvlist);
+}
+
+static int
+i40e_check_floating_handler(__rte_unused const char *key,
+			    const char *value,
+			    __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+is_floating_veb_supported(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating VEB is enabled when there's key-value:
+	 * enable_floating_veb=1
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
+static void
+config_floating_veb(struct rte_eth_dev *dev)
+{
+	struct rte_pci_device *pci_dev = dev->pci_dev;
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	memset(pf->floating_veb_list, 0, sizeof(pf->floating_veb_list));
+
+	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
+		pf->floating_veb = is_floating_veb_supported(pci_dev->devargs);
+		config_vf_floating_veb(pci_dev->devargs, pf->floating_veb,
+				       pf->floating_veb_list);
+	} else {
+		pf->floating_veb = false;
+	}
+}
+
+static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
 	struct rte_pci_device *pci_dev;
@@ -843,6 +1001,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version to support floating VEB */
+	config_floating_veb(dev);
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..e246eb9 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -171,6 +172,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_VEB_SUPPORTED_FW_MAJ 5
+#define FLOATING_VEB_SUPPORTED_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
@@ -398,6 +403,8 @@ struct i40e_mirror_rule {
 
 TAILQ_HEAD(i40e_mirror_rule_list, i40e_mirror_rule);
 
+#define I40E_MAX_VF		128
+
 /*
  * Structure to store private data specific for PF instance.
  */
@@ -450,6 +457,9 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	bool floating_veb; /* The flag to use the floating VEB */
+	/* The floating enable flag for the specific VF */
+	bool floating_veb_list[I40E_MAX_VF];
 };
 
 enum pending_msg {
-- 
2.1.4

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

* [PATCH v14 2/2] i40e: add floating VEB support in i40e
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-27  7:20                             ` [PATCH v14 1/2] i40e: support floating VEB config Zhe Tao
@ 2016-06-27  7:20                             ` Zhe Tao
  2016-06-27 13:22                             ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Ferruh Yigit
                                               ` (2 subsequent siblings)
  4 siblings, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-27  7:20 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs still connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in
the 802.1Qbg spec.

The floating VEB feature is only available for the FW version which
newer than 5.0 (FW major version number > 5).

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  27 ++++++++
 doc/guides/rel_notes/release_16_07.rst |   4 ++
 drivers/net/i40e/i40e_ethdev.c         | 112 ++++++++++++++++++++++++++-------
 drivers/net/i40e/i40e_ethdev.h         |   2 +
 drivers/net/i40e/i40e_pf.c             |  12 +++-
 5 files changed, 134 insertions(+), 23 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..1ce60ab 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,30 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+FVL can support floating VEB feature.
+
+The floating VEB means the VEB doesn't has some uplink connection to the outside
+world, so all the switching belong to this VEB cannot go to outside, the
+security can be assured. Because the floating VEB doesn't need to connect to
+the MAC port, so when the physical port link is down, all the switching within
+this VEB still works fine, but for legacy VEB when the physical port is down
+the VEB cannot forward packets anymore.
+
+With this feature, VFs can communicate with each other, but cannot access
+outside network. When PF is down, and VFs can still forward pkts between each
+other.
+
+To enable this feature, the user should pass a devargs parameter to the EAL
+like "-w 84:00.0,enable_floating_veb=1", and then the PMD will use the floating
+VEB feature for all the VFs created by this PF device.
+Also you can specify which VF need to connect to this floating veb using
+"floating_veb_list".
+Like "-w 84:00.0,enable_floating_veb=1,floating_veb_list=1/3-4", means VF1, VF3,
+VF4 connect to the floating VEB, other VFs connect to the legacy VEB.The "/"
+is used for delimiter of the floating VEB list.
+
+The current implementation only support one floating VEB and one legacy
+VEB. VF can connect to floating VEB or legacy VEB according to the
+configuration.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..1752c40 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,10 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  More details please see floating VEB part in the document
+  doc/guides/nics/i40e.rst.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 553ef56..b6abd1c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3878,21 +3878,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3904,9 +3910,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
+	if (NULL == pf) {
 		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+			    "associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3918,11 +3924,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3938,10 +3952,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3957,6 +3971,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3974,12 +3989,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !pf->floating_veb_list[user_param])) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3993,6 +4018,24 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    pf->floating_veb_list[user_param]) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4161,7 +4204,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4173,11 +4217,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4185,6 +4236,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4194,7 +4255,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4348,7 +4409,11 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL) {
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		} else {
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
+		}
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4456,8 +4521,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index e246eb9..1633607 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -224,6 +224,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -264,6 +265,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..3186853 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf = vf->pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -223,9 +224,16 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	vf->reset_cnt++;
 	I40E_WRITE_FLUSH(hw);
 
+	if (pf->floating_veb == true &&
+	    pf->floating_veb_list[vf_id]) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+			NULL, vf->vf_idx);
+	} else {
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+				vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* Re: [PATCH v14 0/2] i40e: add floating VEB support for i40e
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
  2016-06-27  7:20                             ` [PATCH v14 1/2] i40e: support floating VEB config Zhe Tao
  2016-06-27  7:20                             ` [PATCH v14 2/2] i40e: add floating VEB support in i40e Zhe Tao
@ 2016-06-27 13:22                             ` Ferruh Yigit
  2016-06-29  9:42                             ` Bruce Richardson
  2016-06-29 13:06                             ` [PATCH v15 " Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Ferruh Yigit @ 2016-06-27 13:22 UTC (permalink / raw)
  To: Zhe Tao, dev; +Cc: jingjing.wu

On 6/27/2016 8:20 AM, Zhe Tao wrote:
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W which newer
> than 5.0.
> 
> Zhe Tao (2):
>   i40e: support floating VEB config
>   i40e: add floating VEB support in i40e

Series reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

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

* Re: [PATCH v14 0/2] i40e: add floating VEB support for i40e
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
                                               ` (2 preceding siblings ...)
  2016-06-27 13:22                             ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Ferruh Yigit
@ 2016-06-29  9:42                             ` Bruce Richardson
  2016-06-29 13:06                             ` [PATCH v15 " Zhe Tao
  4 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-29  9:42 UTC (permalink / raw)
  To: Zhe Tao; +Cc: dev, jingjing.wu

On Mon, Jun 27, 2016 at 03:20:14PM +0800, Zhe Tao wrote:
> This patch-set add the support for floating VEB in i40e.
> All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
> the floating VEB. When connect to the floating VEB a new floating VEB is
> created. Now all the VFs need to connect to floating VEB or legacy VEB,
> cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
> the old legacy VEB/VEPA.
> 
> All the VEB/VEPA concepts are not specific for FVL, they are defined in the
> 802.1Qbg spec.
> 
> This floating VEB only take effects on the specific version F/W which newer
> than 5.0.
> 
> Zhe Tao (2):
>   i40e: support floating VEB config
>   i40e: add floating VEB support in i40e
> 
I think the order of the patches would be better reversed, with the feature
coming first and the config after. The documentation would then move to the
new second patch on config, which is where it better fits, since a lot of it
describes how to configure the feature.

Regards,
/Bruce

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

* [PATCH v15 0/2] i40e: add floating VEB support for i40e
  2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
                                               ` (3 preceding siblings ...)
  2016-06-29  9:42                             ` Bruce Richardson
@ 2016-06-29 13:06                             ` Zhe Tao
  2016-06-29 13:06                               ` [PATCH v15 1/2] i40e: add floating VEB support Zhe Tao
  2016-06-29 13:06                               ` [PATCH v15 2/2] i40e: add device args to enable a floating VEB Zhe Tao
  4 siblings, 2 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-29 13:06 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

This patch-set add the support for floating VEB in i40e.
All the VFs VSIs can decide whether to connect to the legacy VEB/VEPA or
the floating VEB. When connect to the floating VEB a new floating VEB is
created. Now all the VFs need to connect to floating VEB or legacy VEB,
cannot connect to both of them. The PF and VMDQ,FD VSIs connect to
the old legacy VEB/VEPA.

All the VEB/VEPA concepts are not specific for FVL, they are defined in the
802.1Qbg spec.

This floating VEB only take effects on the specific version F/W which newer
than 5.0.

Zhe Tao (2):
 i40e: add floating VEB support
 i40e: add device args to enable a floating VEB

 doc/guides/nics/i40e.rst               |  45 ++++++
 doc/guides/rel_notes/release_16_07.rst |   8 +
 drivers/net/i40e/i40e_ethdev.c         | 273 ++++++++++++++++++++++++++++++---
 drivers/net/i40e/i40e_ethdev.h         |  12 ++
 drivers/net/i40e/i40e_pf.c             |  12 +-
 5 files changed, 326 insertions(+), 24 deletions(-)

V2: Added the release notes and changed commit log. 
V3: Changed the VSI release operation. 
V4: Added the FW version check otherwise it will cause the segment fault.
V5: Edited the code for new share code APIs
V6: Changed the floating VEB configuration method 
V7: Added global reset for i40e 
V8: removed global reset and added floating VEB extension support 
V9: Added floating VEB related explanation into commit log 
V10: Changed third patch commit log 
V11: Fixed the issues reported by check-git-log.sh 
V12: Changed the floating VEB VF bitmask to VF list 
V13: Changed some internal functions'names to make it more clear 
V14: Changed some internal variable names 
V15: Changed the sequence of patches and add more explanation
     for floating VEB 
-- 
2.1.4

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

* [PATCH v15 1/2] i40e: add floating VEB support
  2016-06-29 13:06                             ` [PATCH v15 " Zhe Tao
@ 2016-06-29 13:06                               ` Zhe Tao
  2016-06-29 13:06                               ` [PATCH v15 2/2] i40e: add device args to enable a floating VEB Zhe Tao
  1 sibling, 0 replies; 79+ messages in thread
From: Zhe Tao @ 2016-06-29 13:06 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

The standard Virtual Ethernet Bridge(VEB) definition in 1Qbg is a bridge
which has an uplink port to the outside world (maybe another bridge),
but a "floating" VEB is a special VEB without an uplink port to the
outside. Instead, traffic can be sent from one VF to another using the
floating VEB - even when the physical link on the NIC port is down.

VFs VSIs connect either to the standard VEB/VEPA or to the floating VEB,
they cannot connect to both of them. The PF, VMDQ and FD VSIs still
connect to the normal VEB/VEPA.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 113 +++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_ethdev.h |   7 +++
 drivers/net/i40e/i40e_pf.c     |  12 ++++-
 3 files changed, 108 insertions(+), 24 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f94ad87..5efcbc2 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3768,21 +3768,27 @@ i40e_veb_release(struct i40e_veb *veb)
 	struct i40e_vsi *vsi;
 	struct i40e_hw *hw;
 
-	if (veb == NULL || veb->associate_vsi == NULL)
+	if (veb == NULL)
 		return -EINVAL;
 
 	if (!TAILQ_EMPTY(&veb->head)) {
 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
 		return -EACCES;
 	}
+	/* associate_vsi field is NULL for floating VEB */
+	if (veb->associate_vsi != NULL) {
+		vsi = veb->associate_vsi;
+		hw = I40E_VSI_TO_HW(vsi);
 
-	vsi = veb->associate_vsi;
-	hw = I40E_VSI_TO_HW(vsi);
+		vsi->uplink_seid = veb->uplink_seid;
+		vsi->veb = NULL;
+	} else {
+		veb->associate_pf->main_vsi->floating_veb = NULL;
+		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
+	}
 
-	vsi->uplink_seid = veb->uplink_seid;
 	i40e_aq_delete_element(hw, veb->seid, NULL);
 	rte_free(veb);
-	vsi->veb = NULL;
 	return I40E_SUCCESS;
 }
 
@@ -3794,9 +3800,9 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	int ret;
 	struct i40e_hw *hw;
 
-	if (NULL == pf || vsi == NULL) {
-		PMD_DRV_LOG(ERR, "veb setup failed, "
-			    "associated VSI shouldn't null");
+	if (pf == NULL) {
+		PMD_DRV_LOG(ERR,
+			    "veb setup failed, associated PF shouldn't null");
 		return NULL;
 	}
 	hw = I40E_PF_TO_HW(pf);
@@ -3808,11 +3814,19 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 	}
 
 	veb->associate_vsi = vsi;
+	veb->associate_pf = pf;
 	TAILQ_INIT(&veb->head);
-	veb->uplink_seid = vsi->uplink_seid;
+	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
 
-	ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
-		I40E_DEFAULT_TCMAP, false, &veb->seid, false, NULL);
+	/* create floating veb if vsi is NULL */
+	if (vsi != NULL) {
+		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
+				      I40E_DEFAULT_TCMAP, false,
+				      &veb->seid, false, NULL);
+	} else {
+		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
+				      true, &veb->seid, false, NULL);
+	}
 
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
@@ -3828,10 +3842,10 @@ i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
 			    hw->aq.asq_last_status);
 		goto fail;
 	}
-
 	/* Get VEB bandwidth, to be implemented */
 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
-	vsi->uplink_seid = veb->seid;
+	if (vsi)
+		vsi->uplink_seid = veb->seid;
 
 	return veb;
 fail:
@@ -3847,6 +3861,7 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 	struct i40e_vsi_list *vsi_list;
 	int ret;
 	struct i40e_mac_filter *f;
+	uint16_t user_param = vsi->user_param;
 
 	if (!vsi)
 		return I40E_SUCCESS;
@@ -3864,12 +3879,22 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		i40e_veb_release(vsi->veb);
 	}
 
+	if (vsi->floating_veb) {
+		TAILQ_FOREACH(vsi_list, &vsi->floating_veb->head, list) {
+			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
+				return -1;
+			TAILQ_REMOVE(&vsi->floating_veb->head, vsi_list, list);
+		}
+	}
+
 	/* Remove all macvlan filters of the VSI */
 	i40e_vsi_remove_all_macvlan_filter(vsi);
 	TAILQ_FOREACH(f, &vsi->mac_list, next)
 		rte_free(f);
 
-	if (vsi->type != I40E_VSI_MAIN) {
+	if (vsi->type != I40E_VSI_MAIN &&
+	    ((vsi->type != I40E_VSI_SRIOV) ||
+	    !pf->floating_veb_list[user_param])) {
 		/* Remove vsi from parent's sibling list */
 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
@@ -3883,6 +3908,24 @@ i40e_vsi_release(struct i40e_vsi *vsi)
 		if (ret != I40E_SUCCESS)
 			PMD_DRV_LOG(ERR, "Failed to delete element");
 	}
+
+	if ((vsi->type == I40E_VSI_SRIOV) &&
+	    pf->floating_veb_list[user_param]) {
+		/* Remove vsi from parent's sibling list */
+		if (vsi->parent_vsi == NULL ||
+		    vsi->parent_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
+			return I40E_ERR_PARAM;
+		}
+		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
+			     &vsi->sib_vsi_list, list);
+
+		/* Remove all switch element of the VSI */
+		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
+		if (ret != I40E_SUCCESS)
+			PMD_DRV_LOG(ERR, "Failed to delete element");
+	}
+
 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
 
 	if (vsi->type != I40E_VSI_SRIOV)
@@ -4051,7 +4094,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	struct ether_addr broadcast =
 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
 
-	if (type != I40E_VSI_MAIN && uplink_vsi == NULL) {
+	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
+	    uplink_vsi == NULL) {
 		PMD_DRV_LOG(ERR, "VSI setup failed, "
 			    "VSI link shouldn't be NULL");
 		return NULL;
@@ -4063,11 +4107,18 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		return NULL;
 	}
 
-	/* If uplink vsi didn't setup VEB, create one first */
-	if (type != I40E_VSI_MAIN && uplink_vsi->veb == NULL) {
+	/* two situations
+	 * 1.type is not MAIN and uplink vsi is not NULL
+	 * If uplink vsi didn't setup VEB, create one first under veb field
+	 * 2.type is SRIOV and the uplink is NULL
+	 * If floating VEB is NULL, create one veb under floating veb field
+	 */
+
+	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
+	    uplink_vsi->veb == NULL) {
 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
 
-		if (NULL == uplink_vsi->veb) {
+		if (uplink_vsi->veb == NULL) {
 			PMD_DRV_LOG(ERR, "VEB setup failed");
 			return NULL;
 		}
@@ -4075,6 +4126,16 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		i40e_enable_pf_lb(pf);
 	}
 
+	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
+	    pf->main_vsi->floating_veb == NULL) {
+		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
+
+		if (pf->main_vsi->floating_veb == NULL) {
+			PMD_DRV_LOG(ERR, "VEB setup failed");
+			return NULL;
+		}
+	}
+
 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
 	if (!vsi) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
@@ -4084,7 +4145,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 	vsi->type = type;
 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
-	vsi->parent_vsi = uplink_vsi;
+	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
 	/* Allocate queues */
 	switch (vsi->type) {
@@ -4238,7 +4299,10 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		 * For other VSI, the uplink_seid equals to uplink VSI's
 		 * uplink_seid since they share same VEB
 		 */
-		vsi->uplink_seid = uplink_vsi->uplink_seid;
+		if (uplink_vsi == NULL)
+			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
+		else
+			vsi->uplink_seid = uplink_vsi->uplink_seid;
 		ctxt.pf_num = hw->pf_id;
 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
 		ctxt.uplink_seid = vsi->uplink_seid;
@@ -4346,8 +4410,13 @@ i40e_vsi_setup(struct i40e_pf *pf,
 		vsi->seid = ctxt.seid;
 		vsi->vsi_id = ctxt.vsi_number;
 		vsi->sib_vsi_list.vsi = vsi;
-		TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
-				&vsi->sib_vsi_list, list);
+		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
+			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
+					  &vsi->sib_vsi_list, list);
+		} else {
+			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
+					  &vsi->sib_vsi_list, list);
+		}
 	}
 
 	/* MAC/VLAN configuration */
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index cfd2399..19c9dea 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -55,6 +55,8 @@
 #define I40E_VFTA_SIZE            (4096 / I40E_UINT32_BIT_SIZE)
 /* Maximun number of MAC addresses */
 #define I40E_NUM_MACADDR_MAX       64
+/* Maximum number of VFs */
+#define I40E_MAX_VF               128
 
 /*
  * vlan_id is a 12 bit number.
@@ -219,6 +221,7 @@ struct i40e_bw_info {
 struct i40e_veb {
 	struct i40e_vsi_list_head head;
 	struct i40e_vsi *associate_vsi; /* Associate VSI who owns the VEB */
+	struct i40e_pf *associate_pf; /* Associate PF who owns the VEB */
 	uint16_t seid; /* The seid of VEB itself */
 	uint16_t uplink_seid; /* The uplink seid of this VEB */
 	uint16_t stats_idx;
@@ -259,6 +262,7 @@ struct i40e_vsi {
 	struct i40e_vsi_list sib_vsi_list; /* sibling vsi list */
 	struct i40e_vsi *parent_vsi;
 	struct i40e_veb *veb;    /* Associated veb, could be null */
+	struct i40e_veb *floating_veb; /* Associated floating veb */
 	bool offset_loaded;
 	enum i40e_vsi_type type; /* VSI types */
 	uint16_t vlan_num;       /* Total VLAN number */
@@ -450,6 +454,9 @@ struct i40e_pf {
 	struct i40e_fc_conf fc_conf; /* Flow control conf */
 	struct i40e_mirror_rule_list mirror_list;
 	uint16_t nb_mirror_rule;   /* The number of mirror rules */
+	bool floating_veb; /* The flag to use the floating VEB */
+	/* The floating enable flag for the specific VF */
+	bool floating_veb_list[I40E_MAX_VF];
 };
 
 enum pending_msg {
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 5afd61a..dc5b079 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -124,6 +124,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 {
 	uint32_t val, i;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
+	struct i40e_pf *pf;
 	uint16_t vf_id, abs_vf_id, vf_msix_num;
 	int ret;
 	struct i40e_virtchnl_queue_select qsel;
@@ -131,6 +132,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	if (vf == NULL)
 		return -EINVAL;
 
+	pf = vf->pf;
 	vf_id = vf->vf_idx;
 	abs_vf_id = vf_id + hw->func_caps.vf_base_id;
 
@@ -224,8 +226,14 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
 	I40E_WRITE_FLUSH(hw);
 
 	/* Allocate resource again */
-	vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
-			vf->pf->main_vsi, vf->vf_idx);
+	if (pf->floating_veb && pf->floating_veb_list[vf_id]) {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+					 NULL, vf->vf_idx);
+	} else {
+		vf->vsi = i40e_vsi_setup(vf->pf, I40E_VSI_SRIOV,
+					 vf->pf->main_vsi, vf->vf_idx);
+	}
+
 	if (vf->vsi == NULL) {
 		PMD_DRV_LOG(ERR, "Add vsi failed");
 		return -EFAULT;
-- 
2.1.4

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

* [PATCH v15 2/2] i40e: add device args to enable a floating VEB
  2016-06-29 13:06                             ` [PATCH v15 " Zhe Tao
  2016-06-29 13:06                               ` [PATCH v15 1/2] i40e: add floating VEB support Zhe Tao
@ 2016-06-29 13:06                               ` Zhe Tao
  2016-06-29 13:47                                 ` Mcnamara, John
  1 sibling, 1 reply; 79+ messages in thread
From: Zhe Tao @ 2016-06-29 13:06 UTC (permalink / raw)
  To: dev; +Cc: zhe.tao, jingjing.wu

The standard Virtual Ethernet Bridge(VEB) definition in 1Qbg is a bridge
which has an uplink port to the outside world (maybe another bridge), but
a "floating" VEB is a special VEB without an uplink port to the outside.
Instead, traffic can be sent from one VF to another using the floating
VEB - even when the physical link on the NIC port is down.

This patch adds floating VEB options in the devargs for i40e driver.
Using these parameters, applications can decide whether to use legacy
VEB/VEPA or a floating VEB.
To enable this feature, the user should pass a devargs parameter to the
EAL, for example "-w 84:00.0,enable_floating_veb=1", to control whether
the PMD will to use the floating VEB feature or not.

Once the floating VEB feature is enabled, all the VFs created by
this PF device are connected to the floating VEB.

NOTE: The floating VEB functionality requires a NIC firmware version
of 5.0 or greater.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 doc/guides/nics/i40e.rst               |  45 ++++++++++
 doc/guides/rel_notes/release_16_07.rst |   8 ++
 drivers/net/i40e/i40e_ethdev.c         | 160 +++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.h         |   5 ++
 4 files changed, 218 insertions(+)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 934eb02..da695af 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -366,3 +366,48 @@ Delete all flow director rules on a port:
 
    testpmd> flush_flow_director 0
 
+Floating VEB
+~~~~~~~~~~~~~
+
+The Intel® Ethernet Controller X710 and XL710 Family support a feature called
+"Floating VEB".
+
+A Virtual Ethernet Bridge (VEB) is an IEEE Edge Virtual Bridging (EVB) term
+for functionality that allows local switching between virtual endpoints within
+a physical endpoint and also with an external bridge/network.
+
+A "Floating" VEB doesn't have an uplink connection to the outside world so all
+switching is done internally and remains within the host. As such, this
+feature provides security benefits.
+
+In addition, a Floating VEB overcomes a limitation of normal VEBs where they
+cannot forward packets when the physical link is down. Floating VEBs don't need
+to connect to the NIC port so they can still forward traffic from VF to VF
+even when the physical link is down.
+
+Therefore, with this feature enabled VFs can be limited to communicating with
+each other but not an outside network, and they can do so even when there is
+no physical uplink on the associated NIC port.
+
+To enable this feature, the user should pass a ``devargs`` parameter to the
+EAL, for example::
+
+    -w 84:00.0,enable_floating_veb=1
+
+In this configuration the PMD will use the floating VEB feature for all the
+VFs created by this PF device.
+
+Alternatively, the user can specify which VFs need to connect to this floating
+VEB using the ``floating_veb_list`` argument::
+
+    -w 84:00.0,enable_floating_veb=1,floating_veb_list=1;3-4
+
+In this example ``VF1``, ``VF3`` and ``VF4`` connect to the floating VEB,
+while other VFs connect to the normal VEB.
+
+The current implementation only supports one floating VEB and one regular
+VEB. VFs can connect to a floating VEB or a regular VEB according to the
+configuration passed on the EAL command line.
+
+The floating VEB functionality requires a NIC firmware version of 5.0
+or greater.
diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 54ebdc7..fc574af 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -132,6 +132,14 @@ New Features
   * A new library ``librte_pdump`` is added to provide packet capture API.
   * A new ``app/pdump`` tool is added to capture packets in DPDK.
 
+* **Added floating VEB support for i40e PF driver.**
+
+  A "floating VEB" is a special Virtual Ethernet Bridge (VEB) which does not
+  have an upload port, but instead is used for switching traffic between
+  virtual functions (VFs) on a port.
+
+  For information on this feature,  please see the "I40E Poll Mode Driver"
+  section of the "Network Interface Controller Drivers" document.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5efcbc2..9ef0727 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -63,6 +63,9 @@
 #include "i40e_pf.h"
 #include "i40e_regs.h"
 
+#define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
+#define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
+
 #define I40E_CLEAR_PXE_WAIT_MS     200
 
 /* Maximun number of capability elements */
@@ -755,6 +758,161 @@ i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
 }
 
 static int
+floating_veb_list_handler(__rte_unused const char *key,
+			  const char *floating_veb_value,
+			  void *opaque)
+{
+	int idx = 0;
+	unsigned int count = 0;
+	char *end = NULL;
+	int min, max;
+	bool *vf_floating_veb = opaque;
+
+	while (isblank(*floating_veb_value))
+		floating_veb_value++;
+
+	/* Reset floating VEB configuration for VFs */
+	for (idx = 0; idx < I40E_MAX_VF; idx++)
+		vf_floating_veb[idx] = false;
+
+	min = I40E_MAX_VF;
+	do {
+		while (isblank(*floating_veb_value))
+			floating_veb_value++;
+		if (*floating_veb_value == '\0')
+			return -1;
+		errno = 0;
+		idx = strtoul(floating_veb_value, &end, 10);
+		if (errno || end == NULL)
+			return -1;
+		while (isblank(*end))
+			end++;
+		if (*end == '-') {
+			min = idx;
+		} else if ((*end == ';') || (*end == '\0')) {
+			max = idx;
+			if (min == I40E_MAX_VF)
+				min = idx;
+			if (max >= I40E_MAX_VF)
+				max = I40E_MAX_VF - 1;
+			for (idx = min; idx <= max; idx++) {
+				vf_floating_veb[idx] = true;
+				count++;
+			}
+			min = I40E_MAX_VF;
+		} else {
+			return -1;
+		}
+		floating_veb_value = end + 1;
+	} while (*end != '\0');
+
+	if (count == 0)
+		return -1;
+
+	return 0;
+}
+
+static void
+config_vf_floating_veb(struct rte_devargs *devargs,
+		       uint16_t floating_veb,
+		       bool *vf_floating_veb)
+{
+	struct rte_kvargs *kvlist;
+	int i;
+	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
+
+	if (!floating_veb)
+		return;
+	/* All the VFs attach to the floating VEB by default
+	 * when the floating VEB is enabled.
+	 */
+	for (i = 0; i < I40E_MAX_VF; i++)
+		vf_floating_veb[i] = true;
+
+	if (devargs == NULL)
+		return;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	/* When the floating_veb_list parameter exists, all the VFs
+	 * will attach to the legacy VEB firstly, then configure VFs
+	 * to the floating VEB according to the floating_veb_list.
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_list,
+			       floating_veb_list_handler,
+			       vf_floating_veb) < 0) {
+		rte_kvargs_free(kvlist);
+		return;
+	}
+	rte_kvargs_free(kvlist);
+}
+
+static int
+i40e_check_floating_handler(__rte_unused const char *key,
+			    const char *value,
+			    __rte_unused void *opaque)
+{
+	if (strcmp(value, "1"))
+		return -1;
+
+	return 0;
+}
+
+static int
+is_floating_veb_supported(struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
+
+	if (devargs == NULL)
+		return 0;
+
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL)
+		return 0;
+
+	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	/* Floating VEB is enabled when there's key-value:
+	 * enable_floating_veb=1
+	 */
+	if (rte_kvargs_process(kvlist, floating_veb_key,
+			       i40e_check_floating_handler, NULL) < 0) {
+		rte_kvargs_free(kvlist);
+		return 0;
+	}
+	rte_kvargs_free(kvlist);
+
+	return 1;
+}
+
+static void
+config_floating_veb(struct rte_eth_dev *dev)
+{
+	struct rte_pci_device *pci_dev = dev->pci_dev;
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	memset(pf->floating_veb_list, 0, sizeof(pf->floating_veb_list));
+
+	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
+		pf->floating_veb = is_floating_veb_supported(pci_dev->devargs);
+		config_vf_floating_veb(pci_dev->devargs, pf->floating_veb,
+				       pf->floating_veb_list);
+	} else {
+		pf->floating_veb = false;
+	}
+}
+
+static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
 	struct rte_pci_device *pci_dev;
@@ -847,6 +1005,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		     ((hw->nvm.version >> 4) & 0xff),
 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
 
+	/* Need the special FW version to support floating VEB */
+	config_floating_veb(dev);
 	/* Clear PXE mode */
 	i40e_clear_pxe_mode(hw);
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 19c9dea..92c8fad 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -36,6 +36,7 @@
 
 #include <rte_eth_ctrl.h>
 #include <rte_time.h>
+#include <rte_kvargs.h>
 
 #define I40E_VLAN_TAG_SIZE        4
 
@@ -173,6 +174,10 @@ enum i40e_flxpld_layer_idx {
 #define I40E_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
 #define I40E_QUEUE_ITR_INTERVAL_MAX     8160 /* 8160 us */
 
+/* Special FW support this floating VEB feature */
+#define FLOATING_VEB_SUPPORTED_FW_MAJ 5
+#define FLOATING_VEB_SUPPORTED_FW_MIN 0
+
 struct i40e_adapter;
 
 /**
-- 
2.1.4

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

* Re: [PATCH v15 2/2] i40e: add device args to enable a floating VEB
  2016-06-29 13:06                               ` [PATCH v15 2/2] i40e: add device args to enable a floating VEB Zhe Tao
@ 2016-06-29 13:47                                 ` Mcnamara, John
  2016-06-29 14:22                                   ` Bruce Richardson
  0 siblings, 1 reply; 79+ messages in thread
From: Mcnamara, John @ 2016-06-29 13:47 UTC (permalink / raw)
  To: Tao, Zhe, dev; +Cc: Tao, Zhe, Wu, Jingjing

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
> Sent: Wednesday, June 29, 2016 2:06 PM
> To: dev@dpdk.org
> Cc: Tao, Zhe <zhe.tao@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [dpdk-dev] [PATCH v15 2/2] i40e: add device args to enable a
> floating VEB
> 
> The standard Virtual Ethernet Bridge(VEB) definition in 1Qbg is a bridge
> which has an uplink port to the outside world (maybe another bridge), but
> a "floating" VEB is a special VEB without an uplink port to the outside.
> ...
> 
> Signed-off-by: Zhe Tao <zhe.tao@intel.com>

Documentation part:

Acked-by: John McNamara <john.mcnamara@intel.com>


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

* Re: [PATCH v15 2/2] i40e: add device args to enable a floating VEB
  2016-06-29 13:47                                 ` Mcnamara, John
@ 2016-06-29 14:22                                   ` Bruce Richardson
  0 siblings, 0 replies; 79+ messages in thread
From: Bruce Richardson @ 2016-06-29 14:22 UTC (permalink / raw)
  To: Mcnamara, John; +Cc: Tao, Zhe, dev, Wu, Jingjing

On Wed, Jun 29, 2016 at 01:47:27PM +0000, Mcnamara, John wrote:
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Zhe Tao
> > Sent: Wednesday, June 29, 2016 2:06 PM
> > To: dev@dpdk.org
> > Cc: Tao, Zhe <zhe.tao@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> > Subject: [dpdk-dev] [PATCH v15 2/2] i40e: add device args to enable a
> > floating VEB
> > 
> > The standard Virtual Ethernet Bridge(VEB) definition in 1Qbg is a bridge
> > which has an uplink port to the outside world (maybe another bridge), but
> > a "floating" VEB is a special VEB without an uplink port to the outside.
> > ...
> > 
> > Signed-off-by: Zhe Tao <zhe.tao@intel.com>
> 
> Documentation part:
> 
> Acked-by: John McNamara <john.mcnamara@intel.com>
> 
Patchset applied to dpdk-next-net/rel_16_07

Thanks for the work going through so many revisions.

/Bruce

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

end of thread, other threads:[~2016-06-29 14:22 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-21  7:24 [PATCH 0/2] Add floating VEB support for i40e Zhe Tao
2016-01-21  7:24 ` PATCH 1/2] i40e: support floating VEB config Zhe Tao
2016-01-21  7:29   ` David Marchand
2016-01-21  7:53     ` Vincent JARDIN
2016-02-03  8:53   ` Xu, Qian Q
2016-02-23  9:13   ` [PATCH 0/2 v2] i40e: Add floating VEB support for i40e Zhe Tao
2016-02-23  9:13     ` [PATCH 1/2 v2] i40e: support floating VEB config Zhe Tao
2016-02-25  0:55       ` Wu, Jingjing
2016-02-23  9:13     ` [PATCH 2/2 v2] i40e: Add floating VEB support in i40e Zhe Tao
2016-02-25  1:15       ` Wu, Jingjing
2016-02-25  6:31     ` [PATCH 0/2 v3] i40e: Add floating VEB support for i40e Zhe Tao
2016-02-25  6:31       ` [PATCH 1/2 v3] i40e: support floating VEB config Zhe Tao
2016-02-25  6:31       ` [PATCH 2/2 v3] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-02  2:31         ` Xu, Qian Q
2016-03-02  8:08       ` [PATCH 0/2 v4] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-02  8:08         ` [PATCH 1/2 v4] i40e: support floating VEB config Zhe Tao
2016-03-02  8:08         ` [PATCH 2/2 v4] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-23 12:27         ` [PATCH 0/2 v5] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-23 12:27           ` [PATCH 1/2 v5] i40e: support floating VEB config Zhe Tao
2016-03-23 12:51             ` Thomas Monjalon
2016-03-24  2:31               ` Zhe Tao
2016-03-23 12:27           ` [PATCH 2/2 v5] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-24 10:48           ` [PATCH 0/2 v6] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-24 10:48             ` [PATCH 1/2 v6] i40e: support floating VEB config Zhe Tao
2016-03-24 10:48             ` [PATCH 2/2 v6] i40e: Add floating VEB support in i40e Zhe Tao
2016-03-25  8:41             ` [PATCH 0/3 v7] i40e: Add floating VEB support for i40e Zhe Tao
2016-03-25  8:41               ` [PATCH 1/3 v7] i40e: support floating VEB config Zhe Tao
2016-03-28  2:23                 ` Xu, Qian Q
2016-03-25  8:41               ` [PATCH 2/3 v7] i40e: Add floating VEB support in i40e Zhe Tao
2016-04-20  7:31                 ` Wu, Jingjing
2016-03-25  8:42               ` [PATCH 3/3 v7] i40e: Add global reset support for i40e Zhe Tao
2016-04-20 10:15                 ` Wu, Jingjing
2016-03-25 15:28               ` [PATCH 0/3 v7] i40e: Add floating VEB " Bruce Richardson
2016-04-20 14:22               ` Bruce Richardson
2016-05-24 17:28               ` [PATCH v8 0/3] " Zhe Tao
2016-05-24 17:28                 ` [PATCH v8 1/3] i40e: support floating VEB config Zhe Tao
2016-06-09 15:50                   ` Bruce Richardson
2016-05-24 17:28                 ` [PATCH v8 2/3] i40e: Add floating VEB support in i40e Zhe Tao
2016-06-09 15:55                   ` Bruce Richardson
2016-05-24 17:28                 ` [PATCH v8 3/3] i40e: add floating VEB extension support Zhe Tao
2016-05-30 15:49                   ` Peng, Yuan
2016-06-09 15:57                   ` Bruce Richardson
2016-05-24 19:22                 ` [PATCH v8 0/3] i40e: Add floating VEB support for i40e Stephen Hemminger
2016-05-25 10:05                   ` Thomas Monjalon
2016-05-31  2:25                 ` Wu, Jingjing
2016-06-13  6:45                 ` [PATCH v9 0/3] i40e: add " Zhe Tao
2016-06-13  6:45                   ` [PATCH v9 1/3] i40e: support floating VEB config Zhe Tao
2016-06-13  6:45                   ` [PATCH v9 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-13  6:45                   ` [PATCH v9 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-13  8:02                   ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Zhe Tao
2016-06-13  8:02                     ` [PATCH v10 1/3] i40e: support floating VEB config Zhe Tao
2016-06-13  8:02                     ` [PATCH v10 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-13  8:02                     ` [PATCH v10 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-14  3:38                     ` [PATCH v10 0/3] i40e: add floating VEB support for i40e Wu, Jingjing
2016-06-14  5:57                     ` [PATCH v11 " Zhe Tao
2016-06-13 21:44                       ` Zhe Tao
2016-06-14  5:57                       ` [PATCH v11 1/3] i40e: support floating VEB config Zhe Tao
2016-06-14  5:57                       ` [PATCH v11 2/3] i40e: add floating VEB support in i40e Zhe Tao
2016-06-14  5:57                       ` [PATCH v11 3/3] i40e: add floating VEB extension support Zhe Tao
2016-06-24  8:29                       ` [PATCH v12 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-24  8:29                         ` [PATCH v12 1/2] i40e: support floating VEB config Zhe Tao
2016-06-24  9:27                           ` Bruce Richardson
2016-06-24 11:14                           ` Ferruh Yigit
2016-06-26 20:28                             ` Zhe Tao
2016-06-24  8:29                         ` [PATCH v12 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27  5:12                         ` [PATCH v13 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-27  5:12                           ` [PATCH v13 1/2] i40e: support floating VEB config Zhe Tao
2016-06-27  5:12                           ` [PATCH v13 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27  7:20                           ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Zhe Tao
2016-06-27  7:20                             ` [PATCH v14 1/2] i40e: support floating VEB config Zhe Tao
2016-06-27  7:20                             ` [PATCH v14 2/2] i40e: add floating VEB support in i40e Zhe Tao
2016-06-27 13:22                             ` [PATCH v14 0/2] i40e: add floating VEB support for i40e Ferruh Yigit
2016-06-29  9:42                             ` Bruce Richardson
2016-06-29 13:06                             ` [PATCH v15 " Zhe Tao
2016-06-29 13:06                               ` [PATCH v15 1/2] i40e: add floating VEB support Zhe Tao
2016-06-29 13:06                               ` [PATCH v15 2/2] i40e: add device args to enable a floating VEB Zhe Tao
2016-06-29 13:47                                 ` Mcnamara, John
2016-06-29 14:22                                   ` Bruce Richardson
2016-01-21  7:24 ` [PATCH 2/2] i40e: Add floating VEB support in i40e Zhe Tao

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