[dpdk-dev] [PATCH 3/5] i40e: support double vlan stripping and insertion

2015-06-02 Thread Zhang, Helin


> -Original Message-
> From: Olivier MATZ [mailto:olivier.matz at 6wind.com]
> Sent: Monday, June 1, 2015 4:51 PM
> To: Zhang, Helin; dev at dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 3/5] i40e: support double vlan stripping and
> insertion
> 
> Hi Helin,
> 
> On 05/26/2015 10:36 AM, Helin Zhang wrote:
> > It configures specific registers to enable double vlan stripping on RX
> > side and insertion on TX side.
> > The RX descriptors will be parsed, the vlan tags and flags will be
> > saved to corresponding mbuf fields if vlan tag is detected.
> > The TX descriptors will be configured according to the configurations
> > in mbufs, to trigger the hardware insertion of double vlan tags for
> > each packets sent out.
> >
> > Signed-off-by: Helin Zhang 
> 
> > [...]
> 
> > diff --git a/lib/librte_ether/rte_ethdev.h
> > b/lib/librte_ether/rte_ethdev.h index 16dbe00..b26670e 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -882,23 +882,25 @@ struct rte_eth_conf {
> >  /**
> >   * RX offload capabilities of a device.
> >   */
> > -#define DEV_RX_OFFLOAD_VLAN_STRIP  0x0001 -#define
> > DEV_RX_OFFLOAD_IPV4_CKSUM  0x0002
> > -#define DEV_RX_OFFLOAD_UDP_CKSUM   0x0004
> > -#define DEV_RX_OFFLOAD_TCP_CKSUM   0x0008
> > -#define DEV_RX_OFFLOAD_TCP_LRO 0x0010
> > +#define DEV_RX_OFFLOAD_VLAN_STRIP   0x0001
> > +#define DEV_RX_OFFLOAD_QINQ_STRIP   0x0002
> > +#define DEV_RX_OFFLOAD_IPV4_CKSUM   0x0004
> > +#define DEV_RX_OFFLOAD_UDP_CKSUM0x0008
> > +#define DEV_RX_OFFLOAD_TCP_CKSUM0x0010
> > +#define DEV_RX_OFFLOAD_TCP_LRO  0x0020
> >
> >  /**
> >   * TX offload capabilities of a device.
> >   */
> > -#define DEV_TX_OFFLOAD_VLAN_INSERT 0x0001 -#define
> > DEV_TX_OFFLOAD_IPV4_CKSUM  0x0002
> > -#define DEV_TX_OFFLOAD_UDP_CKSUM   0x0004
> > -#define DEV_TX_OFFLOAD_TCP_CKSUM   0x0008
> > -#define DEV_TX_OFFLOAD_SCTP_CKSUM  0x0010
> > -#define DEV_TX_OFFLOAD_TCP_TSO 0x0020
> > -#define DEV_TX_OFFLOAD_UDP_TSO 0x0040
> > -#define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x0080 /**< Used for
> > tunneling packet. */
> > +#define DEV_TX_OFFLOAD_VLAN_INSERT  0x0001
> > +#define DEV_TX_OFFLOAD_QINQ_INSERT  0x0002
> > +#define DEV_TX_OFFLOAD_IPV4_CKSUM   0x0004
> > +#define DEV_TX_OFFLOAD_UDP_CKSUM0x0008
> > +#define DEV_TX_OFFLOAD_TCP_CKSUM0x0010
> > +#define DEV_TX_OFFLOAD_SCTP_CKSUM   0x0020
> > +#define DEV_TX_OFFLOAD_TCP_TSO  0x0040
> > +#define DEV_TX_OFFLOAD_UDP_TSO  0x0080
> > +#define DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM 0x0100
> >
> >  struct rte_eth_dev_info {
> > struct rte_pci_device *pci_dev; /**< Device PCI information. */
> >
> 
> It's probably better to add the new flags after the others for ABI compat 
> reasons.
Agree, will fix it.

Thanks,
Helin

> 
> 
> Regards,
> Olivier


[dpdk-dev] [PATCH 3/5] i40e: support double vlan stripping and insertion

2015-05-26 Thread Helin Zhang
It configures specific registers to enable double vlan stripping
on RX side and insertion on TX side.
The RX descriptors will be parsed, the vlan tags and flags will be
saved to corresponding mbuf fields if vlan tag is detected.
The TX descriptors will be configured according to the
configurations in mbufs, to trigger the hardware insertion of
double vlan tags for each packets sent out.

Signed-off-by: Helin Zhang 
---
 drivers/net/i40e/i40e_ethdev.c| 52 +
 drivers/net/i40e/i40e_ethdev_vf.c |  6 +++
 drivers/net/i40e/i40e_rxtx.c  | 81 +--
 lib/librte_ether/rte_ethdev.h | 28 +++---
 4 files changed, 125 insertions(+), 42 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fb64027..e841623 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -211,6 +211,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
void *arg);
 static void i40e_configure_registers(struct i40e_hw *hw);
 static void i40e_hw_init(struct i40e_hw *hw);
+static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi);

 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -1529,11 +1530,13 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
