* [PATCH v3 01/33] mk/dpaa2: add the crc support to the machine type
From: Shreyansh Jain @ 2016-12-29 5:16 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, john.mcnamara, ferruh.yigit,
jerin.jacob, Hemant Agrawal
In-Reply-To: <1482988612-6638-1-git-send-email-shreyansh.jain@nxp.com>
From: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
---
mk/machine/dpaa2/rte.vars.mk | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mk/machine/dpaa2/rte.vars.mk b/mk/machine/dpaa2/rte.vars.mk
index 8541633..e4735c2 100644
--- a/mk/machine/dpaa2/rte.vars.mk
+++ b/mk/machine/dpaa2/rte.vars.mk
@@ -1,6 +1,7 @@
# BSD LICENSE
#
-# Copyright(c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+# Copyright (c) 2016 NXP. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -53,7 +54,7 @@
# CPU_CFLAGS =
# CPU_LDFLAGS =
# CPU_ASFLAGS =
-MACHINE_CFLAGS += -march=armv8-a
+MACHINE_CFLAGS += -march=armv8-a+crc
ifdef CONFIG_RTE_ARCH_ARM_TUNE
MACHINE_CFLAGS += -mcpu=$(CONFIG_RTE_ARCH_ARM_TUNE)
--
2.7.4
^ permalink raw reply related
* [PATCH v3 00/33] NXP DPAA2 PMD
From: Shreyansh Jain @ 2016-12-29 5:16 UTC (permalink / raw)
To: dev
Cc: thomas.monjalon, bruce.richardson, john.mcnamara, ferruh.yigit,
jerin.jacob, Shreyansh Jain
In-Reply-To: <1482180853-18823-1-git-send-email-hemant.agrawal@nxp.com>
** Sending v3 on behalf of Hemant Agrawal **
The patch series adds NXP’s QorIQ-Layerscape DPAA2 Architecture based
fsl-mc bus driver and network SoC PMD. This version of the driver
supports NXP LS208xA, LS204xA and LS108x families Network SoCs.
DPAA2, or Data Path Acceleration Architecture, is a hardware architecture
designed for high-speed network packet processing. It uses a bus name
‘fsl-mc’, part of Linux Kernel Staging tree [2], for resource management.
A brief description of architecture is given below; detailed description
is part of the documentation in the patches itself.
DPAA2 contains hardware component called the Management Complex (or MC).
It manages the DPAA2 hardware resources. The MC provides an object-based
abstraction for software drivers to use the DPAA2 hardware.
Some of the key objects are:
- DPNI, which refers to the network interface object.
- DPBP, which refers to HW based memory pool object
- DPIO, refers to processing context for accessing QBMAN
Besides the MC, DPAA2 also includes a Hardware based Queue and Buffer Manager
called QBMAN. Prime responsibility of QBMAN is to allow lockless access to
software/user-space to the queues and buffers implemented in the hardware.
The patch series could be logically structured into following sub-areas:
1. (Patch 0001) Enabling crc in armv8 core machine type
2. (Patch 0002) DPAA2 Architecture overview document
3. (Patch 0003) Common dpaa2 hw accelerator drivers for QBMAN.
4. (Patches 0004-0011) introduce fsl-mc bus
5. (Patches 0012-0016) introduce DPAA2 PMD, DPIO and mempool
6. (Patches 0017-0031) Support for DPAA2 Ethernet Device (ethdev)
7. (Patches 0032-0033) Additional functionality in DPAA2 ethdev.
The following design decisions are made during development:
1. DPAA2 implements a new bus called "fsl-mc" and some common accelerator
drivers.
These drivers will be shared with dpaa2 based crypto drivers.
- For this, patch series from Shreyansh [1] has been used for creating a
bus handler.
2. DPAA2 implements the HW mempool offload with DPBP object.
- The new pool is being configured using compile time option and pool name
as "dpaa2".
3. It maintains per lcore DPIO objects and affine the DPIO instance to the
processing threads accessing the QBMAN HW.
Prerequisites:
- For running the PMD, NXP's SoC (board) and SDK (software/BSP) is required.
Information about obtaining relevant software is available in the docs
as part of the patch.
- At present the series has limited support for Ethernet functions. But,
more functionality would be made available in a phased manner.
- This PMD has been validated over the Bus Model [1]
Pending Changes/Caveats:
1. VFIO code for fsl-mc bus is different than eal-vfio code for pci bus.
This need to be re-worked to make possible re-use of the existing code.
2. For the purpose of this "fsl-mc" bus, rte_dpaa2_device/rte_dpaa2_driver
might also be required but they are not part of the first patch series.
Currently, rte_device/driver are being directly used.
3. Patch for supported nics web page.
Dependencies:
[1] http://dpdk.org/ml/archives/dev/2016-December/053315.html
References:
[2] https://www.kernel.org/doc/readme/drivers-staging-fsl-mc-README.txt
[3] http://dpdk.org/ml/archives/dev/2016-October/048949.html
---
v3:
* rebased over master (eac901ce2) and patches from Shreyansh [1] for Bus Arch.
* Fixed comment from John on Patch-0003 for documentation
* Removed Patch-0001 for rte_device in rte_eth_dev; Already upstreamed through
another series
v2:
* separated the "fsl-mc" bus from the dpaa2 pmd driver - introduced drivers/bus
* separated the "dpaa2" hw mempool from dpaa2 pmd driver - introduced drivers/pool
* removed documentation warnings and missing information.
* removed arm64 part specific code from driver
* changed rte_panic to errors
* reduced checkpatch warnings
Hemant Agrawal (33):
mk/dpaa2: add the crc support to the machine type
eal/vfio: adding vfio utility functions in map file
doc: add dpaa2 nic details
drivers/common/dpaa2: adding qbman driver
bus/fslmc: introducing fsl-mc bus driver
bus/fslmc: introduce mc object functions
bus/fslmc: add mc dpni object support
bus/fslmc: add mc dpio object support
bus/fslmc: add mc dpbp object support
bus/fslmc: add mc dpseci object support
bus/fslmc: add vfio support
bus/fslmc: scan for net and sec devices
net/dpaa2: introducing NXP dpaa2 pmd driver
bus/fslmc: add debug log message support
drivers/common/dpaa2: dpio portal driver
drivers/pool/dpaa2: adding hw offloaded mempool
drivers/common/dpaa2: dpio routine to affine to crypto threads
net/dpaa2: adding eth ops to dpaa2
net/dpaa2: add rss flow distribution
net/dpaa2: configure mac address at init
net/dpaa2: attach the buffer pool to dpni
net/dpaa2: add support for l3 and l4 checksum offload
net/dpaa2: add support for promiscuous mode
net/dpaa2: add mtu config support
net/dpaa2: add packet rx and tx support
net/dpaa2: rx packet parsing and packet type support
net/dpaa2: link status update
net/dpaa2: basic stats support
net/dpaa2: enable stashing for LS2088A devices
net/dpaa2: add support for non hw buffer pool packet transmit
net/dpaa2: enabling the use of physical addresses
bus/fslmc: add support for dmamap to ARM SMMU
drivers/common/dpaa2: frame queue based dq storage alloc
MAINTAINERS | 8 +
config/common_base | 22 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 28 +-
doc/guides/nics/dpaa2.rst | 594 ++++++++
doc/guides/nics/features/dpaa2.ini | 18 +
doc/guides/nics/index.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 11 +
drivers/Makefile | 3 +
drivers/bus/Makefile | 38 +
drivers/bus/fslmc/Makefile | 75 +
drivers/bus/fslmc/fslmc_bus.c | 114 ++
drivers/bus/fslmc/fslmc_logs.h | 76 +
drivers/bus/fslmc/fslmc_vfio.c | 629 +++++++++
drivers/bus/fslmc/fslmc_vfio.h | 82 ++
drivers/bus/fslmc/mc/dpbp.c | 230 +++
drivers/bus/fslmc/mc/dpio.c | 272 ++++
drivers/bus/fslmc/mc/dpni.c | 732 ++++++++++
drivers/bus/fslmc/mc/dpseci.c | 527 +++++++
drivers/bus/fslmc/mc/fsl_dpbp.h | 220 +++
drivers/bus/fslmc/mc/fsl_dpbp_cmd.h | 76 +
drivers/bus/fslmc/mc/fsl_dpio.h | 275 ++++
drivers/bus/fslmc/mc/fsl_dpio_cmd.h | 114 ++
drivers/bus/fslmc/mc/fsl_dpkg.h | 177 +++
drivers/bus/fslmc/mc/fsl_dpni.h | 1210 ++++++++++++++++
drivers/bus/fslmc/mc/fsl_dpni_cmd.h | 327 +++++
drivers/bus/fslmc/mc/fsl_dpseci.h | 661 +++++++++
drivers/bus/fslmc/mc/fsl_dpseci_cmd.h | 248 ++++
drivers/bus/fslmc/mc/fsl_mc_cmd.h | 231 +++
drivers/bus/fslmc/mc/fsl_mc_sys.h | 98 ++
drivers/bus/fslmc/mc/fsl_net.h | 480 +++++++
drivers/bus/fslmc/mc/mc_sys.c | 107 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 137 ++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 441 ++++++
drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 70 +
drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 247 ++++
drivers/bus/fslmc/rte_fslmc.h | 119 ++
drivers/bus/fslmc/rte_pmd_fslmcbus_version.map | 62 +
drivers/common/Makefile | 45 +
drivers/common/dpaa2/Makefile | 36 +
drivers/common/dpaa2/qbman/Makefile | 58 +
drivers/common/dpaa2/qbman/include/compat.h | 405 ++++++
.../common/dpaa2/qbman/include/fsl_qbman_base.h | 157 ++
.../common/dpaa2/qbman/include/fsl_qbman_portal.h | 1090 ++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.c | 1492 ++++++++++++++++++++
drivers/common/dpaa2/qbman/qbman_portal.h | 274 ++++
drivers/common/dpaa2/qbman/qbman_private.h | 167 +++
drivers/common/dpaa2/qbman/qbman_sys.h | 380 +++++
drivers/common/dpaa2/qbman/qbman_sys_decl.h | 70 +
.../dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map | 27 +
drivers/net/Makefile | 2 +-
drivers/net/dpaa2/Makefile | 72 +
drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 344 +++++
drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h | 257 ++++
drivers/net/dpaa2/dpaa2_ethdev.c | 1057 ++++++++++++++
drivers/net/dpaa2/dpaa2_ethdev.h | 83 ++
drivers/net/dpaa2/dpaa2_rxtx.c | 421 ++++++
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 4 +
drivers/pool/Makefile | 38 +
drivers/pool/dpaa2/Makefile | 67 +
drivers/pool/dpaa2/dpaa2_hw_mempool.c | 352 +++++
drivers/pool/dpaa2/dpaa2_hw_mempool.h | 95 ++
drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map | 8 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
mk/machine/dpaa2/rte.vars.mk | 5 +-
mk/rte.app.mk | 6 +
65 files changed, 15771 insertions(+), 4 deletions(-)
create mode 100644 doc/guides/nics/dpaa2.rst
create mode 100644 doc/guides/nics/features/dpaa2.ini
create mode 100644 drivers/bus/Makefile
create mode 100644 drivers/bus/fslmc/Makefile
create mode 100644 drivers/bus/fslmc/fslmc_bus.c
create mode 100644 drivers/bus/fslmc/fslmc_logs.h
create mode 100644 drivers/bus/fslmc/fslmc_vfio.c
create mode 100644 drivers/bus/fslmc/fslmc_vfio.h
create mode 100644 drivers/bus/fslmc/mc/dpbp.c
create mode 100644 drivers/bus/fslmc/mc/dpio.c
create mode 100644 drivers/bus/fslmc/mc/dpni.c
create mode 100644 drivers/bus/fslmc/mc/dpseci.c
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpbp_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpio_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpkg.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpni_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci.h
create mode 100644 drivers/bus/fslmc/mc/fsl_dpseci_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_cmd.h
create mode 100644 drivers/bus/fslmc/mc/fsl_mc_sys.h
create mode 100644 drivers/bus/fslmc/mc/fsl_net.h
create mode 100644 drivers/bus/fslmc/mc/mc_sys.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_dpio.h
create mode 100644 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
create mode 100644 drivers/bus/fslmc/rte_fslmc.h
create mode 100644 drivers/bus/fslmc/rte_pmd_fslmcbus_version.map
create mode 100644 drivers/common/Makefile
create mode 100644 drivers/common/dpaa2/Makefile
create mode 100644 drivers/common/dpaa2/qbman/Makefile
create mode 100644 drivers/common/dpaa2/qbman/include/compat.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_base.h
create mode 100644 drivers/common/dpaa2/qbman/include/fsl_qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.c
create mode 100644 drivers/common/dpaa2/qbman/qbman_portal.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_private.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys.h
create mode 100644 drivers/common/dpaa2/qbman/qbman_sys_decl.h
create mode 100644 drivers/common/dpaa2/qbman/rte_pmd_dpaa2_qbman_version.map
create mode 100644 drivers/net/dpaa2/Makefile
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni.c
create mode 100644 drivers/net/dpaa2/base/dpaa2_hw_dpni_annot.h
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.c
create mode 100644 drivers/net/dpaa2/dpaa2_ethdev.h
create mode 100644 drivers/net/dpaa2/dpaa2_rxtx.c
create mode 100644 drivers/net/dpaa2/rte_pmd_dpaa2_version.map
create mode 100644 drivers/pool/Makefile
create mode 100644 drivers/pool/dpaa2/Makefile
create mode 100644 drivers/pool/dpaa2/dpaa2_hw_mempool.c
create mode 100644 drivers/pool/dpaa2/dpaa2_hw_mempool.h
create mode 100644 drivers/pool/dpaa2/rte_pmd_dpaa2_pool_version.map
--
2.7.4
^ permalink raw reply
* Re: [PATCH v2 01/17] net/i40e: store ethertype filter
From: Xing, Beilei @ 2016-12-29 4:36 UTC (permalink / raw)
To: Wu, Jingjing, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <9BB6961774997848B5B42BEC655768F810CC003C@SHSMSX103.ccr.corp.intel.com>
> -----Original Message-----
> From: Xing, Beilei
> Sent: Thursday, December 29, 2016 12:03 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v2 01/17] net/i40e: store ethertype filter
>
> > -----Original Message-----
> > From: Wu, Jingjing
> > Sent: Wednesday, December 28, 2016 10:22 AM
> > To: Xing, Beilei <beilei.xing@intel.com>; Zhang, Helin
> > <helin.zhang@intel.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [PATCH v2 01/17] net/i40e: store ethertype filter
> >
> > > +
> > > +/* Delete ethertype filter in SW list */ static int
> > > +i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
> > > + struct i40e_ethertype_filter *filter) {
> > > + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> > > + int ret = 0;
> > > +
> > > + ret = rte_hash_del_key(ethertype_rule->hash_table,
> > > + &filter->input);
> > > + if (ret < 0)
> > > + PMD_DRV_LOG(ERR,
> > > + "Failed to delete ethertype filter"
> > > + " to hash table %d!",
> > > + ret);
> > > + ethertype_rule->hash_map[ret] = NULL;
> > > +
> > > + TAILQ_REMOVE(ðertype_rule->ethertype_list, filter, rules);
> > > + rte_free(filter);
> >
> > It's better to free filter out of del function because the filter is
> > also the input argument.
> > Or you can define this function to use key as argument but not filter.
>
> Thanks for the suggestion, I'll use the key as parameter in the next version.
>
> >
> > > /*
> > > * Configure ethertype filter, which can director packet by filtering
> > > * with mac address and ether_type or only ether_type @@ -7964,6
> > > +8099,8 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> > > bool add)
> > > {
> > > struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> > > + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> > > + struct i40e_ethertype_filter *ethertype_filter, *node;
> > > struct i40e_control_filter_stats stats;
> > > uint16_t flags = 0;
> > > int ret;
> > > @@ -7982,6 +8119,22 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> > > PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag
> > is"
> > > " not supported.");
> > >
> > > + /* Check if there is the filter in SW list */
> > > + ethertype_filter = rte_zmalloc("ethertype_filter",
> > > + sizeof(*ethertype_filter), 0);
> > > + i40e_ethertype_filter_convert(filter, ethertype_filter);
> > > + node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
> > > + ðertype_filter->input);
> > > + if (add && node) {
> > > + PMD_DRV_LOG(ERR, "Conflict with existing ethertype
> > rules!");
> > > + rte_free(ethertype_filter);
> > > + return -EINVAL;
> > > + } else if (!add && !node) {
> > > + PMD_DRV_LOG(ERR, "There's no corresponding ethertype
> > > filter!");
> > > + rte_free(ethertype_filter);
> > > + return -EINVAL;
> > > + }
> > How about malloc ethertype_filter after check? Especially, no need to
> > malloc it when delete a filter.
>
> Malloc ethertype_filter because i40e_ethertype_filter_convert is involved
> first, and then check if a rule exists with ethertype_filter->input.
Sorry, you are right. In fact I needn't to malloc before convert. Will update it in next version.
>
> >
> > Thanks
> > Jingjing
^ permalink raw reply
* Re: [PATCH v2 01/17] net/i40e: store ethertype filter
From: Xing, Beilei @ 2016-12-29 4:03 UTC (permalink / raw)
To: Wu, Jingjing, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <9BB6961774997848B5B42BEC655768F810CC003C@SHSMSX103.ccr.corp.intel.com>
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, December 28, 2016 10:22 AM
> To: Xing, Beilei <beilei.xing@intel.com>; Zhang, Helin
> <helin.zhang@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v2 01/17] net/i40e: store ethertype filter
>
> > +
> > +/* Delete ethertype filter in SW list */ static int
> > +i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
> > + struct i40e_ethertype_filter *filter) {
> > + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> > + int ret = 0;
> > +
> > + ret = rte_hash_del_key(ethertype_rule->hash_table,
> > + &filter->input);
> > + if (ret < 0)
> > + PMD_DRV_LOG(ERR,
> > + "Failed to delete ethertype filter"
> > + " to hash table %d!",
> > + ret);
> > + ethertype_rule->hash_map[ret] = NULL;
> > +
> > + TAILQ_REMOVE(ðertype_rule->ethertype_list, filter, rules);
> > + rte_free(filter);
>
> It's better to free filter out of del function because the filter is also the input
> argument.
> Or you can define this function to use key as argument but not filter.
Thanks for the suggestion, I'll use the key as parameter in the next version.
>
> > /*
> > * Configure ethertype filter, which can director packet by filtering
> > * with mac address and ether_type or only ether_type @@ -7964,6
> > +8099,8 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> > bool add)
> > {
> > struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> > + struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
> > + struct i40e_ethertype_filter *ethertype_filter, *node;
> > struct i40e_control_filter_stats stats;
> > uint16_t flags = 0;
> > int ret;
> > @@ -7982,6 +8119,22 @@ i40e_ethertype_filter_set(struct i40e_pf *pf,
> > PMD_DRV_LOG(WARNING, "filter vlan ether_type in first tag
> is"
> > " not supported.");
> >
> > + /* Check if there is the filter in SW list */
> > + ethertype_filter = rte_zmalloc("ethertype_filter",
> > + sizeof(*ethertype_filter), 0);
> > + i40e_ethertype_filter_convert(filter, ethertype_filter);
> > + node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
> > + ðertype_filter->input);
> > + if (add && node) {
> > + PMD_DRV_LOG(ERR, "Conflict with existing ethertype
> rules!");
> > + rte_free(ethertype_filter);
> > + return -EINVAL;
> > + } else if (!add && !node) {
> > + PMD_DRV_LOG(ERR, "There's no corresponding ethertype
> > filter!");
> > + rte_free(ethertype_filter);
> > + return -EINVAL;
> > + }
> How about malloc ethertype_filter after check? Especially, no need to malloc
> it when delete a filter.
Malloc ethertype_filter because i40e_ethertype_filter_convert is involved first, and then check if a rule exists with ethertype_filter->input.
>
> Thanks
> Jingjing
^ permalink raw reply
* [PATCH 2/2] vhost: start vhost servers once
From: Charles (Chas) Williams @ 2016-12-28 21:10 UTC (permalink / raw)
To: dev; +Cc: mtetsuyah, yuanhan.liu, Charles (Chas) Williams
In-Reply-To: <1482959452-18486-1-git-send-email-ciwillia@brocade.com>
Start a vhost server once during devinit instead of during device start
and stop. Some vhost clients, QEMU, don't re-attaching to sockets when
the vhost server is stopped and later started. Preserve existing behavior
for vhost clients.
Fixes: ee584e9710b9 ("vhost: add driver on top of the library")
Signed-off-by: Chas Williams <ciwillia@brocade.com>
---
drivers/net/vhost/rte_eth_vhost.c | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index ba559ff..914d83f 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -772,9 +772,8 @@ vhost_driver_session_stop(void)
}
static int
-eth_dev_start(struct rte_eth_dev *dev)
+vhost_dev_start(struct pmd_internal *internal)
{
- struct pmd_internal *internal = dev->data->dev_private;
int ret = 0;
if (rte_atomic16_cmpset(&internal->once, 0, 1)) {
@@ -792,10 +791,8 @@ eth_dev_start(struct rte_eth_dev *dev)
}
static void
-eth_dev_stop(struct rte_eth_dev *dev)
+vhost_dev_stop(struct pmd_internal *internal)
{
- struct pmd_internal *internal = dev->data->dev_private;
-
if (rte_atomic16_cmpset(&internal->once, 1, 0)) {
rte_vhost_driver_unregister(internal->iface_name);
@@ -805,6 +802,27 @@ eth_dev_stop(struct rte_eth_dev *dev)
}
static int
+eth_dev_start(struct rte_eth_dev *dev)
+{
+ struct pmd_internal *internal = dev->data->dev_private;
+ int ret = 0;
+
+ if (internal->flags & RTE_VHOST_USER_CLIENT)
+ ret = vhost_dev_start(internal);
+
+ return ret;
+}
+
+static void
+eth_dev_stop(struct rte_eth_dev *dev)
+{
+ struct pmd_internal *internal = dev->data->dev_private;
+
+ if (internal->flags & RTE_VHOST_USER_CLIENT)
+ vhost_dev_stop(internal);
+}
+
+static int
eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
uint16_t nb_rx_desc __rte_unused,
unsigned int socket_id,
@@ -1079,6 +1097,11 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
eth_dev->rx_pkt_burst = eth_vhost_rx;
eth_dev->tx_pkt_burst = eth_vhost_tx;
+ if ((flags & RTE_VHOST_USER_CLIENT) == 0) {
+ if (vhost_dev_start(internal))
+ goto error;
+ }
+
return data->port_id;
error:
@@ -1216,6 +1239,9 @@ rte_pmd_vhost_remove(const char *name)
eth_dev_stop(eth_dev);
+ if ((internal->flags & RTE_VHOST_USER_CLIENT) == 0)
+ vhost_dev_stop(internal);
+
rte_free(vring_states[eth_dev->data->port_id]);
vring_states[eth_dev->data->port_id] = NULL;
--
2.1.4
^ permalink raw reply related
* [PATCH 1/2] vhost: reference count fix for nb_started_ports
From: Charles (Chas) Williams @ 2016-12-28 21:10 UTC (permalink / raw)
To: dev; +Cc: mtetsuyah, yuanhan.liu, Wen Chiu
From: Wen Chiu <wchiu@brocade.com>
Only increment and decrement nb_started_ports on the first and last
device start and stop. Otherwise, nb_started_ports can become negative
if a device is stopped multiple times.
Fixes: ee584e9710b9 ("vhost: add driver on top of the library")
Signed-off-by: Wen Chiu <wchiu@brocade.com>
Reviewed-by: Chas Williams <ciwillia@brocade.com>
---
drivers/net/vhost/rte_eth_vhost.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 60b0f51..ba559ff 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -782,11 +782,11 @@ eth_dev_start(struct rte_eth_dev *dev)
internal->flags);
if (ret)
return ret;
- }
- /* We need only one message handling thread */
- if (rte_atomic16_add_return(&nb_started_ports, 1) == 1)
- ret = vhost_driver_session_start();
+ /* We need only one message handling thread */
+ if (rte_atomic16_add_return(&nb_started_ports, 1) == 1)
+ ret = vhost_driver_session_start();
+ }
return ret;
}
@@ -796,11 +796,12 @@ eth_dev_stop(struct rte_eth_dev *dev)
{
struct pmd_internal *internal = dev->data->dev_private;
- if (rte_atomic16_cmpset(&internal->once, 1, 0))
+ if (rte_atomic16_cmpset(&internal->once, 1, 0)) {
rte_vhost_driver_unregister(internal->iface_name);
- if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
- vhost_driver_session_stop();
+ if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
+ vhost_driver_session_stop();
+ }
}
static int
--
2.1.4
^ permalink raw reply related
* [PATCH v2] examples/ip_pipeline: fix coremask limitation
From: Sankar Chokkalingam @ 2016-12-28 12:01 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
In-Reply-To: <1482502618-1446-1>
v2: Fixed coding style errors.
v1:
Issue:
coremask used in IP Pipeline is limited to 64 cores.
Solution:
Modified coremask as an array of uint64_t to support RTE_MAX_LCORE
Fixes: 7f64b9c004aa ("examples/ip_pipeline: rework config file syntax")
Fixes: eb32fe7c5574 ("examples/ip_pipeline: rework initialization parameters")
Fixes: b4aee0fb9c6d ("examples/ip_pipeline: reconfigure thread binding dynamically")
Fixes: 4e14069328fc ("examples/ip_pipeline: measure CPU utilization")
Signed-off-by: Sankar Chokkalingam <sankarx.chokkalingam@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
examples/ip_pipeline/app.h | 35 ++++++++++++++++++++++++++++++++++-
examples/ip_pipeline/init.c | 15 ++++++++++-----
examples/ip_pipeline/thread_fe.c | 9 +++------
3 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index f8b84e0..e41290e 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -491,6 +491,9 @@ struct app_eal_params {
#define APP_THREAD_HEADROOM_STATS_COLLECT 1
#endif
+#define APP_CORE_MASK_SIZE \
+ (RTE_MAX_LCORE / 64 + ((RTE_MAX_LCORE % 64) ? 1 : 0))
+
struct app_params {
/* Config */
char app_name[APP_APPNAME_SIZE];
@@ -533,7 +536,7 @@ struct app_params {
/* Init */
char *eal_argv[1 + APP_EAL_ARGC];
struct cpu_core_map *core_map;
- uint64_t core_mask;
+ uint64_t core_mask[APP_CORE_MASK_SIZE];
struct rte_mempool *mempool[APP_MAX_MEMPOOLS];
struct app_link_data link_data[APP_MAX_LINKS];
struct rte_ring *swq[APP_MAX_PKTQ_SWQ];
@@ -1359,6 +1362,36 @@ app_get_link_for_kni(struct app_params *app, struct app_pktq_kni_params *p_kni)
return &app->link_params[link_param_idx];
}
+static inline uint32_t
+app_core_is_enabled(struct app_params *app, uint32_t lcore_id)
+{
+ return(app->core_mask[lcore_id / 64] &
+ (1LLU << (lcore_id % 64)));
+}
+
+static inline void
+app_core_enable_in_core_mask(struct app_params *app, int lcore_id)
+{
+ app->core_mask[lcore_id / 64] |= 1LLU << (lcore_id % 64);
+
+}
+
+static inline void
+app_core_build_core_mask_string(struct app_params *app, char *mask_buffer)
+{
+ int i;
+
+ mask_buffer[0] = '\0';
+ for (i = (int)RTE_DIM(app->core_mask); i > 0; i--) {
+ /* For Hex representation of bits in uint64_t */
+ char buffer[(64 / 8) * 2 + 1];
+ memset(buffer, 0, sizeof(buffer));
+ snprintf(buffer, sizeof(buffer), "%016" PRIx64,
+ app->core_mask[i-1]);
+ strcat(mask_buffer, buffer);
+ }
+}
+
void app_pipeline_params_get(struct app_params *app,
struct app_pipeline_params *p_in,
struct pipeline_params *p_out);
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 3b36b53..d46bd36 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -78,11 +78,14 @@ app_init_core_map(struct app_params *app)
cpu_core_map_print(app->core_map);
}
+/* Core Mask String in Hex Representation */
+#define APP_CORE_MASK_STRING_SIZE ((64 * APP_CORE_MASK_SIZE) / 8 * 2 + 1)
+
static void
app_init_core_mask(struct app_params *app)
{
- uint64_t mask = 0;
uint32_t i;
+ char core_mask_str[APP_CORE_MASK_STRING_SIZE];
for (i = 0; i < app->n_pipelines; i++) {
struct app_pipeline_params *p = &app->pipeline_params[i];
@@ -96,17 +99,18 @@ app_init_core_mask(struct app_params *app)
if (lcore_id < 0)
rte_panic("Cannot create CPU core mask\n");
- mask |= 1LLU << lcore_id;
+ app_core_enable_in_core_mask(app, lcore_id);
}
- app->core_mask = mask;
- APP_LOG(app, HIGH, "CPU core mask = 0x%016" PRIx64, app->core_mask);
+ app_core_build_core_mask_string(app, core_mask_str);
+ APP_LOG(app, HIGH, "CPU core mask = 0x%s", core_mask_str);
}
static void
app_init_eal(struct app_params *app)
{
char buffer[256];
+ char core_mask_str[APP_CORE_MASK_STRING_SIZE];
struct app_eal_params *p = &app->eal_params;
uint32_t n_args = 0;
uint32_t i;
@@ -114,7 +118,8 @@ app_init_eal(struct app_params *app)
app->eal_argv[n_args++] = strdup(app->app_name);
- snprintf(buffer, sizeof(buffer), "-c%" PRIx64, app->core_mask);
+ app_core_build_core_mask_string(app, core_mask_str);
+ snprintf(buffer, sizeof(buffer), "-c%s", core_mask_str);
app->eal_argv[n_args++] = strdup(buffer);
if (p->coremap) {
diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
index 6c547ca..4590c2b 100644
--- a/examples/ip_pipeline/thread_fe.c
+++ b/examples/ip_pipeline/thread_fe.c
@@ -70,8 +70,7 @@ app_pipeline_enable(struct app_params *app,
core_id,
hyper_th_id);
- if ((thread_id < 0) ||
- ((app->core_mask & (1LLU << thread_id)) == 0))
+ if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
return -1;
if (app_pipeline_data(app, pipeline_id) == NULL)
@@ -134,8 +133,7 @@ app_pipeline_disable(struct app_params *app,
core_id,
hyper_th_id);
- if ((thread_id < 0) ||
- ((app->core_mask & (1LLU << thread_id)) == 0))
+ if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
return -1;
if (app_pipeline_data(app, pipeline_id) == NULL)
@@ -188,8 +186,7 @@ app_thread_headroom(struct app_params *app,
core_id,
hyper_th_id);
- if ((thread_id < 0) ||
- ((app->core_mask & (1LLU << thread_id)) == 0))
+ if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
return -1;
req = app_msg_alloc(app);
--
2.5.5
^ permalink raw reply related
* Re: [PATCH] examples/ip_pipeline: fix load balancing function in pass-through pipeline
From: Dumitrescu, Cristian @ 2016-12-28 18:49 UTC (permalink / raw)
To: Singh, Jasvinder, dev@dpdk.org
In-Reply-To: <1479735457-147785-1-git-send-email-jasvinder.singh@intel.com>
> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Monday, November 21, 2016 1:38 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Subject: [PATCH] examples/ip_pipeline: fix load balancing function in pass-
> through pipeline
>
> This patch fixes the configuration file parsing error when load balancing
> function is enabled in pass-through pipeline.
>
> error log:
> pipeline> [APP] Initializing PIPELINE1 ...
> [PIPELINE1] Pass-through
> Parse error in section "PIPELINE1": entry "lb" has invalid value ("hash")
>
> Fixes: cbe82f6cfb0a ("examples/ip_pipeline: add swap action in pass-
> through")
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> ---
> examples/ip_pipeline/pipeline/pipeline_passthrough_be.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
^ permalink raw reply
* [PATCH v4 7/7] doc: update the release notes for the reserved flags
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Add information about the reserved flags for PMD-specific API in
the release note.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
doc/guides/rel_notes/release_17_02.rst | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 34dba45..af71f39 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -58,6 +58,18 @@ New Features
MACsec offload support. The declarations of the APIs and the definitions
of the flags can be found in ``rte_pmd_ixgbe.h``.
+* **Reserved flags for PMD to implement the PMD-specific API.**
+
+ Following flags in mbuf and ethdev are reserved for PMD to define its
+ own flags when implementing the PMD-specific API.
+
+ * DEV_RX_OFFLOAD_RESERVED_0
+ * DEV_TX_OFFLOAD_RESERVED_0
+ * RTE_ETH_EVENT_RESERVED_0
+ * PKT_TX_RESERVED_0
+
+ You can refer to ``rte_pmd_ixgbe.h`` for an example.
+
Resolved Issues
---------------
--
2.7.4
^ permalink raw reply related
* [PATCH v4 6/7] doc: add ixgbe specific APIs
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Add information about the new ixgbe PMD APIs in the release note.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
doc/guides/rel_notes/release_17_02.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 180af82..34dba45 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -52,6 +52,12 @@ New Features
See the :ref:`Generic flow API <Generic_flow_API>` documentation for more
information.
+* **Added APIs for MACsec offload support to the ixgbe PMD.**
+
+ Six new APIs and some related flags have been added to the ixgbe PMD for
+ MACsec offload support. The declarations of the APIs and the definitions
+ of the flags can be found in ``rte_pmd_ixgbe.h``.
+
Resolved Issues
---------------
--
2.7.4
^ permalink raw reply related
* [PATCH v4 5/7] app/testpmd: add MACsec offload commands
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Below MACsec offload commands are added:
- set macsec offload <port_id> on encrypt on|off replay-protect on|off
- set macsec offload <port_id> off
- set macsec sc tx|rx <port_id> <mac> <pi>
- set macsec sa tx|rx <port_id> <idx> <an> <pn> <key>
Also update the testpmd user guide.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
app/test-pmd/cmdline.c | 389 ++++++++++++++++++++++++++++
app/test-pmd/macfwd.c | 7 +
app/test-pmd/macswap.c | 7 +
app/test-pmd/testpmd.h | 2 +
app/test-pmd/txonly.c | 7 +
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 32 +++
6 files changed, 444 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f768b6b..4a67894 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -275,6 +275,18 @@ static void cmd_help_long_parsed(void *parsed_result,
"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
" Set MAC antispoof for a VF from the PF.\n\n"
+
+ "set macsec offload (port_id) on encrypt (on|off) replay-protect (on|off)\n"
+ " Enable MACsec offload.\n\n"
+
+ "set macsec offload (port_id) off\n"
+ " Disable MACsec offload.\n\n"
+
+ "set macsec sc (tx|rx) (port_id) (mac) (pi)\n"
+ " Configure MACsec secure connection (SC).\n\n"
+
+ "set macsec sa (tx|rx) (port_id) (idx) (an) (pn) (key)\n"
+ " Configure MACsec secure association (SA).\n\n"
#endif
"vlan set strip (on|off) (port_id)\n"
@@ -11488,6 +11500,379 @@ cmdline_parse_inst_t cmd_set_vf_mac_addr = {
NULL,
},
};
+
+/* MACsec configuration */
+
+/* Common result structure for MACsec offload enable */
+struct cmd_macsec_offload_on_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t macsec;
+ cmdline_fixed_string_t offload;
+ uint8_t port_id;
+ cmdline_fixed_string_t on;
+ cmdline_fixed_string_t encrypt;
+ cmdline_fixed_string_t en_on_off;
+ cmdline_fixed_string_t replay_protect;
+ cmdline_fixed_string_t rp_on_off;
+};
+
+/* Common CLI fields for MACsec offload disable */
+cmdline_parse_token_string_t cmd_macsec_offload_on_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_macsec_offload_on_macsec =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_offload_on_offload =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ offload, "offload");
+cmdline_parse_token_string_t cmd_macsec_offload_on_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_macsec_offload_on_on =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ on, "on");
+cmdline_parse_token_string_t cmd_macsec_offload_on_encrypt =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ encrypt, "encrypt");
+cmdline_parse_token_string_t cmd_macsec_offload_on_en_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ en_on_off, "on#off");
+cmdline_parse_token_string_t cmd_macsec_offload_on_replay_protect =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ replay_protect, "replay-protect");
+cmdline_parse_token_string_t cmd_macsec_offload_on_rp_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_on_result,
+ rp_on_off, "on#off");
+
+static void
+cmd_set_macsec_offload_on_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_macsec_offload_on_result *res = parsed_result;
+ int ret;
+ portid_t port_id = res->port_id;
+ int en = (strcmp(res->en_on_off, "on") == 0) ? 1 : 0;
+ int rp = (strcmp(res->rp_on_off, "on") == 0) ? 1 : 0;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_MACSEC;
+ ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", port_id);
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_offload_on = {
+ .f = cmd_set_macsec_offload_on_parsed,
+ .data = NULL,
+ .help_str = "set macsec offload <port_id> on "
+ "encrypt on|off replay-protect on|off",
+ .tokens = {
+ (void *)&cmd_macsec_offload_on_set,
+ (void *)&cmd_macsec_offload_on_macsec,
+ (void *)&cmd_macsec_offload_on_offload,
+ (void *)&cmd_macsec_offload_on_port_id,
+ (void *)&cmd_macsec_offload_on_on,
+ (void *)&cmd_macsec_offload_on_encrypt,
+ (void *)&cmd_macsec_offload_on_en_on_off,
+ (void *)&cmd_macsec_offload_on_replay_protect,
+ (void *)&cmd_macsec_offload_on_rp_on_off,
+ NULL,
+ },
+};
+
+/* Common result structure for MACsec offload disable */
+struct cmd_macsec_offload_off_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t macsec;
+ cmdline_fixed_string_t offload;
+ uint8_t port_id;
+ cmdline_fixed_string_t off;
+};
+
+/* Common CLI fields for MACsec offload disable */
+cmdline_parse_token_string_t cmd_macsec_offload_off_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_off_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_macsec_offload_off_macsec =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_off_result,
+ macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_offload_off_offload =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_off_result,
+ offload, "offload");
+cmdline_parse_token_string_t cmd_macsec_offload_off_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_offload_off_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_macsec_offload_off_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_offload_off_result,
+ off, "off");
+
+static void
+cmd_set_macsec_offload_off_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_macsec_offload_off_result *res = parsed_result;
+ int ret;
+ portid_t port_id = res->port_id;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_MACSEC;
+ ret = rte_pmd_ixgbe_macsec_disable(port_id);
+
+ switch (ret) {
+ case 0:
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", port_id);
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_offload_off = {
+ .f = cmd_set_macsec_offload_off_parsed,
+ .data = NULL,
+ .help_str = "set macsec offload <port_id> off",
+ .tokens = {
+ (void *)&cmd_macsec_offload_off_set,
+ (void *)&cmd_macsec_offload_off_macsec,
+ (void *)&cmd_macsec_offload_off_offload,
+ (void *)&cmd_macsec_offload_off_port_id,
+ (void *)&cmd_macsec_offload_off_off,
+ NULL,
+ },
+};
+
+/* Common result structure for MACsec secure connection configure */
+struct cmd_macsec_sc_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t macsec;
+ cmdline_fixed_string_t sc;
+ cmdline_fixed_string_t tx_rx;
+ uint8_t port_id;
+ struct ether_addr mac;
+ uint16_t pi;
+};
+
+/* Common CLI fields for MACsec secure connection configure */
+cmdline_parse_token_string_t cmd_macsec_sc_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_macsec_sc_macsec =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_sc_sc =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ sc, "sc");
+cmdline_parse_token_string_t cmd_macsec_sc_tx_rx =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ tx_rx, "tx#rx");
+cmdline_parse_token_num_t cmd_macsec_sc_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ port_id, UINT8);
+cmdline_parse_token_etheraddr_t cmd_macsec_sc_mac =
+ TOKEN_ETHERADDR_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ mac);
+cmdline_parse_token_num_t cmd_macsec_sc_pi =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sc_result,
+ pi, UINT16);
+
+static void
+cmd_set_macsec_sc_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_macsec_sc_result *res = parsed_result;
+ int ret;
+ int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0;
+
+ ret = is_tx ?
+ rte_pmd_ixgbe_macsec_config_txsc(res->port_id,
+ res->mac.addr_bytes) :
+ rte_pmd_ixgbe_macsec_config_rxsc(res->port_id,
+ res->mac.addr_bytes, res->pi);
+ switch (ret) {
+ case 0:
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_sc = {
+ .f = cmd_set_macsec_sc_parsed,
+ .data = NULL,
+ .help_str = "set macsec sc tx|rx <port_id> <mac> <pi>",
+ .tokens = {
+ (void *)&cmd_macsec_sc_set,
+ (void *)&cmd_macsec_sc_macsec,
+ (void *)&cmd_macsec_sc_sc,
+ (void *)&cmd_macsec_sc_tx_rx,
+ (void *)&cmd_macsec_sc_port_id,
+ (void *)&cmd_macsec_sc_mac,
+ (void *)&cmd_macsec_sc_pi,
+ NULL,
+ },
+};
+
+/* Common result structure for MACsec secure connection configure */
+struct cmd_macsec_sa_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t macsec;
+ cmdline_fixed_string_t sa;
+ cmdline_fixed_string_t tx_rx;
+ uint8_t port_id;
+ uint8_t idx;
+ uint8_t an;
+ uint32_t pn;
+ cmdline_fixed_string_t key;
+};
+
+/* Common CLI fields for MACsec secure connection configure */
+cmdline_parse_token_string_t cmd_macsec_sa_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_macsec_sa_macsec =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_sa_sa =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ sa, "sa");
+cmdline_parse_token_string_t cmd_macsec_sa_tx_rx =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ tx_rx, "tx#rx");
+cmdline_parse_token_num_t cmd_macsec_sa_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_idx =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ idx, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_an =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ an, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_pn =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ pn, UINT32);
+cmdline_parse_token_string_t cmd_macsec_sa_key =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_macsec_sa_result,
+ key, NULL);
+
+static void
+cmd_set_macsec_sa_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_macsec_sa_result *res = parsed_result;
+ int ret;
+ int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0;
+ uint8_t key[16] = { 0 };
+ uint8_t xdgt0;
+ uint8_t xdgt1;
+ int key_len;
+ int i;
+
+ key_len = strlen(res->key) / 2;
+ if (key_len > 16)
+ key_len = 16;
+
+ for (i = 0; i < key_len; i++) {
+ xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
+ if (xdgt0 == 0xFF)
+ return;
+ xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
+ if (xdgt1 == 0xFF)
+ return;
+ key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
+ }
+
+ ret = is_tx ?
+ rte_pmd_ixgbe_macsec_select_txsa(res->port_id,
+ res->idx, res->an, res->pn, key) :
+ rte_pmd_ixgbe_macsec_select_rxsa(res->port_id,
+ res->idx, res->an, res->pn, key);
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid idx %d or an %d\n", res->idx, res->an);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_sa = {
+ .f = cmd_set_macsec_sa_parsed,
+ .data = NULL,
+ .help_str = "set macsec sa tx|rx <port_id> <idx> <an> <pn> <key>",
+ .tokens = {
+ (void *)&cmd_macsec_sa_set,
+ (void *)&cmd_macsec_sa_macsec,
+ (void *)&cmd_macsec_sa_sa,
+ (void *)&cmd_macsec_sa_tx_rx,
+ (void *)&cmd_macsec_sa_port_id,
+ (void *)&cmd_macsec_sa_idx,
+ (void *)&cmd_macsec_sa_an,
+ (void *)&cmd_macsec_sa_pn,
+ (void *)&cmd_macsec_sa_key,
+ NULL,
+ },
+};
#endif
/* ******************************************************************************** */
@@ -11656,6 +12041,10 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
+ (cmdline_parse_inst_t *)&cmd_set_macsec_offload_on,
+ (cmdline_parse_inst_t *)&cmd_set_macsec_offload_off,
+ (cmdline_parse_inst_t *)&cmd_set_macsec_sc,
+ (cmdline_parse_inst_t *)&cmd_set_macsec_sa,
#endif
NULL,
};
diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c
index d361db1..38e955f 100644
--- a/app/test-pmd/macfwd.c
+++ b/app/test-pmd/macfwd.c
@@ -66,6 +66,9 @@
#include <rte_ip.h>
#include <rte_string_fns.h>
#include <rte_flow.h>
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
#include "testpmd.h"
@@ -113,6 +116,10 @@ pkt_burst_mac_forward(struct fwd_stream *fs)
ol_flags = PKT_TX_VLAN_PKT;
if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
ol_flags |= PKT_TX_QINQ_PKT;
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+ ol_flags |= PKT_TX_IXGBE_MACSEC;
+#endif
for (i = 0; i < nb_rx; i++) {
if (likely(i < nb_rx - 1))
rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
diff --git a/app/test-pmd/macswap.c b/app/test-pmd/macswap.c
index f996039..7f5dcd7 100644
--- a/app/test-pmd/macswap.c
+++ b/app/test-pmd/macswap.c
@@ -66,6 +66,9 @@
#include <rte_ip.h>
#include <rte_string_fns.h>
#include <rte_flow.h>
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
#include "testpmd.h"
@@ -113,6 +116,10 @@ pkt_burst_mac_swap(struct fwd_stream *fs)
ol_flags = PKT_TX_VLAN_PKT;
if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
ol_flags |= PKT_TX_QINQ_PKT;
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+ ol_flags |= PKT_TX_IXGBE_MACSEC;
+#endif
for (i = 0; i < nb_rx; i++) {
if (likely(i < nb_rx - 1))
rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 22ce2d6..0a9a1af 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -143,6 +143,8 @@ struct fwd_stream {
#define TESTPMD_TX_OFFLOAD_INSERT_VLAN 0x0040
/** Insert double VLAN header in forward engine */
#define TESTPMD_TX_OFFLOAD_INSERT_QINQ 0x0080
+/** Offload MACsec in forward engine */
+#define TESTPMD_TX_OFFLOAD_MACSEC 0x0100
/** Descriptor for a single flow. */
struct port_flow {
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index e996f35..3aea8b3 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -69,6 +69,9 @@
#include <rte_udp.h>
#include <rte_string_fns.h>
#include <rte_flow.h>
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
#include "testpmd.h"
@@ -215,6 +218,10 @@ pkt_burst_transmit(struct fwd_stream *fs)
ol_flags = PKT_TX_VLAN_PKT;
if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
ol_flags |= PKT_TX_QINQ_PKT;
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+ ol_flags |= PKT_TX_IXGBE_MACSEC;
+#endif
for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
pkt = rte_mbuf_raw_alloc(mbp);
if (pkt == NULL) {
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index cacdef1..f4068d3 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -507,6 +507,38 @@ Set mac antispoof for a VF from the PF::
testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)
+set macsec offload
+~~~~~~~~~~~~~~~~~~
+
+Enable/disable MACsec offload::
+
+ testpmd> set macsec offload (port_id) on encrypt (on|off) replay-protect (on|off)
+ testpmd> set macsec offload (port_id) off
+
+set macsec sc
+~~~~~~~~~~~~~
+
+Configure MACsec secure connection (SC)::
+
+ testpmd> set macsec sc (tx|rx) (port_id) (mac) (pi)
+
+.. note::
+
+ The pi argument is ignored for tx.
+ Check the NIC Datasheet for hardware limits.
+
+set macsec sa
+~~~~~~~~~~~~~
+
+Configure MACsec secure association (SA)::
+
+ testpmd> set macsec sa (tx|rx) (port_id) (idx) (an) (pn) (key)
+
+.. note::
+
+ The IDX value must be 0 or 1.
+ Check the NIC Datasheet for hardware limits.
+
vlan set strip
~~~~~~~~~~~~~~
--
2.7.4
^ permalink raw reply related
* [PATCH v4 4/7] net/ixgbe: add MACsec offload support
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
MACsec (or LinkSec, 802.1AE) is a MAC level encryption/authentication
scheme defined in IEEE 802.1AE that uses symmetric cryptography.
This commit adds the MACsec offload support for ixgbe.
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 481 +++++++++++++++++++++++++++-
drivers/net/ixgbe/ixgbe_ethdev.h | 45 +++
drivers/net/ixgbe/ixgbe_rxtx.c | 5 +
drivers/net/ixgbe/rte_pmd_ixgbe.h | 122 +++++++
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 11 +
5 files changed, 659 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ec2edad..653ddd2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -231,6 +231,7 @@ static int ixgbe_dev_rss_reta_query(struct rte_eth_dev *dev,
uint16_t reta_size);
static void ixgbe_dev_link_status_print(struct rte_eth_dev *dev);
static int ixgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev);
+static int ixgbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev);
static int ixgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);
static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
@@ -745,6 +746,51 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
#define IXGBE_NB_HW_STATS (sizeof(rte_ixgbe_stats_strings) / \
sizeof(rte_ixgbe_stats_strings[0]))
+/* MACsec statistics */
+static const struct rte_ixgbe_xstats_name_off rte_ixgbe_macsec_strings[] = {
+ {"out_pkts_untagged", offsetof(struct ixgbe_macsec_stats,
+ out_pkts_untagged)},
+ {"out_pkts_encrypted", offsetof(struct ixgbe_macsec_stats,
+ out_pkts_encrypted)},
+ {"out_pkts_protected", offsetof(struct ixgbe_macsec_stats,
+ out_pkts_protected)},
+ {"out_octets_encrypted", offsetof(struct ixgbe_macsec_stats,
+ out_octets_encrypted)},
+ {"out_octets_protected", offsetof(struct ixgbe_macsec_stats,
+ out_octets_protected)},
+ {"in_pkts_untagged", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_untagged)},
+ {"in_pkts_badtag", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_badtag)},
+ {"in_pkts_nosci", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_nosci)},
+ {"in_pkts_unknownsci", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_unknownsci)},
+ {"in_octets_decrypted", offsetof(struct ixgbe_macsec_stats,
+ in_octets_decrypted)},
+ {"in_octets_validated", offsetof(struct ixgbe_macsec_stats,
+ in_octets_validated)},
+ {"in_pkts_unchecked", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_unchecked)},
+ {"in_pkts_delayed", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_delayed)},
+ {"in_pkts_late", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_late)},
+ {"in_pkts_ok", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_ok)},
+ {"in_pkts_invalid", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_invalid)},
+ {"in_pkts_notvalid", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_notvalid)},
+ {"in_pkts_unusedsa", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_unusedsa)},
+ {"in_pkts_notusingsa", offsetof(struct ixgbe_macsec_stats,
+ in_pkts_notusingsa)},
+};
+
+#define IXGBE_NB_MACSEC_STATS (sizeof(rte_ixgbe_macsec_strings) / \
+ sizeof(rte_ixgbe_macsec_strings[0]))
+
/* Per-queue statistics */
static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = {
{"mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats, rnbc)},
@@ -2367,6 +2413,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
/* check if lsc interrupt is enabled */
if (dev->data->dev_conf.intr_conf.lsc != 0)
ixgbe_dev_lsc_interrupt_setup(dev);
+ ixgbe_dev_macsec_interrupt_setup(dev);
} else {
rte_intr_callback_unregister(intr_handle,
ixgbe_dev_interrupt_handler, dev);
@@ -2557,6 +2604,7 @@ ixgbe_dev_close(struct rte_eth_dev *dev)
static void
ixgbe_read_stats_registers(struct ixgbe_hw *hw,
struct ixgbe_hw_stats *hw_stats,
+ struct ixgbe_macsec_stats *macsec_stats,
uint64_t *total_missed_rx, uint64_t *total_qbrc,
uint64_t *total_qprc, uint64_t *total_qprdc)
{
@@ -2726,6 +2774,40 @@ ixgbe_read_stats_registers(struct ixgbe_hw *hw,
/* Flow Director Stats registers */
hw_stats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
hw_stats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+
+ /* MACsec Stats registers */
+ macsec_stats->out_pkts_untagged += IXGBE_READ_REG(hw, IXGBE_LSECTXUT);
+ macsec_stats->out_pkts_encrypted +=
+ IXGBE_READ_REG(hw, IXGBE_LSECTXPKTE);
+ macsec_stats->out_pkts_protected +=
+ IXGBE_READ_REG(hw, IXGBE_LSECTXPKTP);
+ macsec_stats->out_octets_encrypted +=
+ IXGBE_READ_REG(hw, IXGBE_LSECTXOCTE);
+ macsec_stats->out_octets_protected +=
+ IXGBE_READ_REG(hw, IXGBE_LSECTXOCTP);
+ macsec_stats->in_pkts_untagged += IXGBE_READ_REG(hw, IXGBE_LSECRXUT);
+ macsec_stats->in_pkts_badtag += IXGBE_READ_REG(hw, IXGBE_LSECRXBAD);
+ macsec_stats->in_pkts_nosci += IXGBE_READ_REG(hw, IXGBE_LSECRXNOSCI);
+ macsec_stats->in_pkts_unknownsci +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXUNSCI);
+ macsec_stats->in_octets_decrypted +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXOCTD);
+ macsec_stats->in_octets_validated +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXOCTV);
+ macsec_stats->in_pkts_unchecked += IXGBE_READ_REG(hw, IXGBE_LSECRXUNCH);
+ macsec_stats->in_pkts_delayed += IXGBE_READ_REG(hw, IXGBE_LSECRXDELAY);
+ macsec_stats->in_pkts_late += IXGBE_READ_REG(hw, IXGBE_LSECRXLATE);
+ for (i = 0; i < 2; i++) {
+ macsec_stats->in_pkts_ok +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXOK(i));
+ macsec_stats->in_pkts_invalid +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXINV(i));
+ macsec_stats->in_pkts_notvalid +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXNV(i));
+ }
+ macsec_stats->in_pkts_unusedsa += IXGBE_READ_REG(hw, IXGBE_LSECRXUNSA);
+ macsec_stats->in_pkts_notusingsa +=
+ IXGBE_READ_REG(hw, IXGBE_LSECRXNUSA);
}
/*
@@ -2738,6 +2820,9 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_stats *hw_stats =
IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+ struct ixgbe_macsec_stats *macsec_stats =
+ IXGBE_DEV_PRIVATE_TO_MACSEC_STATS(
+ dev->data->dev_private);
uint64_t total_missed_rx, total_qbrc, total_qprc, total_qprdc;
unsigned i;
@@ -2746,8 +2831,8 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
total_qprc = 0;
total_qprdc = 0;
- ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
- &total_qprc, &total_qprdc);
+ ixgbe_read_stats_registers(hw, hw_stats, macsec_stats, &total_missed_rx,
+ &total_qbrc, &total_qprc, &total_qprdc);
if (stats == NULL)
return;
@@ -2799,7 +2884,7 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev)
/* This function calculates the number of xstats based on the current config */
static unsigned
ixgbe_xstats_calc_num(void) {
- return IXGBE_NB_HW_STATS +
+ return IXGBE_NB_HW_STATS + IXGBE_NB_MACSEC_STATS +
(IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) +
(IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES);
}
@@ -2826,6 +2911,15 @@ static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
count++;
}
+ /* MACsec Stats */
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ rte_ixgbe_macsec_strings[i].name);
+ count++;
+ }
+
/* RX Priority Stats */
for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
@@ -2875,6 +2969,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_stats *hw_stats =
IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+ struct ixgbe_macsec_stats *macsec_stats =
+ IXGBE_DEV_PRIVATE_TO_MACSEC_STATS(
+ dev->data->dev_private);
uint64_t total_missed_rx, total_qbrc, total_qprc, total_qprdc;
unsigned i, stat, count = 0;
@@ -2888,8 +2985,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
total_qprc = 0;
total_qprdc = 0;
- ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
- &total_qprc, &total_qprdc);
+ ixgbe_read_stats_registers(hw, hw_stats, macsec_stats, &total_missed_rx,
+ &total_qbrc, &total_qprc, &total_qprdc);
/* If this is a reset xstats is NULL, and we have cleared the
* registers by reading them.
@@ -2905,6 +3002,13 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
count++;
}
+ /* MACsec Stats */
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ xstats[count].value = *(uint64_t *)(((char *)macsec_stats) +
+ rte_ixgbe_macsec_strings[i].offset);
+ count++;
+ }
+
/* RX Priority Stats */
for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
@@ -2932,6 +3036,9 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
{
struct ixgbe_hw_stats *stats =
IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+ struct ixgbe_macsec_stats *macsec_stats =
+ IXGBE_DEV_PRIVATE_TO_MACSEC_STATS(
+ dev->data->dev_private);
unsigned count = ixgbe_xstats_calc_num();
@@ -2940,6 +3047,7 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
/* Reset software totals */
memset(stats, 0, sizeof(*stats));
+ memset(macsec_stats, 0, sizeof(*macsec_stats));
}
static void
@@ -3072,6 +3180,10 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
!RTE_ETH_DEV_SRIOV(dev).active)
dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
+ if (hw->mac.type == ixgbe_mac_82599EB ||
+ hw->mac.type == ixgbe_mac_X540)
+ dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_IXGBE_MACSEC_STRIP;
+
if (hw->mac.type == ixgbe_mac_X550 ||
hw->mac.type == ixgbe_mac_X550EM_x ||
hw->mac.type == ixgbe_mac_X550EM_a)
@@ -3085,6 +3197,10 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
DEV_TX_OFFLOAD_SCTP_CKSUM |
DEV_TX_OFFLOAD_TCP_TSO;
+ if (hw->mac.type == ixgbe_mac_82599EB ||
+ hw->mac.type == ixgbe_mac_X540)
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_IXGBE_MACSEC_INSERT;
+
if (hw->mac.type == ixgbe_mac_X550 ||
hw->mac.type == ixgbe_mac_X550EM_x ||
hw->mac.type == ixgbe_mac_X550EM_a)
@@ -3382,6 +3498,28 @@ ixgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
return 0;
}
+/**
+ * It clears the interrupt causes and enables the interrupt.
+ * It will be called once only during nic initialized.
+ *
+ * @param dev
+ * Pointer to struct rte_eth_dev.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev)
+{
+ struct ixgbe_interrupt *intr =
+ IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+
+ intr->mask |= IXGBE_EICR_LINKSEC;
+
+ return 0;
+}
+
/*
* It reads ICR and sets flag (IXGBE_EICR_LSC) for the link_update.
*
@@ -3416,6 +3554,9 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
if (eicr & IXGBE_EICR_MAILBOX)
intr->flags |= IXGBE_FLAG_MAILBOX;
+ if (eicr & IXGBE_EICR_LINKSEC)
+ intr->flags |= IXGBE_FLAG_MACSEC;
+
if (hw->mac.type == ixgbe_mac_X550EM_x &&
hw->phy.type == ixgbe_phy_x550em_ext_t &&
(eicr & IXGBE_EICR_GPI_SDP0_X550EM_x))
@@ -3570,6 +3711,12 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
+ if (intr->flags & IXGBE_FLAG_MACSEC) {
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_IXGBE_MACSEC,
+ NULL);
+ intr->flags &= ~IXGBE_FLAG_MACSEC;
+ }
+
PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
ixgbe_enable_intr(dev);
rte_intr_enable(intr_handle);
@@ -7610,6 +7757,330 @@ ixgbevf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
ixgbevf_dev_interrupt_action(dev);
}
+/**
+ * ixgbe_disable_sec_tx_path_generic - Stops the transmit data path
+ * @hw: pointer to hardware structure
+ *
+ * Stops the transmit data path and waits for the HW to internally empty
+ * the Tx security block
+ **/
+int ixgbe_disable_sec_tx_path_generic(struct ixgbe_hw *hw)
+{
+#define IXGBE_MAX_SECTX_POLL 40
+
+ int i;
+ int sectxreg;
+
+ sectxreg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+ sectxreg |= IXGBE_SECTXCTRL_TX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, sectxreg);
+ for (i = 0; i < IXGBE_MAX_SECTX_POLL; i++) {
+ sectxreg = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT);
+ if (sectxreg & IXGBE_SECTXSTAT_SECTX_RDY)
+ break;
+ /* Use interrupt-safe sleep just in case */
+ usec_delay(1000);
+ }
+
+ /* For informational purposes only */
+ if (i >= IXGBE_MAX_SECTX_POLL)
+ PMD_DRV_LOG(DEBUG, "Tx unit being enabled before security "
+ "path fully disabled. Continuing with init.\n");
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_enable_sec_tx_path_generic - Enables the transmit data path
+ * @hw: pointer to hardware structure
+ *
+ * Enables the transmit data path.
+ **/
+int ixgbe_enable_sec_tx_path_generic(struct ixgbe_hw *hw)
+{
+ uint32_t sectxreg;
+
+ sectxreg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+ sectxreg &= ~IXGBE_SECTXCTRL_TX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, sectxreg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return IXGBE_SUCCESS;
+}
+
+int
+rte_pmd_ixgbe_macsec_enable(uint8_t port, uint8_t en, uint8_t rp)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ /* Stop the data paths */
+ if (ixgbe_disable_sec_rx_path(hw) != IXGBE_SUCCESS)
+ return -ENOTSUP;
+ /*
+ * Workaround:
+ * As no ixgbe_disable_sec_rx_path equivalent is
+ * implemented for tx in the base code, and we are
+ * not allowed to modify the base code in DPDK, so
+ * just call the hand-written one directly for now.
+ * The hardware support has been checked by
+ * ixgbe_disable_sec_rx_path().
+ */
+ ixgbe_disable_sec_tx_path_generic(hw);
+
+ /* Enable Ethernet CRC (required by MACsec offload) */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+ ctrl |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_RXCRCSTRP;
+ IXGBE_WRITE_REG(hw, IXGBE_HLREG0, ctrl);
+
+ /* Enable the TX and RX crypto engines */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+ ctrl &= ~IXGBE_SECTXCTRL_SECTX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl);
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ ctrl &= ~IXGBE_SECRXCTRL_SECRX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl);
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+ ctrl &= ~IXGBE_SECTX_MINSECIFG_MASK;
+ ctrl |= 0x3;
+ IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, ctrl);
+
+ /* Enable SA lookup */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL);
+ ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK;
+ ctrl |= en ? IXGBE_LSECTXCTRL_AUTH_ENCRYPT :
+ IXGBE_LSECTXCTRL_AUTH;
+ ctrl |= IXGBE_LSECTXCTRL_AISCI;
+ ctrl &= ~IXGBE_LSECTXCTRL_PNTHRSH_MASK;
+ ctrl |= IXGBE_MACSEC_PNTHRSH & IXGBE_LSECTXCTRL_PNTHRSH_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl);
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL);
+ ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK;
+ ctrl |= IXGBE_LSECRXCTRL_STRICT << IXGBE_LSECRXCTRL_EN_SHIFT;
+ ctrl &= ~IXGBE_LSECRXCTRL_PLSH;
+ if (rp)
+ ctrl |= IXGBE_LSECRXCTRL_RP;
+ else
+ ctrl &= ~IXGBE_LSECRXCTRL_RP;
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl);
+
+ /* Start the data paths */
+ ixgbe_enable_sec_rx_path(hw);
+ /*
+ * Workaround:
+ * As no ixgbe_enable_sec_rx_path equivalent is
+ * implemented for tx in the base code, and we are
+ * not allowed to modify the base code in DPDK, so
+ * just call the hand-written one directly for now.
+ */
+ ixgbe_enable_sec_tx_path_generic(hw);
+
+ return 0;
+}
+
+int
+rte_pmd_ixgbe_macsec_disable(uint8_t port)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ /* Stop the data paths */
+ if (ixgbe_disable_sec_rx_path(hw) != IXGBE_SUCCESS)
+ return -ENOTSUP;
+ /*
+ * Workaround:
+ * As no ixgbe_disable_sec_rx_path equivalent is
+ * implemented for tx in the base code, and we are
+ * not allowed to modify the base code in DPDK, so
+ * just call the hand-written one directly for now.
+ * The hardware support has been checked by
+ * ixgbe_disable_sec_rx_path().
+ */
+ ixgbe_disable_sec_tx_path_generic(hw);
+
+ /* Disable the TX and RX crypto engines */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+ ctrl |= IXGBE_SECTXCTRL_SECTX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl);
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ ctrl |= IXGBE_SECRXCTRL_SECRX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl);
+
+ /* Disable SA lookup */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL);
+ ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK;
+ ctrl |= IXGBE_LSECTXCTRL_DISABLE;
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl);
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL);
+ ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK;
+ ctrl |= IXGBE_LSECRXCTRL_DISABLE << IXGBE_LSECRXCTRL_EN_SHIFT;
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl);
+
+ /* Start the data paths */
+ ixgbe_enable_sec_rx_path(hw);
+ /*
+ * Workaround:
+ * As no ixgbe_enable_sec_rx_path equivalent is
+ * implemented for tx in the base code, and we are
+ * not allowed to modify the base code in DPDK, so
+ * just call the hand-written one directly for now.
+ */
+ ixgbe_enable_sec_tx_path_generic(hw);
+
+ return 0;
+}
+
+int
+rte_pmd_ixgbe_macsec_config_txsc(uint8_t port, uint8_t *mac)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ ctrl = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXSCL, ctrl);
+
+ ctrl = mac[4] | (mac[5] << 8);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXSCH, ctrl);
+
+ return 0;
+}
+
+int
+rte_pmd_ixgbe_macsec_config_rxsc(uint8_t port, uint8_t *mac, uint16_t pi)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ ctrl = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXSCL, ctrl);
+
+ pi = rte_cpu_to_be_16(pi);
+ ctrl = mac[4] | (mac[5] << 8) | (pi << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXSCH, ctrl);
+
+ return 0;
+}
+
+int
+rte_pmd_ixgbe_macsec_select_txsa(uint8_t port, uint8_t idx, uint8_t an,
+ uint32_t pn, uint8_t *key)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl, i;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (idx != 0 && idx != 1)
+ return -EINVAL;
+
+ if (an >= 4)
+ return -EINVAL;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ /* Set the PN and key */
+ pn = rte_cpu_to_be_32(pn);
+ if (idx == 0) {
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXPN0, pn);
+
+ for (i = 0; i < 4; i++) {
+ ctrl = (key[i * 4 + 0] << 0) |
+ (key[i * 4 + 1] << 8) |
+ (key[i * 4 + 2] << 16) |
+ (key[i * 4 + 3] << 24);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXKEY0(i), ctrl);
+ }
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXPN1, pn);
+
+ for (i = 0; i < 4; i++) {
+ ctrl = (key[i * 4 + 0] << 0) |
+ (key[i * 4 + 1] << 8) |
+ (key[i * 4 + 2] << 16) |
+ (key[i * 4 + 3] << 24);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXKEY1(i), ctrl);
+ }
+ }
+
+ /* Set AN and select the SA */
+ ctrl = (an << idx * 2) | (idx << 4);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECTXSA, ctrl);
+
+ return 0;
+}
+
+int
+rte_pmd_ixgbe_macsec_select_rxsa(uint8_t port, uint8_t idx, uint8_t an,
+ uint32_t pn, uint8_t *key)
+{
+ struct ixgbe_hw *hw;
+ struct rte_eth_dev *dev;
+ uint32_t ctrl, i;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (idx != 0 && idx != 1)
+ return -EINVAL;
+
+ if (an >= 4)
+ return -EINVAL;
+
+ /* Set the PN */
+ pn = rte_cpu_to_be_32(pn);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXPN(idx), pn);
+
+ /* Set the key */
+ for (i = 0; i < 4; i++) {
+ ctrl = (key[i * 4 + 0] << 0) |
+ (key[i * 4 + 1] << 8) |
+ (key[i * 4 + 2] << 16) |
+ (key[i * 4 + 3] << 24);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXKEY(idx, i), ctrl);
+ }
+
+ /* Set the AN and validate the SA */
+ ctrl = an | (1 << 2);
+ IXGBE_WRITE_REG(hw, IXGBE_LSECRXSA(idx), ctrl);
+
+ return 0;
+}
+
RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map);
RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio");
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 80350c2..ffced1c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -43,6 +43,7 @@
#define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
#define IXGBE_FLAG_MAILBOX (uint32_t)(1 << 1)
#define IXGBE_FLAG_PHY_INTERRUPT (uint32_t)(1 << 2)
+#define IXGBE_FLAG_MACSEC (uint32_t)(1 << 3)
/*
* Defines that were not part of ixgbe_type.h as they are not used by the
@@ -130,6 +131,10 @@
#define IXGBE_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
#define IXGBE_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+#define IXGBE_SECTX_MINSECIFG_MASK 0x0000000F
+
+#define IXGBE_MACSEC_PNTHRSH 0xFFFFFE00
+
/*
* Information about the fdir mode.
*/
@@ -265,11 +270,44 @@ struct ixgbe_filter_info {
};
/*
+ * Statistics counters collected by the MACsec
+ */
+struct ixgbe_macsec_stats {
+ /* TX port statistics */
+ uint64_t out_pkts_untagged;
+ uint64_t out_pkts_encrypted;
+ uint64_t out_pkts_protected;
+ uint64_t out_octets_encrypted;
+ uint64_t out_octets_protected;
+
+ /* RX port statistics */
+ uint64_t in_pkts_untagged;
+ uint64_t in_pkts_badtag;
+ uint64_t in_pkts_nosci;
+ uint64_t in_pkts_unknownsci;
+ uint64_t in_octets_decrypted;
+ uint64_t in_octets_validated;
+
+ /* RX SC statistics */
+ uint64_t in_pkts_unchecked;
+ uint64_t in_pkts_delayed;
+ uint64_t in_pkts_late;
+
+ /* RX SA statistics */
+ uint64_t in_pkts_ok;
+ uint64_t in_pkts_invalid;
+ uint64_t in_pkts_notvalid;
+ uint64_t in_pkts_unusedsa;
+ uint64_t in_pkts_notusingsa;
+};
+
+/*
* Structure to store private data for each driver instance (for each port).
*/
struct ixgbe_adapter {
struct ixgbe_hw hw;
struct ixgbe_hw_stats stats;
+ struct ixgbe_macsec_stats macsec_stats;
struct ixgbe_hw_fdir_info fdir;
struct ixgbe_interrupt intr;
struct ixgbe_stat_mapping_registers stat_mappings;
@@ -300,6 +338,9 @@ struct ixgbe_adapter {
#define IXGBE_DEV_PRIVATE_TO_STATS(adapter) \
(&((struct ixgbe_adapter *)adapter)->stats)
+#define IXGBE_DEV_PRIVATE_TO_MACSEC_STATS(adapter) \
+ (&((struct ixgbe_adapter *)adapter)->macsec_stats)
+
#define IXGBE_DEV_PRIVATE_TO_INTR(adapter) \
(&((struct ixgbe_adapter *)adapter)->intr)
@@ -445,4 +486,8 @@ uint32_t ixgbe_convert_vm_rx_mask_to_val(uint16_t rx_mask, uint32_t orig_val);
int ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev,
enum rte_filter_op filter_op, void *arg);
+
+int ixgbe_disable_sec_tx_path_generic(struct ixgbe_hw *hw);
+
+int ixgbe_enable_sec_tx_path_generic(struct ixgbe_hw *hw);
#endif /* _IXGBE_ETHDEV_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index b2d9f45..db9fc18 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -79,12 +79,15 @@
#include "base/ixgbe_common.h"
#include "ixgbe_rxtx.h"
+#include "rte_pmd_ixgbe.h"
+
/* Bit Mask to indicate what bits required for building TX context */
#define IXGBE_TX_OFFLOAD_MASK ( \
PKT_TX_VLAN_PKT | \
PKT_TX_IP_CKSUM | \
PKT_TX_L4_MASK | \
PKT_TX_TCP_SEG | \
+ PKT_TX_IXGBE_MACSEC | \
PKT_TX_OUTER_IP_CKSUM)
#if 1
@@ -519,6 +522,8 @@ tx_desc_ol_flags_to_cmdtype(uint64_t ol_flags)
cmdtype |= IXGBE_ADVTXD_DCMD_TSE;
if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
cmdtype |= (1 << IXGBE_ADVTXD_OUTERIPCS_SHIFT);
+ if (ol_flags & PKT_TX_IXGBE_MACSEC)
+ cmdtype |= IXGBE_ADVTXD_MAC_LINKSEC;
return cmdtype;
}
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h
index c2fb826..13b6a44 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
@@ -42,6 +42,28 @@
#include <rte_ethdev.h>
/**
+ * If these flags are advertised by the PMD, the NIC supports the MACsec
+ * offload. The incoming MACsec traffics can be offloaded transparently
+ * after the MACsec offload is configured correctly by the application.
+ * And the application can set the PKT_TX_IXGBE_MACSEC flag in mbufs to
+ * enable the MACsec offload for the packets to be transmitted.
+ */
+#define DEV_RX_OFFLOAD_IXGBE_MACSEC_STRIP DEV_RX_OFFLOAD_RESERVED_0
+#define DEV_TX_OFFLOAD_IXGBE_MACSEC_INSERT DEV_TX_OFFLOAD_RESERVED_0
+
+/**
+ * This event will occur when the PN counter in a MACsec connection
+ * reach the exhaustion threshold.
+ */
+#define RTE_ETH_EVENT_IXGBE_MACSEC RTE_ETH_EVENT_RESERVED_0
+
+/**
+ * Offload the MACsec. This flag must be set by the application in mbuf
+ * to enable this offload feature for a packet to be transmitted.
+ */
+#define PKT_TX_IXGBE_MACSEC PKT_TX_RESERVED_0
+
+/**
* Set the VF MAC address.
*
* @param port
@@ -183,6 +205,106 @@ int
rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
/**
+ * Enable MACsec offloading.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param en
+ * 1 - Enable encryption (encrypt and add integrity signature).
+ * 0 - Disable encryption (only add integrity signature).
+ * @param rp
+ * 1 - Enable replay protection.
+ * 0 - Disable replay protection.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-ENOTSUP) if hardware doesn't support this feature.
+ */
+int rte_pmd_ixgbe_macsec_enable(uint8_t port, uint8_t en, uint8_t rp);
+
+/**
+ * Disable MACsec offloading.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-ENOTSUP) if hardware doesn't support this feature.
+ */
+int rte_pmd_ixgbe_macsec_disable(uint8_t port);
+
+/**
+ * Configure TX SC (Secure Connection)
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param mac
+ * The MAC address on the local side.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ */
+int rte_pmd_ixgbe_macsec_config_txsc(uint8_t port, uint8_t *mac);
+
+/**
+ * Configure RX SC (Secure Connection)
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param mac
+ * The MAC address on the remote side.
+ * @param pi
+ * The PI (port identifier) on the remote side.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ */
+int rte_pmd_ixgbe_macsec_config_rxsc(uint8_t port, uint8_t *mac, uint16_t pi);
+
+/**
+ * Enable TX SA (Secure Association)
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param idx
+ * The SA to be enabled (0 or 1).
+ * @param an
+ * The association number on the local side.
+ * @param pn
+ * The packet number on the local side.
+ * @param key
+ * The key on the local side.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_macsec_select_txsa(uint8_t port, uint8_t idx, uint8_t an,
+ uint32_t pn, uint8_t *key);
+
+/**
+ * Enable RX SA (Secure Association)
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param idx
+ * The SA to be enabled (0 or 1)
+ * @param an
+ * The association number on the remote side.
+ * @param pn
+ * The packet number on the remote side.
+ * @param key
+ * The key on the remote side.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_ixgbe_macsec_select_rxsa(uint8_t port, uint8_t idx, uint8_t an,
+ uint32_t pn, uint8_t *key);
+
+/**
* Response sent back to ixgbe driver from user app after callback
*/
enum rte_pmd_ixgbe_mb_event_rsp {
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index 92434f3..6d68934 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -15,3 +15,14 @@ DPDK_16.11 {
rte_pmd_ixgbe_set_vf_vlan_insert;
rte_pmd_ixgbe_set_vf_vlan_stripq;
} DPDK_2.0;
+
+DPDK_17.02 {
+ global:
+
+ rte_pmd_ixgbe_macsec_enable;
+ rte_pmd_ixgbe_macsec_disable;
+ rte_pmd_ixgbe_macsec_config_txsc;
+ rte_pmd_ixgbe_macsec_config_rxsc;
+ rte_pmd_ixgbe_macsec_select_txsa;
+ rte_pmd_ixgbe_macsec_select_rxsa;
+} DPDK_16.11;
--
2.7.4
^ permalink raw reply related
* [PATCH v4 3/7] ethdev: reserve capability flags for PMD-specific API
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Reserve a Tx capability flag and a Rx capability flag, that can be
used by PMD to define its own capability flags when implementing the
PMD-specific API.
Suggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_ether/rte_ethdev.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index d465825..8800b39 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -857,6 +857,7 @@ struct rte_eth_conf {
#define DEV_RX_OFFLOAD_TCP_LRO 0x00000010
#define DEV_RX_OFFLOAD_QINQ_STRIP 0x00000020
#define DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM 0x00000040
+#define DEV_RX_OFFLOAD_RESERVED_0 0x00000080 /**< Used for PMD-specific API. */
/**
* TX offload capabilities of a device.
@@ -874,6 +875,7 @@ struct rte_eth_conf {
#define DEV_TX_OFFLOAD_GRE_TNL_TSO 0x00000400 /**< Used for tunneling packet. */
#define DEV_TX_OFFLOAD_IPIP_TNL_TSO 0x00000800 /**< Used for tunneling packet. */
#define DEV_TX_OFFLOAD_GENEVE_TNL_TSO 0x00001000 /**< Used for tunneling packet. */
+#define DEV_TX_OFFLOAD_RESERVED_0 0x00002000 /**< Used for PMD-specific API. */
/**
* Ethernet device information
--
2.7.4
^ permalink raw reply related
* [PATCH v4 2/7] ethdev: reserve an event type for PMD-specific API
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Reserve an event type, that can be used by PMD to define its own
event type when implementing the PMD-specific API.
Suggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_ether/rte_ethdev.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index fb51754..d465825 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -3044,6 +3044,8 @@ enum rte_eth_event_type {
RTE_ETH_EVENT_INTR_RESET,
/**< reset interrupt event, sent to VF on PF reset */
RTE_ETH_EVENT_VF_MBOX, /**< message from the VF received by PF */
+ RTE_ETH_EVENT_RESERVED_0,
+ /**< reserved event type for PMD-specific API */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};
--
2.7.4
^ permalink raw reply related
* [PATCH v4 1/7] mbuf: reserve a Tx offload flag for PMD-specific API
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482939691-34855-1-git-send-email-tiwei.bie@intel.com>
Reserve a Tx offload flag in mbuf, that can be used by PMD to define
its own Tx offload flag when implementing the PMD-specific API.
Suggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_mbuf/rte_mbuf.c | 2 ++
lib/librte_mbuf/rte_mbuf.h | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 63f43c8..15c4f68 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -404,6 +404,7 @@ const char *rte_get_tx_ol_flag_name(uint64_t mask)
case PKT_TX_TUNNEL_GRE: return "PKT_TX_TUNNEL_GRE";
case PKT_TX_TUNNEL_IPIP: return "PKT_TX_TUNNEL_IPIP";
case PKT_TX_TUNNEL_GENEVE: return "PKT_TX_TUNNEL_GENEVE";
+ case PKT_TX_RESERVED_0: return "PKT_TX_RESERVED_0";
default: return NULL;
}
}
@@ -434,6 +435,7 @@ rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
"PKT_TX_TUNNEL_NONE" },
{ PKT_TX_TUNNEL_GENEVE, PKT_TX_TUNNEL_MASK,
"PKT_TX_TUNNEL_NONE" },
+ { PKT_TX_RESERVED_0, PKT_TX_RESERVED_0, NULL },
};
const char *name;
unsigned int i;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ead7c6e..6168a6d 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -182,6 +182,11 @@ extern "C" {
/* add new TX flags here */
/**
+ * Reserved Tx offload flag for PMD-specific API.
+ */
+#define PKT_TX_RESERVED_0 (0x1ULL << 44)
+
+/**
* Bits 45:48 used for the tunnel type.
* When doing Tx offload like TSO or checksum, the HW needs to configure the
* tunnel type into the HW descriptors.
--
2.7.4
^ permalink raw reply related
* [PATCH v4 0/7] Add MACsec offload support for ixgbe
From: Tiwei Bie @ 2016-12-28 15:41 UTC (permalink / raw)
To: dev
Cc: adrien.mazarguil, wenzhuo.lu, john.mcnamara, olivier.matz,
thomas.monjalon, konstantin.ananyev, helin.zhang, wei.dai,
xiao.w.wang
In-Reply-To: <1482677880-117158-1-git-send-email-tiwei.bie@intel.com>
This patch set adds the MACsec offload support for ixgbe.
The testpmd is also updated to support MACsec cmds.
v2:
- Update the documents for testpmd;
- Update the release notes;
- Reuse the functions provided by base code;
v3:
- Add the missing parts of MACsec mbuf flag and reorganize the patch set;
- Add an ethdev event type for MACsec;
- Advertise the MACsec offload capabilities based on the mac type;
- Minor fixes and improvements;
v4:
- Reserve bits in mbuf and ethdev for PMD specific API;
- Use the reserved bits in PMD specific API;
Tiwei Bie (7):
mbuf: reserve a Tx offload flag for PMD-specific API
ethdev: reserve an event type for PMD-specific API
ethdev: reserve capability flags for PMD-specific API
net/ixgbe: add MACsec offload support
app/testpmd: add MACsec offload commands
doc: add ixgbe specific APIs
doc: update the release notes for the reserved flags
app/test-pmd/cmdline.c | 389 ++++++++++++++++++++++
app/test-pmd/macfwd.c | 7 +
app/test-pmd/macswap.c | 7 +
app/test-pmd/testpmd.h | 2 +
app/test-pmd/txonly.c | 7 +
doc/guides/rel_notes/release_17_02.rst | 18 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 32 ++
drivers/net/ixgbe/ixgbe_ethdev.c | 481 +++++++++++++++++++++++++++-
drivers/net/ixgbe/ixgbe_ethdev.h | 45 +++
drivers/net/ixgbe/ixgbe_rxtx.c | 5 +
drivers/net/ixgbe/rte_pmd_ixgbe.h | 122 +++++++
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 11 +
lib/librte_ether/rte_ethdev.h | 4 +
lib/librte_mbuf/rte_mbuf.c | 2 +
lib/librte_mbuf/rte_mbuf.h | 5 +
15 files changed, 1132 insertions(+), 5 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: DPDK v16.07 Build Failure with Unsupported OS CentOS 6.8
From: Shepard Siegel @ 2016-12-28 14:45 UTC (permalink / raw)
To: dev
In-Reply-To: <CAMMLSKC55oLaiqKvcc_g6ghn0b9295bVPNGhnoBwxGbECdq4mA@mail.gmail.com>
Follow-Up: We're all set, thanks John Miller; and my apologies for
incorrectly posting this to "dev" as opposed to "users" mailing list. -Shep
On Wed, Dec 28, 2016 at 9:13 AM, Shepard Siegel <
shepard.siegel@atomicrules.com> wrote:
> A client of ours shipped us an IBM x3650 with CentOS 6.8 installed. Our
> software team is off for the holidays. We use DPDK 16.07 and have had no
> issues with supported OSs. We understand that CentOS 6.8 is not supported
> for DPDK v16.07. Still, since IBM doesn't support CentOS 7 on the x3650, I
> figured I'd give it a try before risking a server OS change.
>
> We do this little dance to setup DPDK on our systems...
>
> git clone git://dpdk.org/dpdk
> cd dpdk
> git branch develop
> git checkout develop
> git reset --hard v16.07
> make config T=x86_64-native-linuxapp-gcc
> sed -ri 's,(PMD_PCAP=).*,\1y,' build/.config
> sed -ri 's/CONFIG_RTE_BUILD_SHARED_LIB=n/CONFIG_RTE_BUILD_SHARED_LIB=y/'
> build/.config
> sudo yum install libpcap-devel
> make
>
> Then the make fails some ways in as below...
>
> [labuser@bw-x3650 dpdk]$ git rev-parse HEAD
> 20e2b6eba13d9eb61b23ea75f09f2aa966fa6325
>
> [labuser@bw-x3650 dpdk]$ uname -r
> 2.6.32-642.11.1.el6.x86_64
>
> [labuser@bw-x3650 dpdk]$ cat /etc/redhat-release
> CentOS release 6.8 (Final)
>
> [labuser@bw-x3650 dpdk]$ make
> == Build lib
> == Build lib/librte_compat
> == Build lib/librte_eal
> == Build lib/librte_eal/common
> == Build lib/librte_eal/linuxapp
> == Build lib/librte_eal/linuxapp/eal
> LD librte_eal.so.2.1
> INSTALL-LIB librte_eal.so.2.1
> == Build lib/librte_eal/linuxapp/igb_uio
> (cat /dev/null; echo kernel//home/labuser/projects/
> dpdk/build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko;) >
> /home/labuser/projects/dpdk/build/build/lib/librte_eal/
> linuxapp/igb_uio/modules.order
> Building modules, stage 2.
> MODPOST 1 modules
> == Build lib/librte_eal/linuxapp/kni
> CC [M] /home/labuser/projects/dpdk/build/build/lib/librte_eal/
> linuxapp/kni/ixgbe_main.o
> In file included from /home/labuser/projects/dpdk/
> lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_osdep.h:41,
> from /home/labuser/projects/dpdk/
> lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_type.h:31,
> from /home/labuser/projects/dpdk/
> lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_dcb.h:32,
> from /home/labuser/projects/dpdk/
> lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe.h:52,
> from /home/labuser/projects/dpdk/
> build/build/lib/librte_eal/linuxapp/kni/ixgbe_main.c:56:
> /home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/kcompat.h:
> In function ‘__kc_vlan_get_protocol’:
> /home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/kcompat.h:2836:
> error: implicit declaration of function ‘vlan_tx_tag_present’
> make[8]: *** [/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni/ixgbe_main.o]
> Error 1
> make[7]: *** [_module_/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni]
> Error 2
> make[6]: *** [sub-make] Error 2
> make[5]: *** [rte_kni.ko] Error 2
> make[4]: *** [kni] Error 2
> make[3]: *** [linuxapp] Error 2
> make[2]: *** [librte_eal] Error 2
> make[1]: *** [lib] Error 2
> make: *** [all] Error 2
>
> Google suggested some hacks; but I'm out of my element in driver source.
> Is this a lost cause and I should try to get the server up to CentOS 7? Or
> is there a relatively simple (if untested) patch that we could try? Our
> objective here is to get through the DPDK and our net/ark PMD build process
> and see if we can run some of our most-basic packet ingress/egress ops on
> our Arkville IP in this system.
>
> Thanks in advance for any constructive feedback. Happy Holidays All. -Shep
>
> Shepard Siegel, CTO
> atomicrules.com
>
>
>
>
>
>
^ permalink raw reply
* DPDK v16.07 Build Failure with Unsupported OS CentOS 6.8
From: Shepard Siegel @ 2016-12-28 14:13 UTC (permalink / raw)
To: dev
A client of ours shipped us an IBM x3650 with CentOS 6.8 installed. Our
software team is off for the holidays. We use DPDK 16.07 and have had no
issues with supported OSs. We understand that CentOS 6.8 is not supported
for DPDK v16.07. Still, since IBM doesn't support CentOS 7 on the x3650, I
figured I'd give it a try before risking a server OS change.
We do this little dance to setup DPDK on our systems...
git clone git://dpdk.org/dpdk
cd dpdk
git branch develop
git checkout develop
git reset --hard v16.07
make config T=x86_64-native-linuxapp-gcc
sed -ri 's,(PMD_PCAP=).*,\1y,' build/.config
sed -ri 's/CONFIG_RTE_BUILD_SHARED_LIB=n/CONFIG_RTE_BUILD_SHARED_LIB=y/'
build/.config
sudo yum install libpcap-devel
make
Then the make fails some ways in as below...
[labuser@bw-x3650 dpdk]$ git rev-parse HEAD
20e2b6eba13d9eb61b23ea75f09f2aa966fa6325
[labuser@bw-x3650 dpdk]$ uname -r
2.6.32-642.11.1.el6.x86_64
[labuser@bw-x3650 dpdk]$ cat /etc/redhat-release
CentOS release 6.8 (Final)
[labuser@bw-x3650 dpdk]$ make
== Build lib
== Build lib/librte_compat
== Build lib/librte_eal
== Build lib/librte_eal/common
== Build lib/librte_eal/linuxapp
== Build lib/librte_eal/linuxapp/eal
LD librte_eal.so.2.1
INSTALL-LIB librte_eal.so.2.1
== Build lib/librte_eal/linuxapp/igb_uio
(cat /dev/null; echo
kernel//home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko;)
>
/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/igb_uio/modules.order
Building modules, stage 2.
MODPOST 1 modules
== Build lib/librte_eal/linuxapp/kni
CC [M]
/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni/ixgbe_main.o
In file included from
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_osdep.h:41,
from
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_type.h:31,
from
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe_dcb.h:32,
from
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/ixgbe.h:52,
from
/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni/ixgbe_main.c:56:
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/kcompat.h:
In function ‘__kc_vlan_get_protocol’:
/home/labuser/projects/dpdk/lib/librte_eal/linuxapp/kni/ethtool/ixgbe/kcompat.h:2836:
error: implicit declaration of function ‘vlan_tx_tag_present’
make[8]: ***
[/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni/ixgbe_main.o]
Error 1
make[7]: ***
[_module_/home/labuser/projects/dpdk/build/build/lib/librte_eal/linuxapp/kni]
Error 2
make[6]: *** [sub-make] Error 2
make[5]: *** [rte_kni.ko] Error 2
make[4]: *** [kni] Error 2
make[3]: *** [linuxapp] Error 2
make[2]: *** [librte_eal] Error 2
make[1]: *** [lib] Error 2
make: *** [all] Error 2
Google suggested some hacks; but I'm out of my element in driver source. Is
this a lost cause and I should try to get the server up to CentOS 7? Or is
there a relatively simple (if untested) patch that we could try? Our
objective here is to get through the DPDK and our net/ark PMD build process
and see if we can run some of our most-basic packet ingress/egress ops on
our Arkville IP in this system.
Thanks in advance for any constructive feedback. Happy Holidays All. -Shep
Shepard Siegel, CTO
atomicrules.com
^ permalink raw reply
* Re: Packet is not being sent
From: Wiles, Keith @ 2016-12-28 14:07 UTC (permalink / raw)
To: April Teodoro; +Cc: dev@dpdk.org
In-Reply-To: <PS1PR02MB15953C90704018E789CA3404BF680@PS1PR02MB1595.apcprd02.prod.outlook.com>
> On Dec 27, 2016, at 11:38 PM, April Teodoro <ateodoro@hotmail.ph> wrote:
>
>
>
>
> ________________________________
> From: April Teodoro <ateodoro@hotmail.ph>
> Sent: Wednesday, December 28, 2016 1:36 PM
> To: dev@dpdk.org
> Subject: Packet is not being sent
>
>
> i, I am wondering what is causing the packet to be dropped. Please help me.
>
> The mempool was created and retrieved via lookup
>
> The port and queues have been verified to be correct.
>
>
> However, according to stats, no packet is transmitted, although rte_eth_tx_burst returns 1. I also do not receive anything on the connected machine.
Hard to tell if all of the initializations have been done correctly in the snap shot below, but please try the testpmd or pktgen to verify the ports are working correctly. If you can not send with those two apps then I would suggest it is something to do with your hardware or system configuration.
>
> 532 if(mem == NULL)
> 533 {
> 534 LOG <<"No mem";
> 535 }
> 536 else{
> 537 LOG << "has mem";
> 538 }
> 539
> 540 rte_mbuf *mbufs = rte_pktmbuf_alloc(mem);
> 541 if(NULL == mbufs)
> 542 {
> 543 LOG << "ALLOCATION failed";
> 544 }
> 545 else
> 546 {
> 547 LOG << "ALLOCATION successful";
> 548 }
> 549
> 550 uint8_t* messageToSend = NULL;
> 551 LOG << "SENDRAW 2";
> 552 ether_addr addr;
> 553 rte_eth_macaddr_get(port, &addr);
> 554 LOG << "start port 2: " << rte_eth_dev_start(2);
>
> 569 ether_addr_copy(&addr, &hdr->s_addr);
> 570 hdr->ether_type = rte_cpu_to_be_16(0x9998);
> 571 mbufs->pkt_len = mbufs->data_len = 8;
> 572
> 573 messageToSend = (uint8_t*)&hdr[2];
> 574
> 575 for(auto i=0u; i < sendmsg.header.msgSize; ++i) {
> 576 messageToSend[i] = sendmsg.data[i];
> 577 }
> 578
> 579 LOG << "SENDRAW " << sendmsg.header.msgSize;
> 580 mbufs->pkt_len = sendmsg.header.msgSize;
> 581 LOG << "SENDRAW 5";
> 582 LOG << "SENDRAW 6";
> 583 rte_mbuf *mbufArray[] = {mbufs};
> 584 rte_pktmbuf_refcnt_update(mbufs, 1);
> 585 LOG << "SENDRAW 7";
> 586 //uint16_t nbPk = rte_eth_tx_burst(2, 0, mbufArray, 1);
> 587 uint32_t sent = 0;
> 588 struct rte_eth_dev_info dev_info;
> 589 struct rte_eth_stats stats;
> 590 LOG << "stats successful? " << rte_eth_stats_get(2, &stats);
> 591 rte_eth_dev_info_get(2, &dev_info);
> 592 LOG << "dev info: " << (dev_info.pci_dev->addr.bus);
> 593 while (1) {
> 594 sent = rte_eth_tx_burst(2, 0, mbufArray, 1);
> 595 if (sent > 0) {
> 596 LOG << "opackets: " << stats.opackets;
> 597 LOG << "obytes: " << stats.obytes;
> 598 LOG << "oerrors: " << stats.oerrors;
> 599 LOG << "packets transmitted " << sent;
> 600 return;
> 601 }
> 602 }
> 603
> 604
> 605 }
Regards,
Keith
^ permalink raw reply
* Re: DPDK: Inter VM communication of iperf3 TCP throughput is very low on same host compare to non DPDK throughput
From: Bodireddy, Bhanuprakash @ 2016-12-28 13:16 UTC (permalink / raw)
To: Rajalakshmi Prabhakar, dev@dpdk.org, users@dpdk.org
In-Reply-To: <PS1PR0401MB13871547D2F1E41A1A5DCDE390690@PS1PR0401MB1387.apcprd04.prod.outlook.com>
>-----Original Message-----
>From: Rajalakshmi Prabhakar [mailto:krajalakshmi@tataelxsi.co.in]
>Sent: Tuesday, December 27, 2016 9:52 AM
>To: dev@dpdk.org; users@dpdk.org
>Cc: Bodireddy, Bhanuprakash <bhanuprakash.bodireddy@intel.com>
>Subject: DPDK: Inter VM communication of iperf3 TCP throughput is very low
>on same host compare to non DPDK throughput
>
>Hello,
>Kindly Support me to get high throughput in inter VM communication of iperf3
>TCP in OpenStack DPDK host. I am not sure that I am mailing to the right ID
>sorry for the inconvenience.
OVS mailing list should be the appropriate one for the problem you reported here.
Use ovs-discuss@openvswitch.org (or) dev@openvswitch.org.
>
>Host - ubuntu16.04
>devstack - stable/newton
>which install DPDK 16.07 and OVS 2.6 versions
>with DPDK plugin and following DPDK configurations
>Grub changes
>GRUB_CMDLINE_LINUX_DEFAULT="quiet splash default_hugepagesz=1G
>hugepagesz=1G hugepages=8 iommu=pt intel_iommu=on"
>local.conf - changes for DPDK
>enable_plugin networking-ovs-dpdk
>https://git.openstack.org/openstack/networking-ovs-dpdk master
>OVS_DPDK_MODE=controller_ovs_dpdk
>OVS_NUM_HUGEPAGES=8
>OVS_CORE_MASK=2
>OVS_PMD_CORE_MASK=4
Only one PMD core is used in your case, scaling the PMD threads can be one option for higher throughputs.
>OVS_DPDK_BIND_PORT=False
>OVS_SOCKET_MEM=2048
>OVS_DPDK_VHOST_USER_DEBUG=n
>OVS_ALLOCATE_HUGEPAGES=True
>OVS_HUGEPAGE_MOUNT_PAGESIZE=1G
>MULTI_HOST=1
>OVS_DATAPATH_TYPE=netdev
>before VM creation
>#nova flavor-key m1.small set hw:mem_page_size=1048576
>Able to create two ubuntu instance in flavor m1.small
How many cores are assigned for the VM and have you tried CPU pinning options instead of allowing the threads to float across the cores?
>Achieved iperf3 tcp throughput of ~7.5Gbps
Are you seeing high drops at the vHost ports and retransmissions? Do you see the same throughput difference with UDP traffic?
However I can't explain now the throughput gap you are observing here. Couple of things worth checking
- For thread starvation (htop to see thread activity on the cores)
- I see that you have single socket setup and no QPI involved. As you have HT enabled, check if appropriate thread siblings are used.
- Check pmd thread/port statistics for anomaly.
BTW, the responses can be slow at this point due to yearend vacation.
Regards,
Bhanuprakash.
>Ensured the vhostport is created and HugePage is consumed at the end of
>2VM created each of 2GB ie 4GB for VMs and 2GB for socket totally 6GB
>$ sudo cat /proc/meminfo |grep Huge
>AnonHugePages: 0 kB
>HugePages_Total: 8
>HugePages_Free: 2
>HugePages_Rsvd: 0
>HugePages_Surp: 0
>Hugepagesize: 1048576 kB
>The same scenario carried for without DPDK case of openstack and achieved
>higher throughput of ~19Gbps, which is contradictory to the expected results.
>Kindly suggest me what additional DPDK configuration to be done for high
>throughput. Also tried cpu pinning and multi queue for OpenStack DPDK but
>no improvement in the result.
>Test PC is single NUMA only.I am not doing NIC binding as only trying to
>validate inter-VM communication in same host. PFB my PC configurations.
>$ lscpu
>Architecture: x86_64
>CPU op-mode(s): 32-bit, 64-bit
>Byte Order: Little Endian
>CPU(s): 12
>On-line CPU(s) list: 0-11
>Thread(s) per core: 2
>Core(s) per socket: 6
>Socket(s): 1
>NUMA node(s): 1
>Vendor ID: GenuineIntel
>CPU family: 6
>Model: 63
>Model name: Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz
>Stepping: 2
>CPU MHz: 1212.000
>CPU max MHz: 2400.0000
>CPU min MHz: 1200.0000
>BogoMIPS: 4794.08
>Virtualization: VT-x
>L1d cache: 32K
>L1i cache: 32K
>L2 cache: 256K
>L3 cache: 15360K
>NUMA node0 CPU(s): 0-11
>Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat
>pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1g b
>rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology
>nonstop_t sc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx
>smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic
>movbe popcnt tsc_deadline _timer aes xsave avx f16c rdrand lahf_lm abm
>epb tpr_shadow vnmi flexpriority ep t vpid fsgsbase tsc_adjust bmi1 avx2
>smep bmi2 erms invpcid cqm xsaveopt cqm_llc cqm_occup_llc dtherm ida arat
>pln pts
>I am following INSTALL.DPDK.ADVANCED.md but no clue on low throughput.
>
>
>Best Regards
>Rajalakshmi Prabhakar
>
>Specialist - Communication BU | Wireless Division
>TATA ELXSI
>IITM Research park , Kanagam road , Taramani , Chennai 600 113 India
>Tel +91 44 66775031 Cell +91 9789832957
>www.tataelxsi.com
^ permalink raw reply
* Re: [PATCH v2 5/6] net/virtio: fix multiple process support
From: Yuanhan Liu @ 2016-12-28 11:14 UTC (permalink / raw)
To: dev; +Cc: stable, Juho Snellman, Yaron Illouz
In-Reply-To: <1482922962-21036-6-git-send-email-yuanhan.liu@linux.intel.com>
On Wed, Dec 28, 2016 at 07:02:41PM +0800, Yuanhan Liu wrote:
...
> Cc: stable@kernel.org
I knew I would make a mistake like this some day :/
Not my first time typing wrong, but it's the first time sending it out.
Sorry for that. Fixed in this reply.
--yliu
^ permalink raw reply
* [PATCH v2 2/6] net/virtio: fix wrong Rx/Tx method for secondary process
From: Yuanhan Liu @ 2016-12-28 11:02 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu, stable
In-Reply-To: <1482922962-21036-1-git-send-email-yuanhan.liu@linux.intel.com>
If the primary enables the vector Rx/Tx path, the current code would
let the secondary always choose the non vector Rx/Tx path. This results
to a Rx/Tx method mismatch between primary and secondary process. Werid
errors then may happen, something like:
PMD: virtio_xmit_pkts() tx: virtqueue_enqueue error: -14
Fix it by choosing the correct Rx/Tx callbacks for the secondary process.
That is, use vector path if it's given.
Fixes: 8d8393fb1861 ("virtio: pick simple Rx/Tx")
Cc: stable@dpdk.org
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
v2: fix a checkpatch warning: use {} consistently
---
drivers/net/virtio/virtio_ethdev.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..ef37ad1 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1304,7 +1304,12 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
- rx_func_get(eth_dev);
+ if (hw->use_simple_rxtx) {
+ eth_dev->tx_pkt_burst = virtio_xmit_pkts_simple;
+ eth_dev->rx_pkt_burst = virtio_recv_pkts_vec;
+ } else {
+ rx_func_get(eth_dev);
+ }
return 0;
}
--
2.8.1
^ permalink raw reply related
* [PATCH v2 1/6] ethdev: fix port data mismatched in multiple process model
From: Yuanhan Liu @ 2016-12-28 11:02 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu, stable, Thomas Monjalon, Bruce Richardson,
Ferruh Yigit
In-Reply-To: <1482922962-21036-1-git-send-email-yuanhan.liu@linux.intel.com>
Assume we have two virtio ports, 00:03.0 and 00:04.0. The first one is
managed by the kernel driver, while the later one is managed by DPDK.
Now we start the primary process. 00:03.0 will be skipped by DPDK virtio
PMD driver (since it's being used by the kernel). 00:04.0 would be
successfully initiated by DPDK virtio PMD (if nothing abnormal happens).
After that, we would get a port id 0, and all the related info needed
by virtio (virtio_hw) is stored at rte_eth_dev_data[0].
Then we start the secondary process. As usual, 00:03.0 will be firstly
probed. It firstly tries to get a local eth_dev structure for it (by
rte_eth_dev_allocate):
port_id = rte_eth_dev_find_free_port();
...
eth_dev = &rte_eth_devices[port_id];
eth_dev->data = &rte_eth_dev_data[port_id];
...
return eth_dev;
Since it's a first PCI device, port_id will be 0. eth_dev->data would
then point to rte_eth_dev_data[0]. And here things start going wrong,
as rte_eth_dev_data[0] actually stores the virtio_hw for 00:04.0.
That said, in the secondary process, DPDK will continue to drive PCI
device 00.03.0 (despite the fact it's been managed by kernel), with
the info from PCI device 00:04.0. Which is wrong.
The fix is to attach the port already registered by the primary process:
iterate the rte_eth_dev_data[], and get the port id who's PCI ID matches
the current PCI device.
This would let us maintain same port ID for the same PCI device, keeping
the chance of referencing to wrong data minimal.
Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Cc: Thomas Monjalon <thomas.monjalon@6wind.com>
Cc: Bruce Richardson <bruce.richardson@intel.com>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_ether/rte_ethdev.c | 58 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 52 insertions(+), 6 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..c10eb9c 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -201,9 +201,6 @@ rte_eth_dev_allocate(const char *name)
return NULL;
}
- if (rte_eth_dev_data == NULL)
- rte_eth_dev_data_alloc();
-
if (rte_eth_dev_allocated(name) != NULL) {
RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n",
name);
@@ -231,6 +228,38 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
return 0;
}
+/*
+ * Attach to a port already registered by the primary process, which
+ * makes sure that the same device would both have the same port id
+ * in the primary and secondary process.
+ */
+static struct rte_eth_dev *
+eth_dev_attach(const char *name)
+{
+ uint8_t i;
+ struct rte_eth_dev *eth_dev;
+
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+ break;
+ }
+ if (i == RTE_MAX_ETHPORTS) {
+ RTE_PMD_DEBUG_TRACE(
+ "device %s is not driven by the primary process\n",
+ name);
+ return NULL;
+ }
+
+ RTE_ASSERT(eth_dev->data->port_id == i);
+
+ eth_dev = &rte_eth_devices[i];
+ eth_dev->data = &rte_eth_dev_data[i];
+ eth_dev->attached = DEV_ATTACHED;
+ nb_ports++;
+
+ return eth_dev;
+}
+
int
rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
struct rte_pci_device *pci_dev)
@@ -246,9 +275,26 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
sizeof(ethdev_name));
- eth_dev = rte_eth_dev_allocate(ethdev_name);
- if (eth_dev == NULL)
- return -ENOMEM;
+ if (rte_eth_dev_data == NULL)
+ rte_eth_dev_data_alloc();
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+ } else {
+ /*
+ * if we failed to attach a device, it means that
+ * device is skipped, due to some errors. Take
+ * virtio-net device as example, it could be the
+ * device is managed by virtio-net kernel driver.
+ * For such case, we return a positive value, to
+ * let EAL skip it as well.
+ */
+ eth_dev = eth_dev_attach(ethdev_name);
+ if (eth_dev == NULL)
+ return 1;
+ }
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
--
2.8.1
^ permalink raw reply related
* [PATCH v2 5/6] net/virtio: fix multiple process support
From: Yuanhan Liu @ 2016-12-28 11:02 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu, stable, Juho Snellman, Yaron Illouz
In-Reply-To: <1482922962-21036-1-git-send-email-yuanhan.liu@linux.intel.com>
The introduce of virtio 1.0 support brings yet another set of ops, badly,
it's not handled correctly, that it breaks the multiple process support.
The issue is the data/function pointer may vary from different processes,
and the old used to do one time set (for primary process only). That
said, the function pointer the secondary process saw is actually from the
primary process space. Accessing it could likely result to a crash.
Kudos to the last patches, we now be able to maintain those info that may
vary among different process locally, meaning every process could have its
own copy for each of them, with the correct value set. And this is what
this patch does:
- remap the PCI (IO port for legacy device and memory map for modern
device)
- set vtpci_ops correctly
After that, multiple process would work like a charm. (At least, it
passed my fuzzy test)
Fixes: b8f04520ad71 ("virtio: use PCI ioport API")
Fixes: d5bbeefca826 ("virtio: introduce PCI implementation structure")
Fixes: 6ba1f63b5ab0 ("virtio: support specification 1.0")
Cc: stable@kernel.org
Cc: Juho Snellman <jsnell@iki.fi>
Cc: Yaron Illouz <yaroni@radcom.com>
Reported-by: Juho Snellman <jsnell@iki.fi>
Reported-by: Yaron Illouz <yaroni@radcom.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 53 +++++++++++++++++++++++++++++++--
drivers/net/virtio/virtio_pci.c | 4 +--
drivers/net/virtio/virtio_pci.h | 4 +++
drivers/net/virtio/virtio_user_ethdev.c | 2 +-
4 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 5567aa2..19d4348 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1289,6 +1289,49 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
}
/*
+ * Remap the PCI device again (IO port map for legacy device and
+ * memory map for modern device), so that the secondary process
+ * could have the PCI initiated correctly.
+ */
+static int
+virtio_remap_pci(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
+{
+ if (hw->modern) {
+ /*
+ * We don't have to re-parse the PCI config space, since
+ * rte_eal_pci_map_device() makes sure the mapped address
+ * in secondary process would equal to the one mapped in
+ * the primary process: error will be returned if that
+ * requirement is not met.
+ *
+ * That said, we could simply reuse all cap pointers
+ * (such as dev_cfg, common_cfg, etc.) parsed from the
+ * primary process, which is stored in shared memory.
+ */
+ if (rte_eal_pci_map_device(pci_dev)) {
+ PMD_INIT_LOG(DEBUG, "failed to map pci device!");
+ return -1;
+ }
+ } else {
+ if (rte_eal_pci_ioport_map(pci_dev, 0, VTPCI_IO(hw)) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+virtio_set_vtpci_ops(struct rte_pci_device *pci_dev, struct virtio_hw *hw)
+{
+ if (pci_dev == NULL)
+ VTPCI_OPS(hw) = &virtio_user_ops;
+ else if (hw->modern)
+ VTPCI_OPS(hw) = &modern_ops;
+ else
+ VTPCI_OPS(hw) = &legacy_ops;
+}
+
+/*
* This function is based on probe() function in virtio_pci.c
* It returns 0 on success.
*/
@@ -1296,7 +1339,7 @@ int
eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
{
struct virtio_hw *hw = eth_dev->data->dev_private;
- struct rte_pci_device *pci_dev;
+ struct rte_pci_device *pci_dev = eth_dev->pci_dev;
uint32_t dev_flags = RTE_ETH_DEV_DETACHABLE;
int ret;
@@ -1306,6 +1349,13 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ if (pci_dev) {
+ ret = virtio_remap_pci(pci_dev, hw);
+ if (ret)
+ return ret;
+ }
+
+ virtio_set_vtpci_ops(pci_dev, hw);
if (hw->use_simple_rxtx) {
eth_dev->tx_pkt_burst = virtio_xmit_pkts_simple;
eth_dev->rx_pkt_burst = virtio_recv_pkts_vec;
@@ -1325,7 +1375,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
}
hw->port_id = eth_dev->data->port_id;
- pci_dev = eth_dev->pci_dev;
if (pci_dev) {
ret = vtpci_init(pci_dev, hw, &dev_flags);
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index d1e9c05..f5754e5 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -303,7 +303,7 @@ legacy_virtio_resource_init(struct rte_pci_device *pci_dev,
return 0;
}
-static const struct virtio_pci_ops legacy_ops = {
+const struct virtio_pci_ops legacy_ops = {
.read_dev_cfg = legacy_read_dev_config,
.write_dev_cfg = legacy_write_dev_config,
.reset = legacy_reset,
@@ -519,7 +519,7 @@ modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
io_write16(1, vq->notify_addr);
}
-static const struct virtio_pci_ops modern_ops = {
+const struct virtio_pci_ops modern_ops = {
.read_dev_cfg = modern_read_dev_config,
.write_dev_cfg = modern_write_dev_config,
.reset = modern_reset,
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 6b9aecf..511a1c8 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -333,4 +333,8 @@ uint8_t vtpci_isr(struct virtio_hw *);
uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
+extern const struct virtio_pci_ops legacy_ops;
+extern const struct virtio_pci_ops modern_ops;
+extern const struct virtio_pci_ops virtio_user_ops;
+
#endif /* _VIRTIO_PCI_H_ */
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 7d2a9d9..3563952 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -212,7 +212,7 @@ virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq)
strerror(errno));
}
-static const struct virtio_pci_ops virtio_user_ops = {
+const struct virtio_pci_ops virtio_user_ops = {
.read_dev_cfg = virtio_user_read_dev_config,
.write_dev_cfg = virtio_user_write_dev_config,
.reset = virtio_user_reset,
--
2.8.1
^ permalink raw reply related
* [PATCH v2 6/6] net/virtio: remove dead structure field
From: Yuanhan Liu @ 2016-12-28 11:02 UTC (permalink / raw)
To: dev; +Cc: Yuanhan Liu
In-Reply-To: <1482922962-21036-1-git-send-email-yuanhan.liu@linux.intel.com>
Actually, virtio_hw->dev is not used since the beginning when it's
introduced. Remove it.
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
drivers/net/virtio/virtio_pci.c | 2 --
drivers/net/virtio/virtio_pci.h | 1 -
2 files changed, 3 deletions(-)
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index f5754e5..fbdb5b7 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -730,8 +730,6 @@ int
vtpci_init(struct rte_pci_device *dev, struct virtio_hw *hw,
uint32_t *dev_flags)
{
- hw->dev = dev;
-
/*
* Try if we can succeed reading virtio pci caps, which exists
* only on modern pci device. If failed, we fallback to legacy
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 511a1c8..4235bef 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -258,7 +258,6 @@ struct virtio_hw {
uint32_t notify_off_multiplier;
uint8_t *isr;
uint16_t *notify_base;
- struct rte_pci_device *dev;
struct virtio_pci_common_cfg *common_cfg;
struct virtio_net_config *dev_cfg;
void *virtio_user_dev;
--
2.8.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox