18fd92a66SOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause 2e60fbd5bSAdrien Mazarguil * Copyright 2015 6WIND S.A. 3e60fbd5bSAdrien Mazarguil * Copyright 2015 Mellanox. 4e60fbd5bSAdrien Mazarguil */ 58fd92a66SOlivier Matz 63f2fe392SNélio Laranjeiro #include <unistd.h> 7e60fbd5bSAdrien Mazarguil 8e60fbd5bSAdrien Mazarguil #include <rte_ether.h> 9ffc905f3SFerruh Yigit #include <rte_ethdev_driver.h> 10198a3c33SNelio Laranjeiro #include <rte_interrupts.h> 11198a3c33SNelio Laranjeiro #include <rte_alarm.h> 12e60fbd5bSAdrien Mazarguil 13e60fbd5bSAdrien Mazarguil #include "mlx5.h" 14e60fbd5bSAdrien Mazarguil #include "mlx5_rxtx.h" 15e60fbd5bSAdrien Mazarguil #include "mlx5_utils.h" 16e60fbd5bSAdrien Mazarguil 17fb732b0aSNélio Laranjeiro /** 18fb732b0aSNélio Laranjeiro * Stop traffic on Tx queues. 19fb732b0aSNélio Laranjeiro * 20fb732b0aSNélio Laranjeiro * @param dev 21fb732b0aSNélio Laranjeiro * Pointer to Ethernet device structure. 22fb732b0aSNélio Laranjeiro */ 236e78005aSNélio Laranjeiro static void 24af4f09f2SNélio Laranjeiro mlx5_txq_stop(struct rte_eth_dev *dev) 256e78005aSNélio Laranjeiro { 26af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 276e78005aSNélio Laranjeiro unsigned int i; 286e78005aSNélio Laranjeiro 296e78005aSNélio Laranjeiro for (i = 0; i != priv->txqs_n; ++i) 30af4f09f2SNélio Laranjeiro mlx5_txq_release(dev, i); 316e78005aSNélio Laranjeiro } 326e78005aSNélio Laranjeiro 33fb732b0aSNélio Laranjeiro /** 34fb732b0aSNélio Laranjeiro * Start traffic on Tx queues. 35fb732b0aSNélio Laranjeiro * 36fb732b0aSNélio Laranjeiro * @param dev 37fb732b0aSNélio Laranjeiro * Pointer to Ethernet device structure. 38fb732b0aSNélio Laranjeiro * 39fb732b0aSNélio Laranjeiro * @return 40*a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 41fb732b0aSNélio Laranjeiro */ 426e78005aSNélio Laranjeiro static int 43af4f09f2SNélio Laranjeiro mlx5_txq_start(struct rte_eth_dev *dev) 446e78005aSNélio Laranjeiro { 45af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 466e78005aSNélio Laranjeiro unsigned int i; 47*a6d83b6aSNélio Laranjeiro int ret; 486e78005aSNélio Laranjeiro 496e78005aSNélio Laranjeiro /* Add memory regions to Tx queues. */ 506e78005aSNélio Laranjeiro for (i = 0; i != priv->txqs_n; ++i) { 516e78005aSNélio Laranjeiro unsigned int idx = 0; 526e78005aSNélio Laranjeiro struct mlx5_mr *mr; 53af4f09f2SNélio Laranjeiro struct mlx5_txq_ctrl *txq_ctrl = mlx5_txq_get(dev, i); 546e78005aSNélio Laranjeiro 556e78005aSNélio Laranjeiro if (!txq_ctrl) 566e78005aSNélio Laranjeiro continue; 57de48f165SYongseok Koh LIST_FOREACH(mr, &priv->mr, next) { 58af4f09f2SNélio Laranjeiro mlx5_txq_mp2mr_reg(&txq_ctrl->txq, mr->mp, idx++); 59de48f165SYongseok Koh if (idx == MLX5_PMD_TX_MP_CACHE) 60de48f165SYongseok Koh break; 61de48f165SYongseok Koh } 626e78005aSNélio Laranjeiro txq_alloc_elts(txq_ctrl); 63af4f09f2SNélio Laranjeiro txq_ctrl->ibv = mlx5_txq_ibv_new(dev, i); 646e78005aSNélio Laranjeiro if (!txq_ctrl->ibv) { 65*a6d83b6aSNélio Laranjeiro rte_errno = ENOMEM; 666e78005aSNélio Laranjeiro goto error; 676e78005aSNélio Laranjeiro } 686e78005aSNélio Laranjeiro } 69af4f09f2SNélio Laranjeiro ret = mlx5_tx_uar_remap(dev, priv->ctx->cmd_fd); 704a984153SXueming Li if (ret) 714a984153SXueming Li goto error; 72*a6d83b6aSNélio Laranjeiro return 0; 736e78005aSNélio Laranjeiro error: 74*a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 75af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 76*a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 77*a6d83b6aSNélio Laranjeiro return -rte_errno; 786e78005aSNélio Laranjeiro } 796e78005aSNélio Laranjeiro 80fb732b0aSNélio Laranjeiro /** 81fb732b0aSNélio Laranjeiro * Stop traffic on Rx queues. 82fb732b0aSNélio Laranjeiro * 83fb732b0aSNélio Laranjeiro * @param dev 84fb732b0aSNélio Laranjeiro * Pointer to Ethernet device structure. 85fb732b0aSNélio Laranjeiro */ 86a1366b1aSNélio Laranjeiro static void 87af4f09f2SNélio Laranjeiro mlx5_rxq_stop(struct rte_eth_dev *dev) 88a1366b1aSNélio Laranjeiro { 89af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 90a1366b1aSNélio Laranjeiro unsigned int i; 91a1366b1aSNélio Laranjeiro 92a1366b1aSNélio Laranjeiro for (i = 0; i != priv->rxqs_n; ++i) 93af4f09f2SNélio Laranjeiro mlx5_rxq_release(dev, i); 94a1366b1aSNélio Laranjeiro } 95a1366b1aSNélio Laranjeiro 96fb732b0aSNélio Laranjeiro /** 97fb732b0aSNélio Laranjeiro * Start traffic on Rx queues. 98fb732b0aSNélio Laranjeiro * 99fb732b0aSNélio Laranjeiro * @param dev 100fb732b0aSNélio Laranjeiro * Pointer to Ethernet device structure. 101fb732b0aSNélio Laranjeiro * 102fb732b0aSNélio Laranjeiro * @return 103*a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 104fb732b0aSNélio Laranjeiro */ 105a1366b1aSNélio Laranjeiro static int 106af4f09f2SNélio Laranjeiro mlx5_rxq_start(struct rte_eth_dev *dev) 107a1366b1aSNélio Laranjeiro { 108af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 109a1366b1aSNélio Laranjeiro unsigned int i; 110a1366b1aSNélio Laranjeiro int ret = 0; 111a1366b1aSNélio Laranjeiro 112a1366b1aSNélio Laranjeiro for (i = 0; i != priv->rxqs_n; ++i) { 113af4f09f2SNélio Laranjeiro struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_get(dev, i); 114a1366b1aSNélio Laranjeiro 115a1366b1aSNélio Laranjeiro if (!rxq_ctrl) 116a1366b1aSNélio Laranjeiro continue; 117a1366b1aSNélio Laranjeiro ret = rxq_alloc_elts(rxq_ctrl); 118a1366b1aSNélio Laranjeiro if (ret) 119a1366b1aSNélio Laranjeiro goto error; 120af4f09f2SNélio Laranjeiro rxq_ctrl->ibv = mlx5_rxq_ibv_new(dev, i); 121*a6d83b6aSNélio Laranjeiro if (!rxq_ctrl->ibv) 122a1366b1aSNélio Laranjeiro goto error; 123a1366b1aSNélio Laranjeiro } 124*a6d83b6aSNélio Laranjeiro return 0; 125a1366b1aSNélio Laranjeiro error: 126*a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 127af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 128*a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 129*a6d83b6aSNélio Laranjeiro return -rte_errno; 130a1366b1aSNélio Laranjeiro } 131a1366b1aSNélio Laranjeiro 132e60fbd5bSAdrien Mazarguil /** 133e60fbd5bSAdrien Mazarguil * DPDK callback to start the device. 134e60fbd5bSAdrien Mazarguil * 135e60fbd5bSAdrien Mazarguil * Simulate device start by attaching all configured flows. 136e60fbd5bSAdrien Mazarguil * 137e60fbd5bSAdrien Mazarguil * @param dev 138e60fbd5bSAdrien Mazarguil * Pointer to Ethernet device structure. 139e60fbd5bSAdrien Mazarguil * 140e60fbd5bSAdrien Mazarguil * @return 141*a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 142e60fbd5bSAdrien Mazarguil */ 143e60fbd5bSAdrien Mazarguil int 144e60fbd5bSAdrien Mazarguil mlx5_dev_start(struct rte_eth_dev *dev) 145e60fbd5bSAdrien Mazarguil { 146e60fbd5bSAdrien Mazarguil struct priv *priv = dev->data->dev_private; 1476e78005aSNélio Laranjeiro struct mlx5_mr *mr = NULL; 148*a6d83b6aSNélio Laranjeiro int ret; 149e60fbd5bSAdrien Mazarguil 150272733b5SNélio Laranjeiro dev->data->dev_started = 1; 151*a6d83b6aSNélio Laranjeiro ret = mlx5_flow_create_drop_queue(dev); 152*a6d83b6aSNélio Laranjeiro if (ret) { 153272733b5SNélio Laranjeiro ERROR("%p: Drop queue allocation failed: %s", 154*a6d83b6aSNélio Laranjeiro (void *)dev, strerror(rte_errno)); 155272733b5SNélio Laranjeiro goto error; 156272733b5SNélio Laranjeiro } 157ecc1c29dSAdrien Mazarguil DEBUG("%p: allocating and configuring hash RX queues", (void *)dev); 1586e78005aSNélio Laranjeiro rte_mempool_walk(mlx5_mp2mr_iter, priv); 159*a6d83b6aSNélio Laranjeiro ret = mlx5_txq_start(dev); 160*a6d83b6aSNélio Laranjeiro if (ret) { 161*a6d83b6aSNélio Laranjeiro ERROR("%p: Tx Queue allocation failed: %s", 162*a6d83b6aSNélio Laranjeiro (void *)dev, strerror(rte_errno)); 1636e78005aSNélio Laranjeiro goto error; 1646e78005aSNélio Laranjeiro } 165*a6d83b6aSNélio Laranjeiro ret = mlx5_rxq_start(dev); 166*a6d83b6aSNélio Laranjeiro if (ret) { 167*a6d83b6aSNélio Laranjeiro ERROR("%p: Rx Queue allocation failed: %s", 168*a6d83b6aSNélio Laranjeiro (void *)dev, strerror(rte_errno)); 169a1366b1aSNélio Laranjeiro goto error; 170a1366b1aSNélio Laranjeiro } 171*a6d83b6aSNélio Laranjeiro ret = mlx5_rx_intr_vec_enable(dev); 172*a6d83b6aSNélio Laranjeiro if (ret) { 173*a6d83b6aSNélio Laranjeiro ERROR("%p: Rx interrupt vector creation failed", 174*a6d83b6aSNélio Laranjeiro (void *)dev); 175e1016cb7SAdrien Mazarguil goto error; 1763c7d44afSShahaf Shuler } 177af4f09f2SNélio Laranjeiro mlx5_xstats_init(dev); 178c7bf6225SYongseok Koh /* Update link status and Tx/Rx callbacks for the first time. */ 179c7bf6225SYongseok Koh memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link)); 180e313ef4cSShahaf Shuler INFO("Forcing port %u link to be up", dev->data->port_id); 181*a6d83b6aSNélio Laranjeiro ret = mlx5_force_link_status_change(dev, ETH_LINK_UP); 182*a6d83b6aSNélio Laranjeiro if (ret) { 183e313ef4cSShahaf Shuler DEBUG("Failed to set port %u link to be up", 184e313ef4cSShahaf Shuler dev->data->port_id); 185e313ef4cSShahaf Shuler goto error; 186e313ef4cSShahaf Shuler } 187af4f09f2SNélio Laranjeiro mlx5_dev_interrupt_handler_install(dev); 188c8d4ee50SNélio Laranjeiro return 0; 189c8d4ee50SNélio Laranjeiro error: 190*a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 191e60fbd5bSAdrien Mazarguil /* Rollback. */ 192272733b5SNélio Laranjeiro dev->data->dev_started = 0; 1935f64e6bfSNélio Laranjeiro for (mr = LIST_FIRST(&priv->mr); mr; mr = LIST_FIRST(&priv->mr)) 194af4f09f2SNélio Laranjeiro mlx5_mr_release(mr); 195af4f09f2SNélio Laranjeiro mlx5_flow_stop(dev, &priv->flows); 196af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 197af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 198af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 199af4f09f2SNélio Laranjeiro mlx5_flow_delete_drop_queue(dev); 200*a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 201*a6d83b6aSNélio Laranjeiro return -rte_errno; 202e60fbd5bSAdrien Mazarguil } 203e60fbd5bSAdrien Mazarguil 204e60fbd5bSAdrien Mazarguil /** 205e60fbd5bSAdrien Mazarguil * DPDK callback to stop the device. 206e60fbd5bSAdrien Mazarguil * 207e60fbd5bSAdrien Mazarguil * Simulate device stop by detaching all configured flows. 208e60fbd5bSAdrien Mazarguil * 209e60fbd5bSAdrien Mazarguil * @param dev 210e60fbd5bSAdrien Mazarguil * Pointer to Ethernet device structure. 211e60fbd5bSAdrien Mazarguil */ 212e60fbd5bSAdrien Mazarguil void 213e60fbd5bSAdrien Mazarguil mlx5_dev_stop(struct rte_eth_dev *dev) 214e60fbd5bSAdrien Mazarguil { 215e60fbd5bSAdrien Mazarguil struct priv *priv = dev->data->dev_private; 2166e78005aSNélio Laranjeiro struct mlx5_mr *mr; 217e60fbd5bSAdrien Mazarguil 2183f2fe392SNélio Laranjeiro dev->data->dev_started = 0; 2193f2fe392SNélio Laranjeiro /* Prevent crashes when queues are still in use. */ 2203f2fe392SNélio Laranjeiro dev->rx_pkt_burst = removed_rx_burst; 2213f2fe392SNélio Laranjeiro dev->tx_pkt_burst = removed_tx_burst; 2223f2fe392SNélio Laranjeiro rte_wmb(); 2233f2fe392SNélio Laranjeiro usleep(1000 * priv->rxqs_n); 224ecc1c29dSAdrien Mazarguil DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev); 225af4f09f2SNélio Laranjeiro mlx5_flow_stop(dev, &priv->flows); 226af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 227af4f09f2SNélio Laranjeiro mlx5_rx_intr_vec_disable(dev); 228af4f09f2SNélio Laranjeiro mlx5_dev_interrupt_handler_uninstall(dev); 229af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 230af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 2315f64e6bfSNélio Laranjeiro for (mr = LIST_FIRST(&priv->mr); mr; mr = LIST_FIRST(&priv->mr)) 232af4f09f2SNélio Laranjeiro mlx5_mr_release(mr); 233af4f09f2SNélio Laranjeiro mlx5_flow_delete_drop_queue(dev); 234e60fbd5bSAdrien Mazarguil } 235272733b5SNélio Laranjeiro 236272733b5SNélio Laranjeiro /** 237272733b5SNélio Laranjeiro * Enable traffic flows configured by control plane 238272733b5SNélio Laranjeiro * 239af4f09f2SNélio Laranjeiro * @param dev 240272733b5SNélio Laranjeiro * Pointer to Ethernet device private data. 241272733b5SNélio Laranjeiro * @param dev 242272733b5SNélio Laranjeiro * Pointer to Ethernet device structure. 243272733b5SNélio Laranjeiro * 244272733b5SNélio Laranjeiro * @return 245*a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 246272733b5SNélio Laranjeiro */ 247272733b5SNélio Laranjeiro int 248af4f09f2SNélio Laranjeiro mlx5_traffic_enable(struct rte_eth_dev *dev) 249272733b5SNélio Laranjeiro { 250af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 251272733b5SNélio Laranjeiro struct rte_flow_item_eth bcast = { 252272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", 253272733b5SNélio Laranjeiro }; 254272733b5SNélio Laranjeiro struct rte_flow_item_eth ipv6_multi_spec = { 255272733b5SNélio Laranjeiro .dst.addr_bytes = "\x33\x33\x00\x00\x00\x00", 256272733b5SNélio Laranjeiro }; 257272733b5SNélio Laranjeiro struct rte_flow_item_eth ipv6_multi_mask = { 258272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\x00\x00\x00\x00", 259272733b5SNélio Laranjeiro }; 260272733b5SNélio Laranjeiro struct rte_flow_item_eth unicast = { 261272733b5SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 262272733b5SNélio Laranjeiro }; 263272733b5SNélio Laranjeiro struct rte_flow_item_eth unicast_mask = { 264272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", 265272733b5SNélio Laranjeiro }; 266272733b5SNélio Laranjeiro const unsigned int vlan_filter_n = priv->vlan_filter_n; 267272733b5SNélio Laranjeiro const struct ether_addr cmp = { 268272733b5SNélio Laranjeiro .addr_bytes = "\x00\x00\x00\x00\x00\x00", 269272733b5SNélio Laranjeiro }; 270272733b5SNélio Laranjeiro unsigned int i; 271272733b5SNélio Laranjeiro unsigned int j; 272272733b5SNélio Laranjeiro int ret; 273272733b5SNélio Laranjeiro 274f8cb4b57SNélio Laranjeiro if (priv->isolated) 275f8cb4b57SNélio Laranjeiro return 0; 276f8cb4b57SNélio Laranjeiro if (dev->data->promiscuous) { 277f8cb4b57SNélio Laranjeiro struct rte_flow_item_eth promisc = { 278f8cb4b57SNélio Laranjeiro .dst.addr_bytes = "\x00\x00\x00\x00\x00\x00", 279f8cb4b57SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 280f8cb4b57SNélio Laranjeiro .type = 0, 281f8cb4b57SNélio Laranjeiro }; 282f8cb4b57SNélio Laranjeiro 283*a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &promisc, &promisc); 284*a6d83b6aSNélio Laranjeiro if (ret) 285*a6d83b6aSNélio Laranjeiro goto error; 286f8cb4b57SNélio Laranjeiro } 287f8cb4b57SNélio Laranjeiro if (dev->data->all_multicast) { 288f8cb4b57SNélio Laranjeiro struct rte_flow_item_eth multicast = { 289f8cb4b57SNélio Laranjeiro .dst.addr_bytes = "\x01\x00\x00\x00\x00\x00", 290f8cb4b57SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 291f8cb4b57SNélio Laranjeiro .type = 0, 292f8cb4b57SNélio Laranjeiro }; 293f8cb4b57SNélio Laranjeiro 294*a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &multicast, &multicast); 295*a6d83b6aSNélio Laranjeiro if (ret) 296*a6d83b6aSNélio Laranjeiro goto error; 297f8cb4b57SNélio Laranjeiro } else { 298f8cb4b57SNélio Laranjeiro /* Add broadcast/multicast flows. */ 299f8cb4b57SNélio Laranjeiro for (i = 0; i != vlan_filter_n; ++i) { 300f8cb4b57SNélio Laranjeiro uint16_t vlan = priv->vlan_filter[i]; 301f8cb4b57SNélio Laranjeiro 302f8cb4b57SNélio Laranjeiro struct rte_flow_item_vlan vlan_spec = { 303f8cb4b57SNélio Laranjeiro .tci = rte_cpu_to_be_16(vlan), 304f8cb4b57SNélio Laranjeiro }; 305f8cb4b57SNélio Laranjeiro struct rte_flow_item_vlan vlan_mask = { 306f8cb4b57SNélio Laranjeiro .tci = 0xffff, 307f8cb4b57SNélio Laranjeiro }; 308f8cb4b57SNélio Laranjeiro 309f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &bcast, &bcast, 310f8cb4b57SNélio Laranjeiro &vlan_spec, &vlan_mask); 311f8cb4b57SNélio Laranjeiro if (ret) 312f8cb4b57SNélio Laranjeiro goto error; 313f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &ipv6_multi_spec, 314f8cb4b57SNélio Laranjeiro &ipv6_multi_mask, 315f8cb4b57SNélio Laranjeiro &vlan_spec, &vlan_mask); 316f8cb4b57SNélio Laranjeiro if (ret) 317f8cb4b57SNélio Laranjeiro goto error; 318f8cb4b57SNélio Laranjeiro } 319f8cb4b57SNélio Laranjeiro if (!vlan_filter_n) { 320f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &bcast, &bcast); 321f8cb4b57SNélio Laranjeiro if (ret) 322f8cb4b57SNélio Laranjeiro goto error; 323f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &ipv6_multi_spec, 324f8cb4b57SNélio Laranjeiro &ipv6_multi_mask); 325f8cb4b57SNélio Laranjeiro if (ret) 326f8cb4b57SNélio Laranjeiro goto error; 327f8cb4b57SNélio Laranjeiro } 328f8cb4b57SNélio Laranjeiro } 329f8cb4b57SNélio Laranjeiro /* Add MAC address flows. */ 330272733b5SNélio Laranjeiro for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) { 331272733b5SNélio Laranjeiro struct ether_addr *mac = &dev->data->mac_addrs[i]; 332272733b5SNélio Laranjeiro 333272733b5SNélio Laranjeiro if (!memcmp(mac, &cmp, sizeof(*mac))) 334272733b5SNélio Laranjeiro continue; 335272733b5SNélio Laranjeiro memcpy(&unicast.dst.addr_bytes, 336272733b5SNélio Laranjeiro mac->addr_bytes, 337272733b5SNélio Laranjeiro ETHER_ADDR_LEN); 338272733b5SNélio Laranjeiro for (j = 0; j != vlan_filter_n; ++j) { 339272733b5SNélio Laranjeiro uint16_t vlan = priv->vlan_filter[j]; 340272733b5SNélio Laranjeiro 341272733b5SNélio Laranjeiro struct rte_flow_item_vlan vlan_spec = { 342272733b5SNélio Laranjeiro .tci = rte_cpu_to_be_16(vlan), 343272733b5SNélio Laranjeiro }; 344272733b5SNélio Laranjeiro struct rte_flow_item_vlan vlan_mask = { 345272733b5SNélio Laranjeiro .tci = 0xffff, 346272733b5SNélio Laranjeiro }; 347272733b5SNélio Laranjeiro 348272733b5SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &unicast, 349272733b5SNélio Laranjeiro &unicast_mask, 350272733b5SNélio Laranjeiro &vlan_spec, 351272733b5SNélio Laranjeiro &vlan_mask); 352272733b5SNélio Laranjeiro if (ret) 353272733b5SNélio Laranjeiro goto error; 354272733b5SNélio Laranjeiro } 355272733b5SNélio Laranjeiro if (!vlan_filter_n) { 356*a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &unicast, &unicast_mask); 357272733b5SNélio Laranjeiro if (ret) 358272733b5SNélio Laranjeiro goto error; 359272733b5SNélio Laranjeiro } 360272733b5SNélio Laranjeiro } 361272733b5SNélio Laranjeiro return 0; 362272733b5SNélio Laranjeiro error: 363*a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 364*a6d83b6aSNélio Laranjeiro mlx5_flow_list_flush(dev, &priv->ctrl_flows); 365*a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 366*a6d83b6aSNélio Laranjeiro return -rte_errno; 367272733b5SNélio Laranjeiro } 368272733b5SNélio Laranjeiro 369272733b5SNélio Laranjeiro 370272733b5SNélio Laranjeiro /** 371272733b5SNélio Laranjeiro * Disable traffic flows configured by control plane 372272733b5SNélio Laranjeiro * 373272733b5SNélio Laranjeiro * @param dev 374af4f09f2SNélio Laranjeiro * Pointer to Ethernet device private data. 375272733b5SNélio Laranjeiro */ 376925061b5SNélio Laranjeiro void 377af4f09f2SNélio Laranjeiro mlx5_traffic_disable(struct rte_eth_dev *dev) 378272733b5SNélio Laranjeiro { 379af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 380272733b5SNélio Laranjeiro 381af4f09f2SNélio Laranjeiro mlx5_flow_list_flush(dev, &priv->ctrl_flows); 382272733b5SNélio Laranjeiro } 383272733b5SNélio Laranjeiro 384272733b5SNélio Laranjeiro /** 385272733b5SNélio Laranjeiro * Restart traffic flows configured by control plane 386272733b5SNélio Laranjeiro * 387272733b5SNélio Laranjeiro * @param dev 388af4f09f2SNélio Laranjeiro * Pointer to Ethernet device private data. 389272733b5SNélio Laranjeiro * 390272733b5SNélio Laranjeiro * @return 391*a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 392272733b5SNélio Laranjeiro */ 393272733b5SNélio Laranjeiro int 394272733b5SNélio Laranjeiro mlx5_traffic_restart(struct rte_eth_dev *dev) 395272733b5SNélio Laranjeiro { 396af4f09f2SNélio Laranjeiro if (dev->data->dev_started) { 397af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 398*a6d83b6aSNélio Laranjeiro return mlx5_traffic_enable(dev); 399af4f09f2SNélio Laranjeiro } 400272733b5SNélio Laranjeiro return 0; 401272733b5SNélio Laranjeiro } 402