* [dpdk-dev] [PATCH 1/7] vmxnet3: add support for VLAN filtering
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-12 18:40 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
` (6 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
VMXNET3 supports configuring filter table in host.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 107 +++++++++++++++++++++++++++++---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 2 +-
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 25 --------
3 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index ef0af16..30d0659 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -87,6 +87,12 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
struct rte_eth_stats *stats);
static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
+static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
+ uint16_t vid, int on);
+static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static void vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
+ int mask, int clear);
+
#if PROCESS_SYS_EVENTS == 1
static void vmxnet3_process_events(struct vmxnet3_hw *);
#endif
@@ -113,6 +119,8 @@ static struct eth_dev_ops vmxnet3_eth_dev_ops = {
.link_update = vmxnet3_dev_link_update,
.stats_get = vmxnet3_dev_stats_get,
.dev_infos_get = vmxnet3_dev_info_get,
+ .vlan_filter_set = vmxnet3_dev_vlan_filter_set,
+ .vlan_offload_set = vmxnet3_dev_vlan_offload_set,
.rx_queue_setup = vmxnet3_dev_rx_queue_setup,
.rx_queue_release = vmxnet3_dev_rx_queue_release,
.tx_queue_setup = vmxnet3_dev_tx_queue_setup,
@@ -371,7 +379,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
Vmxnet3_DSDevRead *devRead = &shared->devRead;
uint32_t *mac_ptr;
uint32_t val, i;
- int ret;
+ int ret, mask;
shared->magic = VMXNET3_REV1_MAGIC;
devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
@@ -442,9 +450,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
if (dev->data->dev_conf.rxmode.hw_ip_checksum)
devRead->misc.uptFeatures |= VMXNET3_F_RXCSUM;
- if (dev->data->dev_conf.rxmode.hw_vlan_strip)
- devRead->misc.uptFeatures |= VMXNET3_F_RXVLAN;
-
if (port_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
ret = vmxnet3_rss_configure(dev);
if (ret != VMXNET3_SUCCESS)
@@ -456,11 +461,14 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->rssConfDesc.confPA = hw->rss_confPA;
}
- if (dev->data->dev_conf.rxmode.hw_vlan_filter) {
- ret = vmxnet3_vlan_configure(dev);
- if (ret != VMXNET3_SUCCESS)
- return ret;
- }
+ mask = 0;
+ if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+ mask |= ETH_VLAN_STRIP_MASK;
+
+ if (dev->data->dev_conf.rxmode.hw_vlan_filter)
+ mask |= ETH_VLAN_FILTER_MASK;
+
+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 1);
PMD_INIT_LOG(DEBUG,
"Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
@@ -690,13 +698,23 @@ vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set) {
VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_RX_MODE);
}
+static void
+vmxnet3_dev_update_filters(struct vmxnet3_hw *hw)
+{
+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+}
+
/* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
static void
vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+ memset(vf_table, 0, VMXNET3_VFT_SIZE * sizeof(*vf_table));
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 1);
+ vmxnet3_dev_update_filters(hw);
}
/* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
@@ -704,8 +722,11 @@ static void
vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+ memset(vf_table, 0, VMXNET3_VFT_SIZE * sizeof(*vf_table));
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0);
+ vmxnet3_dev_update_filters(hw);
}
/* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */
@@ -726,6 +747,74 @@ vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev)
vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 0);
}
+/* Enable/disable filter on vlan */
+static int
+vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on)
+{
+ struct vmxnet3_hw *hw = dev->data->dev_private;
+ struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+
+ /* save state for restore */
+ if (on)
+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, vid);
+ else
+ VMXNET3_CLEAR_VFTABLE_ENTRY(hw->shadow_vfta, vid);
+
+ /* don't change active filter if in promiscious mode */
+ if (rxConf->rxMode & VMXNET3_RXM_PROMISC)
+ return 0;
+
+ /* set in hardware */
+ if (on)
+ VMXNET3_SET_VFTABLE_ENTRY(vf_table, vid);
+ else
+ VMXNET3_CLEAR_VFTABLE_ENTRY(vf_table, vid);
+
+ vmxnet3_dev_update_filters(hw);
+ return 0;
+}
+
+
+static void
+vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
+ int mask, int clear)
+{
+ struct vmxnet3_hw *hw = dev->data->dev_private;
+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
+ Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
+
+ if (mask & ETH_VLAN_STRIP_MASK)
+ devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
+ else
+ devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
+
+ if (mask & ETH_VLAN_FILTER_MASK) {
+ if (clear) {
+ memset(hw->shadow_vfta, 0,
+ VMXNET3_VFT_SIZE * sizeof(uint32_t));
+ /* allow untagged pkts */
+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
+ }
+ memcpy(vf_table, hw->shadow_vfta,
+ VMXNET3_VFT_SIZE * sizeof(*vf_table));
+ } else {
+ /* allow any pkts -- no filtering */
+ if (clear)
+ memset(hw->shadow_vfta, 0xff,
+ VMXNET3_VFT_SIZE * sizeof(uint32_t));
+ memset(vf_table, 0xff, VMXNET3_VFT_SIZE * sizeof(uint32_t));
+ }
+
+ vmxnet3_dev_update_filters(hw);
+}
+
+static void
+vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 0);
+}
+
#if PROCESS_SYS_EVENTS == 1
static void
vmxnet3_process_events(struct vmxnet3_hw *hw)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
index 0941cfc..2c180ad 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
@@ -115,6 +115,7 @@ struct vmxnet3_hw {
VMXNET3_RSSConf *rss_conf;
uint64_t rss_confPA;
vmxnet3_mf_table_t *mf_table;
+ uint32_t shadow_vfta[VMXNET3_VFT_SIZE];
};
#define VMXNET3_GET_ADDR_LO(reg) ((uint32_t)(reg))
@@ -167,7 +168,6 @@ int vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
int vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev);
int vmxnet3_rss_configure(struct rte_eth_dev *dev);
-int vmxnet3_vlan_configure(struct rte_eth_dev *dev);
uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 8425f32..9871f16 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -1051,28 +1051,3 @@ vmxnet3_rss_configure(struct rte_eth_dev *dev)
return VMXNET3_SUCCESS;
}
-
-/*
- * Configure VLAN Filter feature
- */
-int
-vmxnet3_vlan_configure(struct rte_eth_dev *dev)
-{
- uint8_t i;
- struct vmxnet3_hw *hw = dev->data->dev_private;
- uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
-
- PMD_INIT_FUNC_TRACE();
-
- /* Verify if this tag is already set */
- for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
- /* Filter all vlan tags out by default */
- vf_table[i] = 0;
- /* To-Do: Provide another routine in dev_ops for user config */
-
- PMD_INIT_LOG(DEBUG, "Registering VLAN portid: %"PRIu8" tag %u",
- dev->data->port_id, vf_table[i]);
- }
-
- return VMXNET3_SUCCESS;
-}
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 1/7] vmxnet3: add support for VLAN filtering
2014-12-17 5:13 ` [dpdk-dev] [PATCH 1/7] vmxnet3: add support for VLAN filtering Stephen Hemminger
@ 2015-02-12 18:40 ` Yong Wang
0 siblings, 0 replies; 17+ messages in thread
From: Yong Wang @ 2015-02-12 18:40 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>VMXNET3 supports configuring filter table in host.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 107
>+++++++++++++++++++++++++++++---
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 2 +-
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 25 --------
> 3 files changed, 99 insertions(+), 35 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>index ef0af16..30d0659 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>@@ -87,6 +87,12 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev
>*dev,
> struct rte_eth_stats *stats);
> static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
> struct rte_eth_dev_info *dev_info);
>+static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
>+ uint16_t vid, int on);
>+static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int
>mask);
>+static void vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
>+ int mask, int clear);
>+
> #if PROCESS_SYS_EVENTS == 1
> static void vmxnet3_process_events(struct vmxnet3_hw *);
> #endif
>@@ -113,6 +119,8 @@ static struct eth_dev_ops vmxnet3_eth_dev_ops = {
> .link_update = vmxnet3_dev_link_update,
> .stats_get = vmxnet3_dev_stats_get,
> .dev_infos_get = vmxnet3_dev_info_get,
>+ .vlan_filter_set = vmxnet3_dev_vlan_filter_set,
>+ .vlan_offload_set = vmxnet3_dev_vlan_offload_set,
> .rx_queue_setup = vmxnet3_dev_rx_queue_setup,
> .rx_queue_release = vmxnet3_dev_rx_queue_release,
> .tx_queue_setup = vmxnet3_dev_tx_queue_setup,
>@@ -371,7 +379,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
> Vmxnet3_DSDevRead *devRead = &shared->devRead;
> uint32_t *mac_ptr;
> uint32_t val, i;
>- int ret;
>+ int ret, mask;
>
> shared->magic = VMXNET3_REV1_MAGIC;
> devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
>@@ -442,9 +450,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
> if (dev->data->dev_conf.rxmode.hw_ip_checksum)
> devRead->misc.uptFeatures |= VMXNET3_F_RXCSUM;
>
>- if (dev->data->dev_conf.rxmode.hw_vlan_strip)
>- devRead->misc.uptFeatures |= VMXNET3_F_RXVLAN;
>-
> if (port_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) {
> ret = vmxnet3_rss_configure(dev);
> if (ret != VMXNET3_SUCCESS)
>@@ -456,11 +461,14 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
> devRead->rssConfDesc.confPA = hw->rss_confPA;
> }
>
>- if (dev->data->dev_conf.rxmode.hw_vlan_filter) {
>- ret = vmxnet3_vlan_configure(dev);
>- if (ret != VMXNET3_SUCCESS)
>- return ret;
>- }
>+ mask = 0;
>+ if (dev->data->dev_conf.rxmode.hw_vlan_strip)
>+ mask |= ETH_VLAN_STRIP_MASK;
>+
>+ if (dev->data->dev_conf.rxmode.hw_vlan_filter)
>+ mask |= ETH_VLAN_FILTER_MASK;
>+
>+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 1);
>
> PMD_INIT_LOG(DEBUG,
> "Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
>@@ -690,13 +698,23 @@ vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw,
>uint32_t feature, int set) {
> VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_RX_MODE);
> }
>
>+static void
>+vmxnet3_dev_update_filters(struct vmxnet3_hw *hw)
>+{
>+ VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
>+ VMXNET3_CMD_UPDATE_VLAN_FILTERS);
>+}
This function is not really necessary given what it does. If you prefer
to keep it, please rename it to vmxnet3_dev_update_vlan_filters to be more
precise.
>+
> /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in
>adapter */
> static void
> vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
> {
> struct vmxnet3_hw *hw = dev->data->dev_private;
>+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
>
>+ memset(vf_table, 0, VMXNET3_VFT_SIZE * sizeof(*vf_table));
> vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 1);
>+ vmxnet3_dev_update_filters(hw);
> }
>
> /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in
>adapter */
>@@ -704,8 +722,11 @@ static void
> vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
> {
> struct vmxnet3_hw *hw = dev->data->dev_private;
>+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
>
>+ memset(vf_table, 0, VMXNET3_VFT_SIZE * sizeof(*vf_table));
Rather than clearing all vlan filters, we should restore the saved filters
in shadow_vfta before promiscuous mode is enabled. This is also needed
when the device is stopped/restarted.
> vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0);
>+ vmxnet3_dev_update_filters(hw);
> }
>
> /* Allmulticast supported only if Vmxnet3_DriverShared is initialized in
>adapter */
>@@ -726,6 +747,74 @@ vmxnet3_dev_allmulticast_disable(struct rte_eth_dev
>*dev)
> vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_ALL_MULTI, 0);
> }
>
>+/* Enable/disable filter on vlan */
>+static int
>+vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int
>on)
>+{
>+ struct vmxnet3_hw *hw = dev->data->dev_private;
>+ struct Vmxnet3_RxFilterConf *rxConf = &hw->shared->devRead.rxFilterConf;
>+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
Since you already defined rxConf, vf_table can be defined as:
uint32_t *vf_table = rxConf->vfTable;
>+
>+ /* save state for restore */
>+ if (on)
>+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, vid);
>+ else
>+ VMXNET3_CLEAR_VFTABLE_ENTRY(hw->shadow_vfta, vid);
>+
>+ /* don't change active filter if in promiscious mode */
>+ if (rxConf->rxMode & VMXNET3_RXM_PROMISC)
>+ return 0;
>+
>+ /* set in hardware */
>+ if (on)
>+ VMXNET3_SET_VFTABLE_ENTRY(vf_table, vid);
>+ else
>+ VMXNET3_CLEAR_VFTABLE_ENTRY(vf_table, vid);
>+
>+ vmxnet3_dev_update_filters(hw);
>+ return 0;
>+}
>+
>+
>+static void
>+vmxnet3_dev_vlan_offload_set_clear(struct rte_eth_dev *dev,
>+ int mask, int clear)
Remove on tab here for better indention.
>+{
>+ struct vmxnet3_hw *hw = dev->data->dev_private;
>+ uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
>+ Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
devRead can be defined before vf_table and vf_table as
devRead->rxFilterConf.vfTable.
>+
>+ if (mask & ETH_VLAN_STRIP_MASK)
>+ devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
>+ else
>+ devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
There is a missing REG write after making changes to uptFeatures from
the .vlan_offload_set callback path (i.e, when “clear" is 0).
VMXNET3_WRITE_BAR1_REG(sc, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_FEATURE);
>+
>+ if (mask & ETH_VLAN_FILTER_MASK) {
>+ if (clear) {
>+ memset(hw->shadow_vfta, 0,
>+ VMXNET3_VFT_SIZE * sizeof(uint32_t));
Remove one tab here for better indention.
Instead of uint32_t, change it to sizeof(*hw->shadow_vfta) to be
consistent with the memset of vf_table.
>+ /* allow untagged pkts */
>+ VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
>+ }
>+ memcpy(vf_table, hw->shadow_vfta,
>+ VMXNET3_VFT_SIZE * sizeof(*vf_table));
>+ } else {
>+ /* allow any pkts -- no filtering */
>+ if (clear)
>+ memset(hw->shadow_vfta, 0xff,
>+ VMXNET3_VFT_SIZE * sizeof(uint32_t));
>+ memset(vf_table, 0xff, VMXNET3_VFT_SIZE * sizeof(uint32_t));
Same here.
>+ }
>+
>+ vmxnet3_dev_update_filters(hw);
>+}
>+
>+static void
>+vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
>+{
>+ vmxnet3_dev_vlan_offload_set_clear(dev, mask, 0);
>+}
>+
> #if PROCESS_SYS_EVENTS == 1
> static void
> vmxnet3_process_events(struct vmxnet3_hw *hw)
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>index 0941cfc..2c180ad 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>@@ -115,6 +115,7 @@ struct vmxnet3_hw {
> VMXNET3_RSSConf *rss_conf;
> uint64_t rss_confPA;
> vmxnet3_mf_table_t *mf_table;
>+ uint32_t shadow_vfta[VMXNET3_VFT_SIZE];
> };
>
> #define VMXNET3_GET_ADDR_LO(reg) ((uint32_t)(reg))
>@@ -167,7 +168,6 @@ int vmxnet3_dev_tx_queue_setup(struct rte_eth_dev
>*dev, uint16_t tx_queue_id,
> int vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev);
>
> int vmxnet3_rss_configure(struct rte_eth_dev *dev);
>-int vmxnet3_vlan_configure(struct rte_eth_dev *dev);
>
> uint16_t vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
> uint16_t nb_pkts);
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 8425f32..9871f16 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -1051,28 +1051,3 @@ vmxnet3_rss_configure(struct rte_eth_dev *dev)
>
> return VMXNET3_SUCCESS;
> }
>-
>-/*
>- * Configure VLAN Filter feature
>- */
>-int
>-vmxnet3_vlan_configure(struct rte_eth_dev *dev)
>-{
>- uint8_t i;
>- struct vmxnet3_hw *hw = dev->data->dev_private;
>- uint32_t *vf_table = hw->shared->devRead.rxFilterConf.vfTable;
>-
>- PMD_INIT_FUNC_TRACE();
>-
>- /* Verify if this tag is already set */
>- for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
>- /* Filter all vlan tags out by default */
>- vf_table[i] = 0;
>- /* To-Do: Provide another routine in dev_ops for user config */
>-
>- PMD_INIT_LOG(DEBUG, "Registering VLAN portid: %"PRIu8" tag %u",
>- dev->data->port_id, vf_table[i]);
>- }
>-
>- return VMXNET3_SUCCESS;
>-}
>--
>2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
2014-12-17 5:13 ` [dpdk-dev] [PATCH 1/7] vmxnet3: add support for VLAN filtering Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-11 0:54 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 3/7] vmxnet3: add support for mulit-segment transmit Stephen Hemminger
` (5 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
Remove check for packets sending packets greater than MTU. No other driver does
this, it should be handled at higher layer.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 2 --
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 1 -
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 10 ----------
3 files changed, 13 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 30d0659..4947c78 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -219,7 +219,6 @@ eth_vmxnet3_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
hw->num_rx_queues = 1;
hw->num_tx_queues = 1;
- hw->cur_mtu = ETHER_MTU;
hw->bufs_per_pkt = 1;
/* Check h/w version compatibility with driver. */
@@ -394,7 +393,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
- devRead->misc.mtu = hw->cur_mtu;
devRead->misc.numTxQueues = hw->num_tx_queues;
devRead->misc.numRxQueues = hw->num_rx_queues;
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
index 2c180ad..258fbae 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
@@ -101,7 +101,6 @@ struct vmxnet3_hw {
uint8_t num_tx_queues;
uint8_t num_rx_queues;
uint8_t bufs_per_pkt;
- uint16_t cur_mtu;
Vmxnet3_TxQueueDesc *tqd_start; /* start address of all tx queue desc */
Vmxnet3_RxQueueDesc *rqd_start; /* start address of all rx queue desc */
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 9871f16..8e15784 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -369,16 +369,6 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
continue;
}
- /* Needs to minus ether header len */
- if (txm->data_len > (hw->cur_mtu + ETHER_HDR_LEN)) {
- PMD_TX_LOG(DEBUG, "Packet data_len higher than MTU");
- rte_pktmbuf_free(tx_pkts[nb_tx]);
- txq->stats.drop_total++;
-
- nb_tx++;
- continue;
- }
-
txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base + txq->cmd_ring.next2fill);
if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
struct Vmxnet3_TxDataDesc *tdd;
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check
2014-12-17 5:13 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
@ 2015-02-11 0:54 ` Yong Wang
0 siblings, 0 replies; 17+ messages in thread
From: Yong Wang @ 2015-02-11 0:54 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>Remove check for packets sending packets greater than MTU. No other
>driver does
>this, it should be handled at higher layer.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 2 --
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 1 -
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 10 ----------
> 3 files changed, 13 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>index 30d0659..4947c78 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>@@ -219,7 +219,6 @@ eth_vmxnet3_dev_init(__attribute__((unused)) struct
>eth_driver *eth_drv,
>
> hw->num_rx_queues = 1;
> hw->num_tx_queues = 1;
>- hw->cur_mtu = ETHER_MTU;
> hw->bufs_per_pkt = 1;
>
> /* Check h/w version compatibility with driver. */
>@@ -394,7 +393,6 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
>
> devRead->misc.queueDescPA = hw->queueDescPA;
> devRead->misc.queueDescLen = hw->queue_desc_len;
>- devRead->misc.mtu = hw->cur_mtu;
> devRead->misc.numTxQueues = hw->num_tx_queues;
> devRead->misc.numRxQueues = hw->num_rx_queues;
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>index 2c180ad..258fbae 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>@@ -101,7 +101,6 @@ struct vmxnet3_hw {
> uint8_t num_tx_queues;
> uint8_t num_rx_queues;
> uint8_t bufs_per_pkt;
>- uint16_t cur_mtu;
>
> Vmxnet3_TxQueueDesc *tqd_start; /* start address of all tx queue desc
>*/
> Vmxnet3_RxQueueDesc *rqd_start; /* start address of all rx queue desc
>*/
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 9871f16..8e15784 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -369,16 +369,6 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
> continue;
> }
>
>- /* Needs to minus ether header len */
>- if (txm->data_len > (hw->cur_mtu + ETHER_HDR_LEN)) {
>- PMD_TX_LOG(DEBUG, "Packet data_len higher than MTU");
>- rte_pktmbuf_free(tx_pkts[nb_tx]);
>- txq->stats.drop_total++;
>-
>- nb_tx++;
>- continue;
>- }
>-
> txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base +
>txq->cmd_ring.next2fill);
> if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
> struct Vmxnet3_TxDataDesc *tdd;
>--
>2.1.3
>
Acked-by: Yong Wang <yongwang@vmware.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 3/7] vmxnet3: add support for mulit-segment transmit
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
2014-12-17 5:13 ` [dpdk-dev] [PATCH 1/7] vmxnet3: add support for VLAN filtering Stephen Hemminger
2014-12-17 5:13 ` [dpdk-dev] [PATCH 2/7] vmxnet3: remove mtu check Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-11 21:15 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 4/7] vmxnet3: fix link state handling Stephen Hemminger
` (4 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Bill Hong, Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
Change sending loop to support multi-segment mbufs.
The VMXNET3 api has start-of-packet and end-packet flags, so it
is not hard to send multi-segment mbuf's.
Also, update descriptor in 32 bit value rather than toggling
bitfields which is slower and error prone.
Based on code in earlier driver, and the Linux kernel driver.
Add a compiler barrier to make sure that update of earlier descriptor
are completed prior to update of generation bit on start of packet.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bill Hong <bhong@brocade.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 126 +++++++++++++---------------------
1 file changed, 48 insertions(+), 78 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 8e15784..7cb0b93 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -312,13 +312,9 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
#endif
mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
- if (unlikely(mbuf == NULL))
- rte_panic("EOP desc does not point to a valid mbuf");
- else
- rte_pktmbuf_free(mbuf);
-
-
+ rte_pktmbuf_free_seg(mbuf);
txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
+
/* Mark the txd for which tcd was generated as completed */
vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
@@ -336,13 +332,8 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts)
{
uint16_t nb_tx;
- Vmxnet3_TxDesc *txd = NULL;
- vmxnet3_buf_info_t *tbi = NULL;
- struct vmxnet3_hw *hw;
- struct rte_mbuf *txm;
vmxnet3_tx_queue_t *txq = tx_queue;
-
- hw = txq->hw;
+ struct vmxnet3_hw *hw = txq->hw;
if (unlikely(txq->stopped)) {
PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
@@ -354,75 +345,60 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
nb_tx = 0;
while (nb_tx < nb_pkts) {
+ Vmxnet3_GenericDesc *gdesc;
+ vmxnet3_buf_info_t *tbi;
+ uint32_t first2fill, avail, dw2;
+ struct rte_mbuf *txm = tx_pkts[nb_tx];
+ struct rte_mbuf *m_seg = txm;
+
+ /* Is command ring full? */
+ avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
+ if (txm->nb_segs > avail) {
+ ++txq->stats.tx_ring_full;
+ break;
+ }
- if (vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring)) {
- int copy_size = 0;
-
- txm = tx_pkts[nb_tx];
- /* Don't support scatter packets yet, free them if met */
- if (txm->nb_segs != 1) {
- PMD_TX_LOG(DEBUG, "Don't support scatter packets yet, drop!");
- rte_pktmbuf_free(tx_pkts[nb_tx]);
- txq->stats.drop_total++;
-
- nb_tx++;
- continue;
- }
-
- txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base + txq->cmd_ring.next2fill);
- if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
- struct Vmxnet3_TxDataDesc *tdd;
-
- tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
- copy_size = rte_pktmbuf_pkt_len(txm);
- rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
- }
-
- /* Fill the tx descriptor */
+ /* use the previous gen bit for the SOP desc */
+ dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
+ first2fill = txq->cmd_ring.next2fill;
+ do {
+ /* Remember the transmit buffer for cleanup */
tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
- tbi->bufPA = RTE_MBUF_DATA_DMA_ADDR(txm);
- if (copy_size)
- txd->addr = rte_cpu_to_le_64(txq->data_ring.basePA +
- txq->cmd_ring.next2fill *
- sizeof(struct Vmxnet3_TxDataDesc));
- else
- txd->addr = tbi->bufPA;
- txd->len = txm->data_len;
+ tbi->m = m_seg;
- /* Mark the last descriptor as End of Packet. */
- txd->cq = 1;
- txd->eop = 1;
+ /* NB: the following assumes that VMXNET3 maximum
+ transmit buffer size (16K) is greater than
+ maximum sizeof mbuf segment size. */
+ gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
+ gdesc->txd.addr = RTE_MBUF_DATA_DMA_ADDR(m_seg);
+ gdesc->dword[2] = dw2 | m_seg->data_len;
+ gdesc->dword[3] = 0;
- /* Add VLAN tag if requested */
- if (txm->ol_flags & PKT_TX_VLAN_PKT) {
- txd->ti = 1;
- txd->tci = rte_cpu_to_le_16(txm->vlan_tci);
- }
+ /* move to the next2fill descriptor */
+ vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
- /* Record current mbuf for freeing it later in tx complete */
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
- VMXNET3_ASSERT(txm);
-#endif
- tbi->m = txm;
+ /* use the right gen for non-SOP desc */
+ dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT;
+ } while ( (m_seg = m_seg->next) != NULL);
- /* Set the offloading mode to default */
- txd->hlen = 0;
- txd->om = VMXNET3_OM_NONE;
- txd->msscof = 0;
+ /* Update the EOP descriptor */
+ gdesc->dword[3] |= VMXNET3_TXD_EOP | VMXNET3_TXD_CQ;
- /* finally flip the GEN bit of the SOP desc */
- txd->gen = txq->cmd_ring.gen;
- txq->shared->ctrl.txNumDeferred++;
+ /* Add VLAN tag if present */
+ gdesc = txq->cmd_ring.base + first2fill;
+ if (txm->ol_flags & PKT_TX_VLAN_PKT) {
+ gdesc->txd.ti = 1;
+ gdesc->txd.tci = txm->vlan_tci;
+ }
- /* move to the next2fill descriptor */
- vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
- nb_tx++;
+ /* TODO: Add transmit checksum offload here */
- } else {
- PMD_TX_LOG(DEBUG, "No free tx cmd desc(s)");
- txq->stats.drop_total += (nb_pkts - nb_tx);
- break;
- }
+ /* flip the GEN bit on the SOP */
+ rte_compiler_barrier();
+ gdesc->dword[2] ^= VMXNET3_TXD_GEN;
+
+ txq->shared->ctrl.txNumDeferred++;
+ nb_tx++;
}
PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u", txq->shared->ctrl.txThreshold);
@@ -722,12 +698,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
PMD_INIT_FUNC_TRACE();
- if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS) !=
- ETH_TXQ_FLAGS_NOMULTSEGS) {
- PMD_INIT_LOG(ERR, "TX Multi segment not support yet");
- return -EINVAL;
- }
-
if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS) !=
ETH_TXQ_FLAGS_NOOFFLOADS) {
PMD_INIT_LOG(ERR, "TX not support offload function yet");
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 3/7] vmxnet3: add support for mulit-segment transmit
2014-12-17 5:13 ` [dpdk-dev] [PATCH 3/7] vmxnet3: add support for mulit-segment transmit Stephen Hemminger
@ 2015-02-11 21:15 ` Yong Wang
0 siblings, 0 replies; 17+ messages in thread
From: Yong Wang @ 2015-02-11 21:15 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Bill Hong, Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>Change sending loop to support multi-segment mbufs.
>The VMXNET3 api has start-of-packet and end-packet flags, so it
>is not hard to send multi-segment mbuf's.
>
>Also, update descriptor in 32 bit value rather than toggling
>bitfields which is slower and error prone.
>Based on code in earlier driver, and the Linux kernel driver.
>
>Add a compiler barrier to make sure that update of earlier descriptor
>are completed prior to update of generation bit on start of packet.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>Signed-off-by: Bill Hong <bhong@brocade.com>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 126
>+++++++++++++---------------------
> 1 file changed, 48 insertions(+), 78 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 8e15784..7cb0b93 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -312,13 +312,9 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
> VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
> #endif
> mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
>- if (unlikely(mbuf == NULL))
>- rte_panic("EOP desc does not point to a valid mbuf");
>- else
>- rte_pktmbuf_free(mbuf);
>-
>-
>+ rte_pktmbuf_free_seg(mbuf);
> txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
>+
> /* Mark the txd for which tcd was generated as completed */
> vmxnet3_cmd_ring_adv_next2comp(&txq->cmd_ring);
>
>@@ -336,13 +332,8 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
> uint16_t nb_pkts)
> {
> uint16_t nb_tx;
>- Vmxnet3_TxDesc *txd = NULL;
>- vmxnet3_buf_info_t *tbi = NULL;
>- struct vmxnet3_hw *hw;
>- struct rte_mbuf *txm;
> vmxnet3_tx_queue_t *txq = tx_queue;
>-
>- hw = txq->hw;
>+ struct vmxnet3_hw *hw = txq->hw;
>
> if (unlikely(txq->stopped)) {
> PMD_TX_LOG(DEBUG, "Tx queue is stopped.");
>@@ -354,75 +345,60 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf
>**tx_pkts,
>
> nb_tx = 0;
> while (nb_tx < nb_pkts) {
>+ Vmxnet3_GenericDesc *gdesc;
>+ vmxnet3_buf_info_t *tbi;
>+ uint32_t first2fill, avail, dw2;
>+ struct rte_mbuf *txm = tx_pkts[nb_tx];
>+ struct rte_mbuf *m_seg = txm;
>+
>+ /* Is command ring full? */
>+ avail = vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring);
>+ if (txm->nb_segs > avail) {
>+ ++txq->stats.tx_ring_full;
>+ break;
>+ }
You need to check for VMXNET3_MAX_TXD_PER_PKT as this is the max # of tx
descriptors
allowed for a non-tso pkt.
Food for thoughts: if avail is more than 0, it might be better to continue
if the next pkt could fit into the remaining descriptors, rather than break
here so all remaining pkts will be freed.
>
>- if (vmxnet3_cmd_ring_desc_avail(&txq->cmd_ring)) {
>- int copy_size = 0;
>-
>- txm = tx_pkts[nb_tx];
>- /* Don't support scatter packets yet, free them if met */
>- if (txm->nb_segs != 1) {
>- PMD_TX_LOG(DEBUG, "Don't support scatter packets yet, drop!");
>- rte_pktmbuf_free(tx_pkts[nb_tx]);
>- txq->stats.drop_total++;
>-
>- nb_tx++;
>- continue;
>- }
>-
>- txd = (Vmxnet3_TxDesc *)(txq->cmd_ring.base +
>txq->cmd_ring.next2fill);
>- if (rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
>- struct Vmxnet3_TxDataDesc *tdd;
>-
>- tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
>- copy_size = rte_pktmbuf_pkt_len(txm);
>- rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
>- }
Why do you remove this code block? It uses a special data ring for small
packets
which results in substantial performance improvement. Please refer to
commit
2e849373 for details.
Related to this, I wonder what tests have you done as that¹s not clear
from the
commit descriptions? Do we have any coverage of perf regressions?
>-
>- /* Fill the tx descriptor */
>+ /* use the previous gen bit for the SOP desc */
>+ dw2 = (txq->cmd_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
>+ first2fill = txq->cmd_ring.next2fill;
>+ do {
>+ /* Remember the transmit buffer for cleanup */
> tbi = txq->cmd_ring.buf_info + txq->cmd_ring.next2fill;
>- tbi->bufPA = RTE_MBUF_DATA_DMA_ADDR(txm);
>- if (copy_size)
>- txd->addr = rte_cpu_to_le_64(txq->data_ring.basePA +
>- txq->cmd_ring.next2fill *
>- sizeof(struct Vmxnet3_TxDataDesc));
>- else
>- txd->addr = tbi->bufPA;
>- txd->len = txm->data_len;
>+ tbi->m = m_seg;
>
>- /* Mark the last descriptor as End of Packet. */
>- txd->cq = 1;
>- txd->eop = 1;
>+ /* NB: the following assumes that VMXNET3 maximum
>+ transmit buffer size (16K) is greater than
>+ maximum sizeof mbuf segment size. */
Can you add VMXNET3_ASSERT(VMXNET3_MAX_TX_BUF_SIZE >= txd->len)?
>+ gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
>+ gdesc->txd.addr = RTE_MBUF_DATA_DMA_ADDR(m_seg);
>+ gdesc->dword[2] = dw2 | m_seg->data_len;
>+ gdesc->dword[3] = 0;
>
>- /* Add VLAN tag if requested */
>- if (txm->ol_flags & PKT_TX_VLAN_PKT) {
>- txd->ti = 1;
>- txd->tci = rte_cpu_to_le_16(txm->vlan_tci);
>- }
>+ /* move to the next2fill descriptor */
>+ vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
>
>- /* Record current mbuf for freeing it later in tx complete */
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
>- VMXNET3_ASSERT(txm);
>-#endif
>- tbi->m = txm;
>+ /* use the right gen for non-SOP desc */
>+ dw2 = txq->cmd_ring.gen << VMXNET3_TXD_GEN_SHIFT;
>+ } while ( (m_seg = m_seg->next) != NULL);
>
>- /* Set the offloading mode to default */
>- txd->hlen = 0;
>- txd->om = VMXNET3_OM_NONE;
>- txd->msscof = 0;
>+ /* Update the EOP descriptor */
>+ gdesc->dword[3] |= VMXNET3_TXD_EOP | VMXNET3_TXD_CQ;
>
>- /* finally flip the GEN bit of the SOP desc */
>- txd->gen = txq->cmd_ring.gen;
>- txq->shared->ctrl.txNumDeferred++;
>+ /* Add VLAN tag if present */
>+ gdesc = txq->cmd_ring.base + first2fill;
>+ if (txm->ol_flags & PKT_TX_VLAN_PKT) {
>+ gdesc->txd.ti = 1;
>+ gdesc->txd.tci = txm->vlan_tci;
>+ }
>
>- /* move to the next2fill descriptor */
>- vmxnet3_cmd_ring_adv_next2fill(&txq->cmd_ring);
>- nb_tx++;
>+ /* TODO: Add transmit checksum offload here */
>- } else {
>- PMD_TX_LOG(DEBUG, "No free tx cmd desc(s)");
>- txq->stats.drop_total += (nb_pkts - nb_tx);
>- break;
>- }
>+ /* flip the GEN bit on the SOP */
>+ rte_compiler_barrier();
>+ gdesc->dword[2] ^= VMXNET3_TXD_GEN;
>+
>+ txq->shared->ctrl.txNumDeferred++;
>+ nb_tx++;
> }
>
> PMD_TX_LOG(DEBUG, "vmxnet3 txThreshold: %u",
>txq->shared->ctrl.txThreshold);
>@@ -722,12 +698,6 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
>
> PMD_INIT_FUNC_TRACE();
>
>- if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS) !=
>- ETH_TXQ_FLAGS_NOMULTSEGS) {
>- PMD_INIT_LOG(ERR, "TX Multi segment not support yet");
>- return -EINVAL;
>- }
>-
> if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS) !=
> ETH_TXQ_FLAGS_NOOFFLOADS) {
> PMD_INIT_LOG(ERR, "TX not support offload function yet");
>--
>2.1.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 4/7] vmxnet3: fix link state handling
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
` (2 preceding siblings ...)
2014-12-17 5:13 ` [dpdk-dev] [PATCH 3/7] vmxnet3: add support for mulit-segment transmit Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-11 2:24 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs Stephen Hemminger
` (3 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
This patch is a bugfx.
The Intel version of VMXNET3 driver does not handle link state properly.
The VMXNET3 API returns 1 if connected and 0 if disconnected.
Also need to return correct value to indicate state change.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 53 +++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 4947c78..7afb43f 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -157,9 +157,36 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
* - On success, zero.
* - On failure, negative value.
*/
-static inline int
-rte_vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
+
+static int
+vmxnet3_dev_atomic_read_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+{
+ struct rte_eth_link *dst = link;
+ struct rte_eth_link *src = &(dev->data->dev_link);
+
+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+ *(uint64_t *)src) == 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Atomically writes the link status information into global
+ * structure rte_eth_dev.
+ *
+ * @param dev
+ * - Pointer to the structure rte_eth_dev to read from.
+ * - Pointer to the buffer to be saved with the link status.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, negative value.
+ */
+static int
+vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
{
struct rte_eth_link *dst = &(dev->data->dev_link);
struct rte_eth_link *src = link;
@@ -576,7 +603,7 @@ vmxnet3_dev_stop(struct rte_eth_dev *dev)
/* Clear recorded link status */
memset(&link, 0, sizeof(link));
- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
+ vmxnet3_dev_atomic_write_link_status(dev, &link);
}
/*
@@ -658,28 +685,24 @@ static int
vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
- struct rte_eth_link link;
+ struct rte_eth_link old, link;
uint32_t ret;
+ memset(&link, 0, sizeof(link));
+ vmxnet3_dev_atomic_read_link_status(dev, &old);
+
VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
- if (!ret) {
- PMD_INIT_LOG(ERR, "Link Status Negative : %s()", __func__);
- return -1;
- }
-
if (ret & 0x1) {
link.link_status = 1;
link.link_duplex = ETH_LINK_FULL_DUPLEX;
link.link_speed = ETH_LINK_SPEED_10000;
-
- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
-
- return 0;
}
- return -1;
+ vmxnet3_dev_atomic_write_link_status(dev, &link);
+
+ return (old.link_status == link.link_status) ? -1 : 0;
}
/* Updating rxmode through Vmxnet3_DriverShared structure in adapter */
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 4/7] vmxnet3: fix link state handling
2014-12-17 5:13 ` [dpdk-dev] [PATCH 4/7] vmxnet3: fix link state handling Stephen Hemminger
@ 2015-02-11 2:24 ` Yong Wang
0 siblings, 0 replies; 17+ messages in thread
From: Yong Wang @ 2015-02-11 2:24 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>This patch is a bugfx.
>
>The Intel version of VMXNET3 driver does not handle link state properly.
>The VMXNET3 API returns 1 if connected and 0 if disconnected.
>Also need to return correct value to indicate state change.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>---
Acked-by: Yong Wang <yongwang@vmware.com>
One nit below:
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 53
>+++++++++++++++++++++++----------
> 1 file changed, 38 insertions(+), 15 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>index 4947c78..7afb43f 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
>@@ -157,9 +157,36 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t
>size,
> * - On success, zero.
> * - On failure, negative value.
> */
>-static inline int
>-rte_vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
>- struct rte_eth_link *link)
>+
>+static int
>+vmxnet3_dev_atomic_read_link_status(struct rte_eth_dev *dev,
>+ struct rte_eth_link *link)
>+{
>+ struct rte_eth_link *dst = link;
>+ struct rte_eth_link *src = &(dev->data->dev_link);
>+
>+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
>+ *(uint64_t *)src) == 0)
>+ return -1;
>+
>+ return 0;
>+}
>+
>+/**
>+ * Atomically writes the link status information into global
>+ * structure rte_eth_dev.
>+ *
>+ * @param dev
>+ * - Pointer to the structure rte_eth_dev to read from.
"to write to" here.
>+ * - Pointer to the buffer to be saved with the link status.
>+ *
>+ * @return
>+ * - On success, zero.
>+ * - On failure, negative value.
>+ */
>+static int
>+vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
>+ struct rte_eth_link *link)
> {
> struct rte_eth_link *dst = &(dev->data->dev_link);
> struct rte_eth_link *src = link;
>@@ -576,7 +603,7 @@ vmxnet3_dev_stop(struct rte_eth_dev *dev)
>
> /* Clear recorded link status */
> memset(&link, 0, sizeof(link));
>- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
>+ vmxnet3_dev_atomic_write_link_status(dev, &link);
> }
>
> /*
>@@ -658,28 +685,24 @@ static int
> vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused))
>int wait_to_complete)
> {
> struct vmxnet3_hw *hw = dev->data->dev_private;
>- struct rte_eth_link link;
>+ struct rte_eth_link old, link;
> uint32_t ret;
>
>+ memset(&link, 0, sizeof(link));
>+ vmxnet3_dev_atomic_read_link_status(dev, &old);
>+
> VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
> ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
>
>- if (!ret) {
>- PMD_INIT_LOG(ERR, "Link Status Negative : %s()", __func__);
>- return -1;
>- }
>-
> if (ret & 0x1) {
> link.link_status = 1;
> link.link_duplex = ETH_LINK_FULL_DUPLEX;
> link.link_speed = ETH_LINK_SPEED_10000;
>-
>- rte_vmxnet3_dev_atomic_write_link_status(dev, &link);
>-
>- return 0;
> }
>
>- return -1;
>+ vmxnet3_dev_atomic_write_link_status(dev, &link);
>+
>+ return (old.link_status == link.link_status) ? -1 : 0;
> }
>
> /* Updating rxmode through Vmxnet3_DriverShared structure in adapter */
>--
>2.1.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
` (3 preceding siblings ...)
2014-12-17 5:13 ` [dpdk-dev] [PATCH 4/7] vmxnet3: fix link state handling Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-11 0:54 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
` (2 subsequent siblings)
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
By defining macro as a stub it is possible to get rid of #ifdef's
in the actual code.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 6 ++++--
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 9 +--------
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
index 258fbae..0990f59 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
@@ -35,9 +35,11 @@
#define _VMXNET3_ETHDEV_H_
#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
-#define VMXNET3_ASSERT(x) do { \
- if (!(x)) rte_panic("VMXNET3: x"); \
+#define VMXNET3_ASSERT(x) do { \
+ if (unlikely(!(x))) rte_panic("VMXNET3: %s\n", #x); \
} while(0)
+#else
+#define VMXNET3_ASSERT(x) do { (void)(x); } while (0)
#endif
#define VMXNET3_MAX_MAC_ADDRS 1
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 7cb0b93..bd47c6c 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -308,9 +308,7 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
while (tcd->gen == comp_ring->gen) {
/* Release cmd_ring descriptor and free mbuf */
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
-#endif
mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
rte_pktmbuf_free_seg(mbuf);
txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
@@ -539,16 +537,13 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
VMXNET3_ASSERT(rcd->len <= rxd->len);
VMXNET3_ASSERT(rbi->m);
-#endif
+
if (unlikely(rcd->len == 0)) {
PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
ring_idx, idx);
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
VMXNET3_ASSERT(rcd->sop && rcd->eop);
-#endif
rte_pktmbuf_free_seg(rbi->m);
goto rcd_done;
}
@@ -561,9 +556,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_free_seg(rbi->m);
goto rcd_done;
}
-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
-#endif
/* Get the packet buffer pointer from buf_info */
rxm = rbi->m;
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs
2014-12-17 5:13 ` [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs Stephen Hemminger
@ 2015-02-11 0:54 ` Yong Wang
2015-02-11 2:18 ` Stephen Hemminger
0 siblings, 1 reply; 17+ messages in thread
From: Yong Wang @ 2015-02-11 0:54 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>By defining macro as a stub it is possible to get rid of #ifdef's
>in the actual code.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>---
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 6 ++++--
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 9 +--------
> 2 files changed, 5 insertions(+), 10 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>index 258fbae..0990f59 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h
>@@ -35,9 +35,11 @@
> #define _VMXNET3_ETHDEV_H_
>
> #ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
>-#define VMXNET3_ASSERT(x) do { \
>- if (!(x)) rte_panic("VMXNET3: x"); \
>+#define VMXNET3_ASSERT(x) do { \
>+ if (unlikely(!(x))) rte_panic("VMXNET3: %s\n", #x); \
> } while(0)
>+#else
>+#define VMXNET3_ASSERT(x) do { (void)(x); } while (0)
Why not
#define VMXNET_ASSERT(x) do { (void)(0); } while (0)
or simply
#define VMXNET_ASSERT(x)
Are you expecting the condition (x) to have some side effects?
At least that¹s not the case for current usages.
> #endif
>
> #define VMXNET3_MAX_MAC_ADDRS 1
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index 7cb0b93..bd47c6c 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -308,9 +308,7 @@ vmxnet3_tq_tx_complete(vmxnet3_tx_queue_t *txq)
> while (tcd->gen == comp_ring->gen) {
>
> /* Release cmd_ring descriptor and free mbuf */
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
> VMXNET3_ASSERT(txq->cmd_ring.base[tcd->txdIdx].txd.eop == 1);
>-#endif
> mbuf = txq->cmd_ring.buf_info[tcd->txdIdx].m;
> rte_pktmbuf_free_seg(mbuf);
> txq->cmd_ring.buf_info[tcd->txdIdx].m = NULL;
>@@ -539,16 +537,13 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
>
> PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
>
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
> VMXNET3_ASSERT(rcd->len <= rxd->len);
> VMXNET3_ASSERT(rbi->m);
>-#endif
>+
> if (unlikely(rcd->len == 0)) {
> PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
> ring_idx, idx);
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
> VMXNET3_ASSERT(rcd->sop && rcd->eop);
>-#endif
> rte_pktmbuf_free_seg(rbi->m);
> goto rcd_done;
> }
>@@ -561,9 +556,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
> rte_pktmbuf_free_seg(rbi->m);
> goto rcd_done;
> }
>-#ifdef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
> VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
>-#endif
> /* Get the packet buffer pointer from buf_info */
> rxm = rbi->m;
>
>--
>2.1.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs
2015-02-11 0:54 ` Yong Wang
@ 2015-02-11 2:18 ` Stephen Hemminger
0 siblings, 0 replies; 17+ messages in thread
From: Stephen Hemminger @ 2015-02-11 2:18 UTC (permalink / raw)
To: Yong Wang; +Cc: dev, Stephen Hemminger
On Wed, 11 Feb 2015 00:54:57 +0000
Yong Wang <yongwang@vmware.com> wrote:
> Why not
> #define VMXNET_ASSERT(x) do { (void)(0); } while (0)
>
> or simply
> #define VMXNET_ASSERT(x)
Because that will generate unused warnings in Gcc,
and by having the compiler evaluate the result it also makes
sure that junk doesn't get put in.
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
` (4 preceding siblings ...)
2014-12-17 5:13 ` [dpdk-dev] [PATCH 5/7] vmxnet3: get rid of DEBUG ifdefs Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-02-11 1:28 ` Yong Wang
2014-12-17 5:13 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
2015-01-15 11:02 ` [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Thomas Monjalon
7 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Bill Hong, Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
Refactor the logic to compute receive offload flags to a simpler
function. Andd add support for putting RSS flow hash into packet.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bill Hong <bhong@brocade.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 69 ++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 29 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index bd47c6c..53ddb2c 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -488,6 +488,43 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
return i;
}
+
+/* Receive side checksum and other offloads */
+static void
+vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
+{
+ /* Check for hardware stripped VLAN tag */
+ if (rcd->ts) {
+ rxm->ol_flags |= PKT_RX_VLAN_PKT;
+ rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
+ }
+
+ /* Check for RSS */
+ if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
+ rxm->ol_flags |= PKT_RX_RSS_HASH;
+ rxm->hash.rss = rcd->rssHash;
+ }
+
+ /* Check packet type, checksum errors, etc. Only support IPv4 for now. */
+ if (rcd->v4) {
+ struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
+ struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
+
+ if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
+ rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
+ else
+ rxm->ol_flags |= PKT_RX_IPV4_HDR;
+
+ if (!rcd->cnc) {
+ if (!rcd->ipc)
+ rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
+
+ if ((rcd->tcp || rcd->udp) && !rcd->tuc)
+ rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
+ }
+ }
+}
+
/*
* Process the Rx Completion Ring of given vmxnet3_rx_queue
* for nb_pkts burst and return the number of packets received
@@ -583,17 +620,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
goto rcd_done;
}
- /* Check for hardware stripped VLAN tag */
- if (rcd->ts) {
- PMD_RX_LOG(DEBUG, "Received packet with vlan ID: %d.",
- rcd->tci);
- rxm->ol_flags = PKT_RX_VLAN_PKT;
- /* Copy vlan tag in packet buffer */
- rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
- } else {
- rxm->ol_flags = 0;
- rxm->vlan_tci = 0;
- }
/* Initialize newly received packet buffer */
rxm->port = rxq->port_id;
@@ -602,25 +628,10 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm->pkt_len = (uint16_t)rcd->len;
rxm->data_len = (uint16_t)rcd->len;
rxm->data_off = RTE_PKTMBUF_HEADROOM;
+ rxm->ol_flags = 0;
+ rxm->vlan_tci = 0;
- /* Check packet type, checksum errors, etc. Only support IPv4 for now. */
- if (rcd->v4) {
- struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
- struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
-
- if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
- rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
- else
- rxm->ol_flags |= PKT_RX_IPV4_HDR;
-
- if (!rcd->cnc) {
- if (!rcd->ipc)
- rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
-
- if ((rcd->tcp || rcd->udp) && !rcd->tuc)
- rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
- }
- }
+ vmxnet3_rx_offload(rcd, rxm);
rx_pkts[nb_rx++] = rxm;
rcd_done:
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload
2014-12-17 5:13 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
@ 2015-02-11 1:28 ` Yong Wang
0 siblings, 0 replies; 17+ messages in thread
From: Yong Wang @ 2015-02-11 1:28 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Bill Hong, Stephen Hemminger
On 12/16/14, 9:13 PM, "Stephen Hemminger" <stephen@networkplumber.org>
wrote:
>From: Stephen Hemminger <shemming@brocade.com>
>
>Refactor the logic to compute receive offload flags to a simpler
>function. Andd add support for putting RSS flow hash into packet.
>
>Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>Signed-off-by: Bill Hong <bhong@brocade.com>
>---
Acked-by: Yong Wang <yongwang@vmware.com>
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 69
>++++++++++++++++++++---------------
> 1 file changed, 40 insertions(+), 29 deletions(-)
>
>diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>index bd47c6c..53ddb2c 100644
>--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
>@@ -488,6 +488,43 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq,
>uint8_t ring_id)
> return i;
> }
>
>+
>+/* Receive side checksum and other offloads */
>+static void
>+vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
>+{
>+ /* Check for hardware stripped VLAN tag */
>+ if (rcd->ts) {
>+ rxm->ol_flags |= PKT_RX_VLAN_PKT;
>+ rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
>+ }
>+
>+ /* Check for RSS */
>+ if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE) {
>+ rxm->ol_flags |= PKT_RX_RSS_HASH;
>+ rxm->hash.rss = rcd->rssHash;
>+ }
>+
>+ /* Check packet type, checksum errors, etc. Only support IPv4 for now.
>*/
>+ if (rcd->v4) {
>+ struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
>+ struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
>+
>+ if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
>+ rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
>+ else
>+ rxm->ol_flags |= PKT_RX_IPV4_HDR;
>+
>+ if (!rcd->cnc) {
>+ if (!rcd->ipc)
>+ rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
>+
>+ if ((rcd->tcp || rcd->udp) && !rcd->tuc)
>+ rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
>+ }
>+ }
>+}
>+
> /*
> * Process the Rx Completion Ring of given vmxnet3_rx_queue
> * for nb_pkts burst and return the number of packets received
>@@ -583,17 +620,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
> goto rcd_done;
> }
>
>- /* Check for hardware stripped VLAN tag */
>- if (rcd->ts) {
>- PMD_RX_LOG(DEBUG, "Received packet with vlan ID: %d.",
>- rcd->tci);
>- rxm->ol_flags = PKT_RX_VLAN_PKT;
>- /* Copy vlan tag in packet buffer */
>- rxm->vlan_tci = rte_le_to_cpu_16((uint16_t)rcd->tci);
>- } else {
>- rxm->ol_flags = 0;
>- rxm->vlan_tci = 0;
>- }
>
> /* Initialize newly received packet buffer */
> rxm->port = rxq->port_id;
>@@ -602,25 +628,10 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf
>**rx_pkts, uint16_t nb_pkts)
> rxm->pkt_len = (uint16_t)rcd->len;
> rxm->data_len = (uint16_t)rcd->len;
> rxm->data_off = RTE_PKTMBUF_HEADROOM;
>+ rxm->ol_flags = 0;
>+ rxm->vlan_tci = 0;
>
>- /* Check packet type, checksum errors, etc. Only support IPv4 for now.
>*/
>- if (rcd->v4) {
>- struct ether_hdr *eth = rte_pktmbuf_mtod(rxm, struct ether_hdr *);
>- struct ipv4_hdr *ip = (struct ipv4_hdr *)(eth + 1);
>-
>- if (((ip->version_ihl & 0xf) << 2) > (int)sizeof(struct ipv4_hdr))
>- rxm->ol_flags |= PKT_RX_IPV4_HDR_EXT;
>- else
>- rxm->ol_flags |= PKT_RX_IPV4_HDR;
>-
>- if (!rcd->cnc) {
>- if (!rcd->ipc)
>- rxm->ol_flags |= PKT_RX_IP_CKSUM_BAD;
>-
>- if ((rcd->tcp || rcd->udp) && !rcd->tuc)
>- rxm->ol_flags |= PKT_RX_L4_CKSUM_BAD;
>- }
>- }
>+ vmxnet3_rx_offload(rcd, rxm);
>
> rx_pkts[nb_rx++] = rxm;
> rcd_done:
>--
>2.1.3
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
` (5 preceding siblings ...)
2014-12-17 5:13 ` [dpdk-dev] [PATCH 6/7] vmxnet3: support RSS and refactor offload Stephen Hemminger
@ 2014-12-17 5:13 ` Stephen Hemminger
2015-01-15 11:02 ` [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Thomas Monjalon
7 siblings, 0 replies; 17+ messages in thread
From: Stephen Hemminger @ 2014-12-17 5:13 UTC (permalink / raw)
To: dev; +Cc: Bill Hong, Stephen Hemminger
From: Stephen Hemminger <shemming@brocade.com>
Add support for linking multi-segment buffers together to
handle Jumbo packets
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bill Hong <bhong@brocade.com>
---
lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 1 +
lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 2 +
lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 81 ++++++++++++++++-----------------
3 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
index 7afb43f..bcf48f5 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c
@@ -418,6 +418,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
devRead->misc.driverInfo.vmxnet3RevSpt = 1;
devRead->misc.driverInfo.uptVerSpt = 1;
+ devRead->misc.mtu = rte_le_to_cpu_32(dev->data->mtu);
devRead->misc.queueDescPA = hw->queueDescPA;
devRead->misc.queueDescLen = hw->queue_desc_len;
devRead->misc.numTxQueues = hw->num_tx_queues;
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
index c5abdb6..ee4e970 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_ring.h
@@ -174,6 +174,8 @@ typedef struct vmxnet3_rx_queue {
uint32_t qid1;
uint32_t qid2;
Vmxnet3_RxQueueDesc *shared;
+ struct rte_mbuf *start_seg;
+ struct rte_mbuf *last_seg;
struct vmxnet3_rxq_stats stats;
bool stopped;
uint16_t queue_id; /**< Device RX queue index. */
diff --git a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
index 53ddb2c..c47ba2e 100644
--- a/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
+++ b/lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c
@@ -488,7 +488,6 @@ vmxnet3_post_rx_bufs(vmxnet3_rx_queue_t *rxq, uint8_t ring_id)
return i;
}
-
/* Receive side checksum and other offloads */
static void
vmxnet3_rx_offload(const Vmxnet3_RxCompDesc *rcd, struct rte_mbuf *rxm)
@@ -566,34 +565,11 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxd = (Vmxnet3_RxDesc *)rxq->cmd_ring[ring_idx].base + idx;
rbi = rxq->cmd_ring[ring_idx].buf_info + idx;
- if (unlikely(rcd->sop != 1 || rcd->eop != 1)) {
- rte_pktmbuf_free_seg(rbi->m);
- PMD_RX_LOG(DEBUG, "Packet spread across multiple buffers\n)");
- goto rcd_done;
- }
-
PMD_RX_LOG(DEBUG, "rxd idx: %d ring idx: %d.", idx, ring_idx);
VMXNET3_ASSERT(rcd->len <= rxd->len);
VMXNET3_ASSERT(rbi->m);
- if (unlikely(rcd->len == 0)) {
- PMD_RX_LOG(DEBUG, "Rx buf was skipped. rxring[%d][%d]\n)",
- ring_idx, idx);
- VMXNET3_ASSERT(rcd->sop && rcd->eop);
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
-
- /* Assuming a packet is coming in a single packet buffer */
- if (unlikely(rxd->btype != VMXNET3_RXD_BTYPE_HEAD)) {
- PMD_RX_LOG(DEBUG,
- "Alert : Misbehaving device, incorrect "
- " buffer type used. iPacket dropped.");
- rte_pktmbuf_free_seg(rbi->m);
- goto rcd_done;
- }
- VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
/* Get the packet buffer pointer from buf_info */
rxm = rbi->m;
@@ -605,7 +581,7 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxq->cmd_ring[ring_idx].next2comp = idx;
/* For RCD with EOP set, check if there is frame error */
- if (unlikely(rcd->err)) {
+ if (unlikely(rcd->eop && rcd->err)) {
rxq->stats.drop_total++;
rxq->stats.drop_err++;
@@ -620,7 +596,6 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
goto rcd_done;
}
-
/* Initialize newly received packet buffer */
rxm->port = rxq->port_id;
rxm->nb_segs = 1;
@@ -631,9 +606,44 @@ vmxnet3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxm->ol_flags = 0;
rxm->vlan_tci = 0;
- vmxnet3_rx_offload(rcd, rxm);
+ /*
+ * If this is the first buffer of the received packet,
+ * set the pointer to the first mbuf of the packet
+ * Otherwise, update the total length and the number of segments
+ * of the current scattered packet, and update the pointer to
+ * the last mbuf of the current packet.
+ */
+ if (rcd->sop) {
+ VMXNET3_ASSERT(!rxq->start_seg);
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_HEAD);
+
+ if (unlikely(rcd->len == 0)) {
+ PMD_RX_LOG(DEBUG,
+ "Rx buf was skipped. rxring[%d][%d])",
+ ring_idx, idx);
+ rte_pktmbuf_free_seg(rbi->m);
+ goto rcd_done;
+ }
+
+ rxq->start_seg = rxm;
+ vmxnet3_rx_offload(rcd, rxm);
+ } else {
+ struct rte_mbuf *start = rxq->start_seg;
+
+ VMXNET3_ASSERT(rxd->btype == VMXNET3_RXD_BTYPE_BODY);
+ VMXNET3_ASSERT(start != NULL);
+
+ start->pkt_len += rxm->data_len;
+ start->nb_segs++;
+
+ rxq->last_seg->next = rxm;
+ }
+ rxq->last_seg = rxm;
- rx_pkts[nb_rx++] = rxm;
+ if (rcd->eop) {
+ rx_pkts[nb_rx++] = rxq->start_seg;
+ rxq->start_seg = NULL;
+ }
rcd_done:
rxq->cmd_ring[ring_idx].next2comp = idx;
VMXNET3_INC_RING_IDX_ONLY(rxq->cmd_ring[ring_idx].next2comp, rxq->cmd_ring[ring_idx].size);
@@ -802,23 +812,9 @@ vmxnet3_dev_rx_queue_setup(struct rte_eth_dev *dev,
int size;
uint8_t i;
char mem_name[32];
- uint16_t buf_size;
- struct rte_pktmbuf_pool_private *mbp_priv;
PMD_INIT_FUNC_TRACE();
- mbp_priv = (struct rte_pktmbuf_pool_private *)
- rte_mempool_get_priv(mp);
- buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
- RTE_PKTMBUF_HEADROOM);
-
- if (dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) {
- PMD_INIT_LOG(ERR, "buf_size = %u, max_pkt_len = %u, "
- "VMXNET3 don't support scatter packets yet",
- buf_size, dev->data->dev_conf.rxmode.max_rx_pkt_len);
- return -EINVAL;
- }
-
rxq = rte_zmalloc("ethdev_rx_queue", sizeof(struct vmxnet3_rx_queue), RTE_CACHE_LINE_SIZE);
if (rxq == NULL) {
PMD_INIT_LOG(ERR, "Can not allocate rx queue structure");
@@ -937,6 +933,7 @@ vmxnet3_dev_rxtx_init(struct rte_eth_dev *dev)
}
}
rxq->stopped = FALSE;
+ rxq->start_seg = NULL;
}
for (i = 0; i < dev->data->nb_tx_queues; i++) {
--
2.1.3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements
2014-12-17 5:13 [dpdk-dev] [PATCH 0/7] vmxnet3: driver enhancements Stephen Hemminger
` (6 preceding siblings ...)
2014-12-17 5:13 ` [dpdk-dev] [PATCH 7/7] vmxnet3: support jumbo frames Stephen Hemminger
@ 2015-01-15 11:02 ` Thomas Monjalon
[not found] ` <20150121164925.10d1751c@urahara>
7 siblings, 1 reply; 17+ messages in thread
From: Thomas Monjalon @ 2015-01-15 11:02 UTC (permalink / raw)
To: dev
Someone to review these patches?
2014-12-16 21:13, Stephen Hemminger:
> This set of patches updates the vmxnet3 in the DPDK to match
> the features in the driver I wrote. The most important critical
> feature is support for multi-segment jumbo frames.
>
> Stephen Hemminger (7):
> vmxnet3: add support for VLAN filtering
> vmxnet3: remove mtu check
> vmxnet3: add support for mulit-segment transmit
> vmxnet3: fix link state handling
> vmxnet3: get rid of DEBUG ifdefs
> vmxnet3: support RSS and refactor offload
> vmxnet3: support jumbo frames
>
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.c | 163 ++++++++++++++---
> lib/librte_pmd_vmxnet3/vmxnet3_ethdev.h | 9 +-
> lib/librte_pmd_vmxnet3/vmxnet3_ring.h | 2 +
> lib/librte_pmd_vmxnet3/vmxnet3_rxtx.c | 306 +++++++++++++-------------------
> 4 files changed, 265 insertions(+), 215 deletions(-)
^ permalink raw reply [flat|nested] 17+ messages in thread