On Mon, Mar 16, 2020 at 03:03:41PM +0530, Harman Kalra wrote: > From: Vamsi Attunuru <vattun...@marvell.com> > > Patch adds support for vlan filter offload support. > MBOX messages for vlan filter on/off and vlan filter > entry add/rm are added to configure PCAM entries to > filter out the vlan traffic on a given port. > > Patch also defines rx_offload_flag for vlan filtering. > > Signed-off-by: Vamsi Attunuru <vattun...@marvell.com>
Acked-by: Harman Kalra <hka...@marvell.com> > --- > doc/guides/nics/features/octeontx.ini | 2 + > doc/guides/nics/octeontx.rst | 1 + > drivers/net/octeontx/Makefile | 1 + > drivers/net/octeontx/base/octeontx_pkivf.c | 40 +++++ > drivers/net/octeontx/base/octeontx_pkivf.h | 20 +++ > drivers/net/octeontx/meson.build | 3 +- > drivers/net/octeontx/octeontx_ethdev.c | 10 ++ > drivers/net/octeontx/octeontx_ethdev.h | 24 ++- > drivers/net/octeontx/octeontx_ethdev_ops.c | 184 +++++++++++++++++++++ > drivers/net/octeontx/octeontx_rxtx.h | 1 + > 10 files changed, 284 insertions(+), 2 deletions(-) > create mode 100644 drivers/net/octeontx/octeontx_ethdev_ops.c > > diff --git a/doc/guides/nics/features/octeontx.ini > b/doc/guides/nics/features/octeontx.ini > index e3ee79f0f..53c541f4b 100644 > --- a/doc/guides/nics/features/octeontx.ini > +++ b/doc/guides/nics/features/octeontx.ini > @@ -13,6 +13,8 @@ Jumbo frame = Y > Scattered Rx = Y > Promiscuous mode = Y > Unicast MAC filter = Y > +VLAN filter = Y > +VLAN offload = P > CRC offload = Y > Packet type parsing = Y > Basic stats = Y > diff --git a/doc/guides/nics/octeontx.rst b/doc/guides/nics/octeontx.rst > index ddb626bc3..c8655bf37 100644 > --- a/doc/guides/nics/octeontx.rst > +++ b/doc/guides/nics/octeontx.rst > @@ -22,6 +22,7 @@ Features of the OCTEON TX Ethdev PMD are: > - Jumbo frames > - Scatter-Gather IO support > - Link state information > +- MAC/VLAN filtering > - MTU update > - SR-IOV VF > - Multiple queues for TX > diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile > index 8ddfc3089..694f403f1 100644 > --- a/drivers/net/octeontx/Makefile > +++ b/drivers/net/octeontx/Makefile > @@ -28,6 +28,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkovf.c > SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkivf.c > SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_bgx.c > SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev.c > +SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev_ops.c > > ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) > CFLAGS_octeontx_rxtx.o += -fno-prefetch-loop-arrays > diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c > b/drivers/net/octeontx/base/octeontx_pkivf.c > index 8ce041955..0ddff5488 100644 > --- a/drivers/net/octeontx/base/octeontx_pkivf.c > +++ b/drivers/net/octeontx/base/octeontx_pkivf.c > @@ -136,6 +136,46 @@ octeontx_pki_port_errchk_config(int port, > pki_errchk_cfg_t *cfg) > return res; > } > > +int > +octeontx_pki_port_vlan_fltr_config(int port, > + pki_port_vlan_filter_config_t *fltr_cfg) > +{ > + struct octeontx_mbox_hdr hdr; > + int res; > + > + pki_port_vlan_filter_config_t cfg = *fltr_cfg; > + int len = sizeof(pki_port_vlan_filter_config_t); > + > + hdr.coproc = OCTEONTX_PKI_COPROC; > + hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_CONFIG; > + hdr.vfid = port; > + > + res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0); > + if (res < 0) > + return -EACCES; > + return res; > +} > + > +int > +octeontx_pki_port_vlan_fltr_entry_config(int port, > + pki_port_vlan_filter_entry_config_t *e_cfg) > +{ > + struct octeontx_mbox_hdr hdr; > + int res; > + > + pki_port_vlan_filter_entry_config_t cfg = *e_cfg; > + int len = sizeof(pki_port_vlan_filter_entry_config_t); > + > + hdr.coproc = OCTEONTX_PKI_COPROC; > + hdr.msg = MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG; > + hdr.vfid = port; > + > + res = octeontx_mbox_send(&hdr, &cfg, len, NULL, 0); > + if (res < 0) > + return -EACCES; > + return res; > +} > + > #define PCI_VENDOR_ID_CAVIUM 0x177D > #define PCI_DEVICE_ID_OCTEONTX_PKI_VF 0xA0DD > > diff --git a/drivers/net/octeontx/base/octeontx_pkivf.h > b/drivers/net/octeontx/base/octeontx_pkivf.h > index d541dc3bd..d41eaa57e 100644 > --- a/drivers/net/octeontx/base/octeontx_pkivf.h > +++ b/drivers/net/octeontx/base/octeontx_pkivf.h > @@ -36,6 +36,8 @@ > #define MBOX_PKI_PORT_ALLOC_QPG 21 > #define MBOX_PKI_PORT_FREE_QPG 22 > #define MBOX_PKI_SET_PORT_CONFIG 23 > +#define MBOX_PKI_PORT_VLAN_FILTER_CONFIG 24 > +#define MBOX_PKI_PORT_VLAN_FILTER_ENTRY_CONFIG 25 > > #define MBOX_PKI_MAX_QOS_ENTRY 64 > > @@ -236,6 +238,20 @@ typedef struct pki_port_modify_qos_entry { > struct pki_qos_entry qos_entry; > } pki_mod_qos_t; > > +/* pki port VLAN filter config */ > +typedef struct pki_port_vlan_filter_config { > + uint8_t port_type; /* OCTTX_PORT_TYPE_[NET/INT/PCI] */ > + uint8_t fltr_conf; /* '1' to enable & '0' to disable */ > +} pki_port_vlan_filter_config_t; > + > +/* pki port VLAN filter entry config */ > +typedef struct pki_port_vlan_filter_entry_config { > + uint8_t port_type; /* OCTTX_PORT_TYPE_[NET/INT/PCI] */ > + uint8_t entry_conf; /* '1' to add & '0' to remove */ > + uint16_t vlan_tpid; /* in host byte-order */ > + uint16_t vlan_id; /* in host byte-order */ > +} pki_port_vlan_filter_entry_config_t; > + > static inline int > octeontx_pki_port_modify_qos(int port, pki_mod_qos_t *qos_cfg) > { > @@ -348,5 +364,9 @@ int octeontx_pki_port_pktbuf_config(int port, > pki_pktbuf_cfg_t *buf_cfg); > int octeontx_pki_port_create_qos(int port, pki_qos_cfg_t *qos_cfg); > int octeontx_pki_port_close(int port); > int octeontx_pki_port_errchk_config(int port, pki_errchk_cfg_t *cfg); > +int octeontx_pki_port_vlan_fltr_config(int port, > + pki_port_vlan_filter_config_t *fltr_cfg); > +int octeontx_pki_port_vlan_fltr_entry_config(int port, > + pki_port_vlan_filter_entry_config_t *entry_cfg); > > #endif /* __OCTEONTX_PKI_H__ */ > diff --git a/drivers/net/octeontx/meson.build > b/drivers/net/octeontx/meson.build > index 0e249eb98..f7ba6e68b 100644 > --- a/drivers/net/octeontx/meson.build > +++ b/drivers/net/octeontx/meson.build > @@ -5,7 +5,8 @@ subdir('base') > objs = [base_objs] > > sources = files('octeontx_rxtx.c', > - 'octeontx_ethdev.c' > + 'octeontx_ethdev.c', > + 'octeontx_ethdev_ops.c' > ) > > allow_experimental_apis = true > diff --git a/drivers/net/octeontx/octeontx_ethdev.c > b/drivers/net/octeontx/octeontx_ethdev.c > index 91b9ea645..5dd40bc04 100644 > --- a/drivers/net/octeontx/octeontx_ethdev.c > +++ b/drivers/net/octeontx/octeontx_ethdev.c > @@ -360,6 +360,12 @@ octeontx_dev_configure(struct rte_eth_dev *dev) > return -EFAULT; > } > > + ret = octeontx_dev_vlan_offload_init(dev); > + if (ret) { > + octeontx_log_err("failed to initialize vlan offload"); > + return -EFAULT; > + } > + > nic->pki.classifier_enable = false; > nic->pki.hash_enable = true; > nic->pki.initialized = false; > @@ -384,6 +390,8 @@ octeontx_dev_close(struct rte_eth_dev *dev) > > rte_event_dev_close(nic->evdev); > > + octeontx_dev_vlan_offload_fini(dev); > + > ret = octeontx_pko_channel_close(nic->base_ochan); > if (ret < 0) { > octeontx_log_err("failed to close channel %d VF%d %d %d", > @@ -1185,6 +1193,8 @@ static const struct eth_dev_ops octeontx_dev_ops = { > .mac_addr_remove = octeontx_dev_mac_addr_del, > .mac_addr_add = octeontx_dev_mac_addr_add, > .mac_addr_set = octeontx_dev_default_mac_addr_set, > + .vlan_offload_set = octeontx_dev_vlan_offload_set, > + .vlan_filter_set = octeontx_dev_vlan_filter_set, > .tx_queue_start = octeontx_dev_tx_queue_start, > .tx_queue_stop = octeontx_dev_tx_queue_stop, > .tx_queue_setup = octeontx_dev_tx_queue_setup, > diff --git a/drivers/net/octeontx/octeontx_ethdev.h > b/drivers/net/octeontx/octeontx_ethdev.h > index 27f6556dd..e7e0d40c7 100644 > --- a/drivers/net/octeontx/octeontx_ethdev.h > +++ b/drivers/net/octeontx/octeontx_ethdev.h > @@ -55,7 +55,8 @@ > > #define OCTEONTX_RX_OFFLOADS (DEV_RX_OFFLOAD_CHECKSUM | \ > DEV_RX_OFFLOAD_SCATTER | \ > - DEV_RX_OFFLOAD_JUMBO_FRAME) > + DEV_RX_OFFLOAD_JUMBO_FRAME | \ > + DEV_RX_OFFLOAD_VLAN_FILTER) > > #define OCTEONTX_TX_OFFLOADS (DEV_TX_OFFLOAD_MT_LOCKFREE | \ > DEV_TX_OFFLOAD_MBUF_FAST_FREE | \ > @@ -70,6 +71,18 @@ octeontx_pmd_priv(struct rte_eth_dev *dev) > extern uint16_t > rte_octeontx_pchan_map[OCTEONTX_MAX_BGX_PORTS][OCTEONTX_MAX_LMAC_PER_BGX]; > > +struct vlan_entry { > + TAILQ_ENTRY(vlan_entry) next; > + uint16_t vlan_id; > +}; > + > +TAILQ_HEAD(octeontx_vlan_filter_tbl, vlan_entry); > + > +struct octeontx_vlan_info { > + struct octeontx_vlan_filter_tbl fltr_tbl; > + uint8_t filter_on; > +}; > + > /* Octeontx ethdev nic */ > struct octeontx_nic { > struct rte_eth_dev *dev; > @@ -107,6 +120,7 @@ struct octeontx_nic { > uint16_t rx_offload_flags; > uint64_t tx_offloads; > uint16_t tx_offload_flags; > + struct octeontx_vlan_info vlan_info; > } __rte_cache_aligned; > > struct octeontx_txq { > @@ -127,4 +141,12 @@ struct octeontx_rxq { > > void > octeontx_set_tx_function(struct rte_eth_dev *dev); > + > +/* VLAN */ > +int octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev); > +int octeontx_dev_vlan_offload_fini(struct rte_eth_dev *eth_dev); > +int octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask); > +int octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, > + uint16_t vlan_id, int on); > + > #endif /* __OCTEONTX_ETHDEV_H__ */ > diff --git a/drivers/net/octeontx/octeontx_ethdev_ops.c > b/drivers/net/octeontx/octeontx_ethdev_ops.c > new file mode 100644 > index 000000000..8c3065542 > --- /dev/null > +++ b/drivers/net/octeontx/octeontx_ethdev_ops.c > @@ -0,0 +1,184 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2020 Marvell International Ltd. > + */ > + > +#include <rte_malloc.h> > + > +#include "octeontx_ethdev.h" > +#include "octeontx_logs.h" > +#include "octeontx_rxtx.h" > + > +static int > +octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag) > +{ > + struct octeontx_vlan_info *vlan = &nic->vlan_info; > + pki_port_vlan_filter_config_t fltr_conf; > + int rc = 0; > + > + if (vlan->filter_on == flag) > + return rc; > + > + fltr_conf.port_type = OCTTX_PORT_TYPE_NET; > + fltr_conf.fltr_conf = flag; > + > + rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf); > + if (rc != 0) { > + octeontx_log_err("Fail to configure vlan hw filter for port %d", > + nic->port_id); > + goto done; > + } > + > + vlan->filter_on = flag; > + > +done: > + return rc; > +} > + > +int > +octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) > +{ > + struct octeontx_nic *nic = octeontx_pmd_priv(dev); > + struct rte_eth_rxmode *rxmode; > + int rc = 0; > + > + rxmode = &dev->data->dev_conf.rxmode; > + > + if (mask & ETH_VLAN_EXTEND_MASK) { > + octeontx_log_err("Extend offload not supported"); > + return -ENOTSUP; > + } > + > + if (mask & ETH_VLAN_STRIP_MASK) { > + octeontx_log_err("VLAN strip offload not supported"); > + return -ENOTSUP; > + } > + > + if (mask & ETH_VLAN_FILTER_MASK) { > + if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { > + rc = octeontx_vlan_hw_filter(nic, true); > + if (rc) > + goto done; > + > + nic->rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; > + nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F; > + } else { > + rc = octeontx_vlan_hw_filter(nic, false); > + if (rc) > + goto done; > + > + nic->rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER; > + nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F; > + } > + } > + > +done: > + return rc; > +} > + > +int > +octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int > on) > +{ > + struct octeontx_nic *nic = octeontx_pmd_priv(dev); > + struct octeontx_vlan_info *vlan = &nic->vlan_info; > + pki_port_vlan_filter_entry_config_t fltr_entry; > + struct vlan_entry *entry = NULL; > + int entry_count = 0; > + int rc = -EINVAL; > + > + if (on) { > + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) > + if (entry->vlan_id == vlan_id) { > + octeontx_log_dbg("Vlan Id is already set"); > + return 0; > + } > + } else { > + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) > + entry_count++; > + > + if (!entry_count) > + return 0; > + } > + > + fltr_entry.port_type = OCTTX_PORT_TYPE_NET; > + fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN; > + fltr_entry.vlan_id = vlan_id; > + fltr_entry.entry_conf = on; > + > + if (on) { > + entry = rte_zmalloc("octeontx_nic_vlan_entry", > + sizeof(struct vlan_entry), 0); > + if (!entry) { > + octeontx_log_err("Failed to allocate memory"); > + return -ENOMEM; > + } > + } > + > + rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id, > + &fltr_entry); > + if (rc != 0) { > + octeontx_log_err("Fail to configure vlan filter entry " > + "for port %d", nic->port_id); > + if (entry) > + rte_free(entry); > + > + goto done; > + } > + > + if (on) { > + entry->vlan_id = vlan_id; > + TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next); > + } else { > + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { > + if (entry->vlan_id == vlan_id) { > + TAILQ_REMOVE(&vlan->fltr_tbl, entry, next); > + rte_free(entry); > + break; > + } > + } > + } > + > +done: > + return rc; > +} > + > +int > +octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev) > +{ > + struct octeontx_nic *nic = octeontx_pmd_priv(dev); > + int rc; > + > + TAILQ_INIT(&nic->vlan_info.fltr_tbl); > + > + rc = octeontx_dev_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); > + if (rc) > + octeontx_log_err("Failed to set vlan offload rc=%d", rc); > + > + return rc; > +} > + > +int > +octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev) > +{ > + struct octeontx_nic *nic = octeontx_pmd_priv(dev); > + struct octeontx_vlan_info *vlan = &nic->vlan_info; > + pki_port_vlan_filter_entry_config_t fltr_entry; > + struct vlan_entry *entry; > + int rc = 0; > + > + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { > + fltr_entry.port_type = OCTTX_PORT_TYPE_NET; > + fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN; > + fltr_entry.vlan_id = entry->vlan_id; > + fltr_entry.entry_conf = 0; > + > + rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id, > + &fltr_entry); > + if (rc != 0) { > + octeontx_log_err("Fail to configure vlan filter entry " > + "for port %d", nic->port_id); > + break; > + } > + } > + > + return rc; > +} > diff --git a/drivers/net/octeontx/octeontx_rxtx.h > b/drivers/net/octeontx/octeontx_rxtx.h > index 2383a8eb6..cc044dd79 100644 > --- a/drivers/net/octeontx/octeontx_rxtx.h > +++ b/drivers/net/octeontx/octeontx_rxtx.h > @@ -19,6 +19,7 @@ > > #define OCCTX_RX_OFFLOAD_NONE (0) > #define OCCTX_RX_OFFLOAD_RSS_F BIT(0) > +#define OCCTX_RX_VLAN_FLTR_F BIT(1) > #define OCCTX_RX_MULTI_SEG_F BIT(15) > > #define OCCTX_TX_OFFLOAD_NONE (0) > -- > 2.18.0 >