dev_info->max_vfs = dev->pci_dev->max_vfs;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
+   DEV_RX_OFFLOAD_QINQ_STRIP |
DEV_RX_OFFLOAD_IPV4_CKSUM |
DEV_RX_OFFLOAD_UDP_CKSUM |
DEV_RX_OFFLOAD_TCP_CKSUM;
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_VLAN_INSERT |
+   DEV_TX_OFFLOAD_QINQ_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
DEV_TX_OFFLOAD_TCP_CKSUM |
@@ -3056,6 +3059,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 * macvlan filter which is expected and cannot be removed.
 */
i40e_update_default_filter_setting(vsi);
+   i40e_config_qinq(hw, vsi);
} else if (type == I40E_VSI_SRIOV) {
memset(, 0, sizeof(ctxt));
/**
@@ -3096,6 +3100,8 @@ i40e_vsi_setup(struct i40e_pf *pf,
 * Since VSI is not created yet, only configure parameter,
 * will add vsi below.
 */
+
+   i40e_config_qinq(hw, vsi);
} else if (type == I40E_VSI_VMDQ2) {
memset(, 0, sizeof(ctxt));
/*
@@ -5697,3 +5703,49 @@ i40e_configure_registers(struct i40e_hw *hw)
"0x%"PRIx32, reg_table[i].val, reg_table[i].addr);
}
 }
+
+#define I40E_VSI_TSR(_i)(0x00050800 + ((_i) * 4))
+#define I40E_VSI_TSR_QINQ_CONFIG0xc030
+#define I40E_VSI_L2TAGSTXVALID(_i)  (0x00042800 + ((_i) * 4))
+#define I40E_VSI_L2TAGSTXVALID_QINQ 0xab
+static int
+i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi)
+{
+   uint32_t reg;
+   int ret;
+
+   if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
+   PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
+   return -EINVAL;
+   }
+
+   /* Configure for double VLAN RX stripping */
+   reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
+   if ((reg & I40E_VSI_TSR_QINQ_CONFIG) != I40E_VSI_TSR_QINQ_CONFIG) {
+   reg |= I40E_VSI_TSR_QINQ_CONFIG;
+   ret = i40e_aq_debug_write_register(hw,
+  I40E_VSI_TSR(vsi->vsi_id),
+  reg, NULL);
+   if (ret < 0) {
+   PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
+   vsi->vsi_id);
+   return I40E_ERR_CONFIG;
+   }
+   }
+
+   /* Configure for double VLAN TX insertion */
+   reg = I40E_READ_REG(hw, I40E_VSI_L2TAGSTXVALID(vsi->vsi_id));
+   if ((reg & 0xff) != I40E_VSI_L2TAGSTXVALID_QINQ) {
+   reg = I40E_VSI_L2TAGSTXVALID_QINQ;
+   ret = i40e_aq_debug_write_register(hw,
+  I40E_VSI_L2TAGSTXVALID(
+  vsi->vsi_id), reg, NULL);
+   if (ret < 0) {
+   PMD_DRV_LOG(ERR, "Failed to update "
+   "VSI_L2TAGSTXVALID[%d]", vsi->vsi_id);
+   return I40E_ERR_CONFIG;
+   }
+   }
+
+   return 0;
+}
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c 
b/drivers/net/i40e/i40e_ethdev_vf.c
index 9f92a2f..1a4d088 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1643,6 +1643,12 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info