18fd92a66SOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause 2e9086978SAdrien Mazarguil * Copyright 2015 6WIND S.A. 35feecc57SShahaf Shuler * Copyright 2015 Mellanox Technologies, Ltd 4e9086978SAdrien Mazarguil */ 5e9086978SAdrien Mazarguil 6e9086978SAdrien Mazarguil #include <stddef.h> 7e9086978SAdrien Mazarguil #include <errno.h> 8e9086978SAdrien Mazarguil #include <stdint.h> 9c12671e3SMatan Azrad #include <unistd.h> 10c12671e3SMatan Azrad 11df96fd0dSBruce Richardson #include <ethdev_driver.h> 12e9086978SAdrien Mazarguil #include <rte_common.h> 13c12671e3SMatan Azrad #include <rte_malloc.h> 14c12671e3SMatan Azrad #include <rte_hypervisor.h> 15e9086978SAdrien Mazarguil 16e9086978SAdrien Mazarguil #include "mlx5.h" 17f3db9489SYaacov Hazan #include "mlx5_autoconf.h" 18227684feSYongseok Koh #include "mlx5_rxtx.h" 19151cbe3aSMichael Baum #include "mlx5_rx.h" 20227684feSYongseok Koh #include "mlx5_utils.h" 218bb2410eSOphir Munk #include "mlx5_devx.h" 22e9086978SAdrien Mazarguil 23e9086978SAdrien Mazarguil /** 24e9086978SAdrien Mazarguil * DPDK callback to configure a VLAN filter. 25e9086978SAdrien Mazarguil * 26e9086978SAdrien Mazarguil * @param dev 27e9086978SAdrien Mazarguil * Pointer to Ethernet device structure. 28e9086978SAdrien Mazarguil * @param vlan_id 29e9086978SAdrien Mazarguil * VLAN ID to filter. 30e9086978SAdrien Mazarguil * @param on 31e9086978SAdrien Mazarguil * Toggle filter. 32e9086978SAdrien Mazarguil * 33e9086978SAdrien Mazarguil * @return 34a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 35e9086978SAdrien Mazarguil */ 36e9086978SAdrien Mazarguil int 37e9086978SAdrien Mazarguil mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 38e9086978SAdrien Mazarguil { 39dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 40272733b5SNélio Laranjeiro unsigned int i; 41e9086978SAdrien Mazarguil 42a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "port %u %s VLAN filter ID %" PRIu16, 430f99970bSNélio Laranjeiro dev->data->port_id, (on ? "enable" : "disable"), vlan_id); 448e46d4e1SAlexander Kozyrev MLX5_ASSERT(priv->vlan_filter_n <= RTE_DIM(priv->vlan_filter)); 45272733b5SNélio Laranjeiro for (i = 0; (i != priv->vlan_filter_n); ++i) 46272733b5SNélio Laranjeiro if (priv->vlan_filter[i] == vlan_id) 47272733b5SNélio Laranjeiro break; 48e4aefd6dSNélio Laranjeiro /* Check if there's room for another VLAN filter. */ 49e4aefd6dSNélio Laranjeiro if (i == RTE_DIM(priv->vlan_filter)) { 50a6d83b6aSNélio Laranjeiro rte_errno = ENOMEM; 51a6d83b6aSNélio Laranjeiro return -rte_errno; 52e4aefd6dSNélio Laranjeiro } 53272733b5SNélio Laranjeiro if (i < priv->vlan_filter_n) { 548e46d4e1SAlexander Kozyrev MLX5_ASSERT(priv->vlan_filter_n != 0); 55272733b5SNélio Laranjeiro /* Enabling an existing VLAN filter has no effect. */ 56272733b5SNélio Laranjeiro if (on) 57*46532860SDariusz Sosnowski goto no_effect; 58272733b5SNélio Laranjeiro /* Remove VLAN filter from list. */ 59272733b5SNélio Laranjeiro --priv->vlan_filter_n; 60272733b5SNélio Laranjeiro memmove(&priv->vlan_filter[i], 61272733b5SNélio Laranjeiro &priv->vlan_filter[i + 1], 62272733b5SNélio Laranjeiro sizeof(priv->vlan_filter[i]) * 63272733b5SNélio Laranjeiro (priv->vlan_filter_n - i)); 64272733b5SNélio Laranjeiro priv->vlan_filter[priv->vlan_filter_n] = 0; 65272733b5SNélio Laranjeiro } else { 668e46d4e1SAlexander Kozyrev MLX5_ASSERT(i == priv->vlan_filter_n); 67272733b5SNélio Laranjeiro /* Disabling an unknown VLAN filter has no effect. */ 68272733b5SNélio Laranjeiro if (!on) 69*46532860SDariusz Sosnowski goto no_effect; 70272733b5SNélio Laranjeiro /* Add new VLAN filter. */ 71272733b5SNélio Laranjeiro priv->vlan_filter[priv->vlan_filter_n] = vlan_id; 72272733b5SNélio Laranjeiro ++priv->vlan_filter_n; 73272733b5SNélio Laranjeiro } 74*46532860SDariusz Sosnowski return on ? mlx5_traffic_vlan_add(dev, vlan_id) : mlx5_traffic_vlan_remove(dev, vlan_id); 75*46532860SDariusz Sosnowski no_effect: 76a6d83b6aSNélio Laranjeiro return 0; 77e9086978SAdrien Mazarguil } 78f3db9489SYaacov Hazan 79f3db9489SYaacov Hazan /** 80f3db9489SYaacov Hazan * Callback to set/reset VLAN stripping for a specific queue. 81f3db9489SYaacov Hazan * 82f3db9489SYaacov Hazan * @param dev 83f3db9489SYaacov Hazan * Pointer to Ethernet device structure. 84f3db9489SYaacov Hazan * @param queue 85f3db9489SYaacov Hazan * RX queue index. 86f3db9489SYaacov Hazan * @param on 87f3db9489SYaacov Hazan * Enable/disable VLAN stripping. 88f3db9489SYaacov Hazan */ 89f3db9489SYaacov Hazan void 90f3db9489SYaacov Hazan mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on) 91f3db9489SYaacov Hazan { 92dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 935ceb3a02SXueming Li struct mlx5_rxq_priv *rxq = mlx5_rxq_get(dev, queue); 945ceb3a02SXueming Li struct mlx5_rxq_data *rxq_data = &rxq->ctrl->rxq; 95dc9ceff7SDekel Peled int ret = 0; 96f3db9489SYaacov Hazan 975ceb3a02SXueming Li MLX5_ASSERT(rxq != NULL && rxq->ctrl != NULL); 98f3db9489SYaacov Hazan /* Validate hw support */ 9987af0d1eSMichael Baum if (!priv->sh->dev_cap.hw_vlan_strip) { 100a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u VLAN stripping is not supported", 1010f99970bSNélio Laranjeiro dev->data->port_id); 102f3db9489SYaacov Hazan return; 103f3db9489SYaacov Hazan } 104f3db9489SYaacov Hazan /* Validate queue number */ 105f3db9489SYaacov Hazan if (queue >= priv->rxqs_n) { 106a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u VLAN stripping, invalid queue number %d", 1070f99970bSNélio Laranjeiro dev->data->port_id, queue); 108f3db9489SYaacov Hazan return; 109f3db9489SYaacov Hazan } 1108bb2410eSOphir Munk DRV_LOG(DEBUG, "port %u set VLAN stripping offloads %d for port %uqueue %d", 1115ceb3a02SXueming Li dev->data->port_id, on, rxq_data->port_id, queue); 1125ceb3a02SXueming Li if (rxq->ctrl->obj == NULL) { 113af4f09f2SNélio Laranjeiro /* Update related bits in RX queue. */ 1145ceb3a02SXueming Li rxq_data->vlan_strip = !!on; 115af4f09f2SNélio Laranjeiro return; 116af4f09f2SNélio Laranjeiro } 1175ceb3a02SXueming Li ret = priv->obj_ops.rxq_obj_modify_vlan_strip(rxq, on); 118a6d83b6aSNélio Laranjeiro if (ret) { 119e96242efSMichael Baum DRV_LOG(ERR, "Port %u failed to modify object stripping mode:" 120e96242efSMichael Baum " %s", dev->data->port_id, strerror(rte_errno)); 121af4f09f2SNélio Laranjeiro return; 122af4f09f2SNélio Laranjeiro } 123af4f09f2SNélio Laranjeiro /* Update related bits in RX queue. */ 1245ceb3a02SXueming Li rxq_data->vlan_strip = !!on; 125f3db9489SYaacov Hazan } 126f3db9489SYaacov Hazan 127f3db9489SYaacov Hazan /** 128f3db9489SYaacov Hazan * Callback to set/reset VLAN offloads for a port. 129f3db9489SYaacov Hazan * 130f3db9489SYaacov Hazan * @param dev 131f3db9489SYaacov Hazan * Pointer to Ethernet device structure. 132f3db9489SYaacov Hazan * @param mask 133f3db9489SYaacov Hazan * VLAN offload bit mask. 134a6d83b6aSNélio Laranjeiro * 135a6d83b6aSNélio Laranjeiro * @return 136a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 137f3db9489SYaacov Hazan */ 138289ba0c0SDavid Harton int 139f3db9489SYaacov Hazan mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask) 140f3db9489SYaacov Hazan { 141dbeba4cfSThomas Monjalon struct mlx5_priv *priv = dev->data->dev_private; 142f3db9489SYaacov Hazan unsigned int i; 143f3db9489SYaacov Hazan 144295968d1SFerruh Yigit if (mask & RTE_ETH_VLAN_STRIP_MASK) { 14517b843ebSShahaf Shuler int hw_vlan_strip = !!(dev->data->dev_conf.rxmode.offloads & 146295968d1SFerruh Yigit RTE_ETH_RX_OFFLOAD_VLAN_STRIP); 147f3db9489SYaacov Hazan 14887af0d1eSMichael Baum if (!priv->sh->dev_cap.hw_vlan_strip) { 149a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u VLAN stripping is not supported", 1500f99970bSNélio Laranjeiro dev->data->port_id); 151289ba0c0SDavid Harton return 0; 152f3db9489SYaacov Hazan } 153f3db9489SYaacov Hazan /* Run on every RX queue and set/reset VLAN stripping. */ 154f3db9489SYaacov Hazan for (i = 0; (i != priv->rxqs_n); i++) 155af4f09f2SNélio Laranjeiro mlx5_vlan_strip_queue_set(dev, i, hw_vlan_strip); 156f3db9489SYaacov Hazan } 157289ba0c0SDavid Harton return 0; 158f3db9489SYaacov Hazan } 159