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 40a6d83b6aSNé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; 47a6d83b6aSNé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) { 65a6d83b6aSNé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; 72a6d83b6aSNélio Laranjeiro return 0; 736e78005aSNélio Laranjeiro error: 74a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 75af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 76a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 77a6d83b6aSNé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 103a6d83b6aSNé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); 121a6d83b6aSNélio Laranjeiro if (!rxq_ctrl->ibv) 122a1366b1aSNélio Laranjeiro goto error; 123a1366b1aSNélio Laranjeiro } 124a6d83b6aSNélio Laranjeiro return 0; 125a1366b1aSNélio Laranjeiro error: 126a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 127af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 128a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 129a6d83b6aSNé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 141a6d83b6aSNé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; 148a6d83b6aSNélio Laranjeiro int ret; 149e60fbd5bSAdrien Mazarguil 150272733b5SNélio Laranjeiro dev->data->dev_started = 1; 151a6d83b6aSNélio Laranjeiro ret = mlx5_flow_create_drop_queue(dev); 152a6d83b6aSNélio Laranjeiro if (ret) { 153*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u drop queue allocation failed: %s", 1540f99970bSNélio Laranjeiro dev->data->port_id, strerror(rte_errno)); 155272733b5SNélio Laranjeiro goto error; 156272733b5SNélio Laranjeiro } 157*a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "port %u allocating and configuring hash Rx queues", 1580f99970bSNélio Laranjeiro dev->data->port_id); 1596e78005aSNélio Laranjeiro rte_mempool_walk(mlx5_mp2mr_iter, priv); 160a6d83b6aSNélio Laranjeiro ret = mlx5_txq_start(dev); 161a6d83b6aSNélio Laranjeiro if (ret) { 162*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u Tx queue allocation failed: %s", 1630f99970bSNélio Laranjeiro dev->data->port_id, strerror(rte_errno)); 1646e78005aSNélio Laranjeiro goto error; 1656e78005aSNélio Laranjeiro } 166a6d83b6aSNélio Laranjeiro ret = mlx5_rxq_start(dev); 167a6d83b6aSNélio Laranjeiro if (ret) { 168*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u Rx queue allocation failed: %s", 1690f99970bSNélio Laranjeiro dev->data->port_id, strerror(rte_errno)); 170a1366b1aSNélio Laranjeiro goto error; 171a1366b1aSNélio Laranjeiro } 172a6d83b6aSNélio Laranjeiro ret = mlx5_rx_intr_vec_enable(dev); 173a6d83b6aSNélio Laranjeiro if (ret) { 174*a170a30dSNélio Laranjeiro DRV_LOG(ERR, "port %u Rx interrupt vector creation failed", 1750f99970bSNélio Laranjeiro dev->data->port_id); 176e1016cb7SAdrien Mazarguil goto error; 1773c7d44afSShahaf Shuler } 178af4f09f2SNélio Laranjeiro mlx5_xstats_init(dev); 179c7bf6225SYongseok Koh /* Update link status and Tx/Rx callbacks for the first time. */ 180c7bf6225SYongseok Koh memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link)); 181*a170a30dSNélio Laranjeiro DRV_LOG(INFO, "forcing port %u link to be up", dev->data->port_id); 182a6d83b6aSNélio Laranjeiro ret = mlx5_force_link_status_change(dev, ETH_LINK_UP); 183a6d83b6aSNélio Laranjeiro if (ret) { 184*a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "failed to set port %u link to be up", 185e313ef4cSShahaf Shuler dev->data->port_id); 186e313ef4cSShahaf Shuler goto error; 187e313ef4cSShahaf Shuler } 188af4f09f2SNélio Laranjeiro mlx5_dev_interrupt_handler_install(dev); 189c8d4ee50SNélio Laranjeiro return 0; 190c8d4ee50SNélio Laranjeiro error: 191a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 192e60fbd5bSAdrien Mazarguil /* Rollback. */ 193272733b5SNélio Laranjeiro dev->data->dev_started = 0; 1945f64e6bfSNélio Laranjeiro for (mr = LIST_FIRST(&priv->mr); mr; mr = LIST_FIRST(&priv->mr)) 195af4f09f2SNélio Laranjeiro mlx5_mr_release(mr); 196af4f09f2SNélio Laranjeiro mlx5_flow_stop(dev, &priv->flows); 197af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 198af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 199af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 200af4f09f2SNélio Laranjeiro mlx5_flow_delete_drop_queue(dev); 201a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 202a6d83b6aSNélio Laranjeiro return -rte_errno; 203e60fbd5bSAdrien Mazarguil } 204e60fbd5bSAdrien Mazarguil 205e60fbd5bSAdrien Mazarguil /** 206e60fbd5bSAdrien Mazarguil * DPDK callback to stop the device. 207e60fbd5bSAdrien Mazarguil * 208e60fbd5bSAdrien Mazarguil * Simulate device stop by detaching all configured flows. 209e60fbd5bSAdrien Mazarguil * 210e60fbd5bSAdrien Mazarguil * @param dev 211e60fbd5bSAdrien Mazarguil * Pointer to Ethernet device structure. 212e60fbd5bSAdrien Mazarguil */ 213e60fbd5bSAdrien Mazarguil void 214e60fbd5bSAdrien Mazarguil mlx5_dev_stop(struct rte_eth_dev *dev) 215e60fbd5bSAdrien Mazarguil { 216e60fbd5bSAdrien Mazarguil struct priv *priv = dev->data->dev_private; 2176e78005aSNélio Laranjeiro struct mlx5_mr *mr; 218e60fbd5bSAdrien Mazarguil 2193f2fe392SNélio Laranjeiro dev->data->dev_started = 0; 2203f2fe392SNélio Laranjeiro /* Prevent crashes when queues are still in use. */ 2213f2fe392SNélio Laranjeiro dev->rx_pkt_burst = removed_rx_burst; 2223f2fe392SNélio Laranjeiro dev->tx_pkt_burst = removed_tx_burst; 2233f2fe392SNélio Laranjeiro rte_wmb(); 2243f2fe392SNélio Laranjeiro usleep(1000 * priv->rxqs_n); 225*a170a30dSNélio Laranjeiro DRV_LOG(DEBUG, "port %u cleaning up and destroying hash Rx queues", 2260f99970bSNélio Laranjeiro dev->data->port_id); 227af4f09f2SNélio Laranjeiro mlx5_flow_stop(dev, &priv->flows); 228af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 229af4f09f2SNélio Laranjeiro mlx5_rx_intr_vec_disable(dev); 230af4f09f2SNélio Laranjeiro mlx5_dev_interrupt_handler_uninstall(dev); 231af4f09f2SNélio Laranjeiro mlx5_txq_stop(dev); 232af4f09f2SNélio Laranjeiro mlx5_rxq_stop(dev); 2335f64e6bfSNélio Laranjeiro for (mr = LIST_FIRST(&priv->mr); mr; mr = LIST_FIRST(&priv->mr)) 234af4f09f2SNélio Laranjeiro mlx5_mr_release(mr); 235af4f09f2SNélio Laranjeiro mlx5_flow_delete_drop_queue(dev); 236e60fbd5bSAdrien Mazarguil } 237272733b5SNélio Laranjeiro 238272733b5SNélio Laranjeiro /** 239272733b5SNélio Laranjeiro * Enable traffic flows configured by control plane 240272733b5SNélio Laranjeiro * 241af4f09f2SNélio Laranjeiro * @param dev 242272733b5SNélio Laranjeiro * Pointer to Ethernet device private data. 243272733b5SNélio Laranjeiro * @param dev 244272733b5SNélio Laranjeiro * Pointer to Ethernet device structure. 245272733b5SNélio Laranjeiro * 246272733b5SNélio Laranjeiro * @return 247a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 248272733b5SNélio Laranjeiro */ 249272733b5SNélio Laranjeiro int 250af4f09f2SNélio Laranjeiro mlx5_traffic_enable(struct rte_eth_dev *dev) 251272733b5SNélio Laranjeiro { 252af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 253272733b5SNélio Laranjeiro struct rte_flow_item_eth bcast = { 254272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", 255272733b5SNélio Laranjeiro }; 256272733b5SNélio Laranjeiro struct rte_flow_item_eth ipv6_multi_spec = { 257272733b5SNélio Laranjeiro .dst.addr_bytes = "\x33\x33\x00\x00\x00\x00", 258272733b5SNélio Laranjeiro }; 259272733b5SNélio Laranjeiro struct rte_flow_item_eth ipv6_multi_mask = { 260272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\x00\x00\x00\x00", 261272733b5SNélio Laranjeiro }; 262272733b5SNélio Laranjeiro struct rte_flow_item_eth unicast = { 263272733b5SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 264272733b5SNélio Laranjeiro }; 265272733b5SNélio Laranjeiro struct rte_flow_item_eth unicast_mask = { 266272733b5SNélio Laranjeiro .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff", 267272733b5SNélio Laranjeiro }; 268272733b5SNélio Laranjeiro const unsigned int vlan_filter_n = priv->vlan_filter_n; 269272733b5SNélio Laranjeiro const struct ether_addr cmp = { 270272733b5SNélio Laranjeiro .addr_bytes = "\x00\x00\x00\x00\x00\x00", 271272733b5SNélio Laranjeiro }; 272272733b5SNélio Laranjeiro unsigned int i; 273272733b5SNélio Laranjeiro unsigned int j; 274272733b5SNélio Laranjeiro int ret; 275272733b5SNélio Laranjeiro 276f8cb4b57SNélio Laranjeiro if (priv->isolated) 277f8cb4b57SNélio Laranjeiro return 0; 278f8cb4b57SNélio Laranjeiro if (dev->data->promiscuous) { 279f8cb4b57SNélio Laranjeiro struct rte_flow_item_eth promisc = { 280f8cb4b57SNélio Laranjeiro .dst.addr_bytes = "\x00\x00\x00\x00\x00\x00", 281f8cb4b57SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 282f8cb4b57SNélio Laranjeiro .type = 0, 283f8cb4b57SNélio Laranjeiro }; 284f8cb4b57SNélio Laranjeiro 285a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &promisc, &promisc); 286a6d83b6aSNélio Laranjeiro if (ret) 287a6d83b6aSNélio Laranjeiro goto error; 288f8cb4b57SNélio Laranjeiro } 289f8cb4b57SNélio Laranjeiro if (dev->data->all_multicast) { 290f8cb4b57SNélio Laranjeiro struct rte_flow_item_eth multicast = { 291f8cb4b57SNélio Laranjeiro .dst.addr_bytes = "\x01\x00\x00\x00\x00\x00", 292f8cb4b57SNélio Laranjeiro .src.addr_bytes = "\x00\x00\x00\x00\x00\x00", 293f8cb4b57SNélio Laranjeiro .type = 0, 294f8cb4b57SNélio Laranjeiro }; 295f8cb4b57SNélio Laranjeiro 296a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &multicast, &multicast); 297a6d83b6aSNélio Laranjeiro if (ret) 298a6d83b6aSNélio Laranjeiro goto error; 299f8cb4b57SNélio Laranjeiro } else { 300f8cb4b57SNélio Laranjeiro /* Add broadcast/multicast flows. */ 301f8cb4b57SNélio Laranjeiro for (i = 0; i != vlan_filter_n; ++i) { 302f8cb4b57SNélio Laranjeiro uint16_t vlan = priv->vlan_filter[i]; 303f8cb4b57SNélio Laranjeiro 304f8cb4b57SNélio Laranjeiro struct rte_flow_item_vlan vlan_spec = { 305f8cb4b57SNélio Laranjeiro .tci = rte_cpu_to_be_16(vlan), 306f8cb4b57SNélio Laranjeiro }; 307f8cb4b57SNélio Laranjeiro struct rte_flow_item_vlan vlan_mask = { 308f8cb4b57SNélio Laranjeiro .tci = 0xffff, 309f8cb4b57SNélio Laranjeiro }; 310f8cb4b57SNélio Laranjeiro 311f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &bcast, &bcast, 312f8cb4b57SNélio Laranjeiro &vlan_spec, &vlan_mask); 313f8cb4b57SNélio Laranjeiro if (ret) 314f8cb4b57SNélio Laranjeiro goto error; 315f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &ipv6_multi_spec, 316f8cb4b57SNélio Laranjeiro &ipv6_multi_mask, 317f8cb4b57SNélio Laranjeiro &vlan_spec, &vlan_mask); 318f8cb4b57SNélio Laranjeiro if (ret) 319f8cb4b57SNélio Laranjeiro goto error; 320f8cb4b57SNélio Laranjeiro } 321f8cb4b57SNélio Laranjeiro if (!vlan_filter_n) { 322f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &bcast, &bcast); 323f8cb4b57SNélio Laranjeiro if (ret) 324f8cb4b57SNélio Laranjeiro goto error; 325f8cb4b57SNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &ipv6_multi_spec, 326f8cb4b57SNélio Laranjeiro &ipv6_multi_mask); 327f8cb4b57SNélio Laranjeiro if (ret) 328f8cb4b57SNélio Laranjeiro goto error; 329f8cb4b57SNélio Laranjeiro } 330f8cb4b57SNélio Laranjeiro } 331f8cb4b57SNélio Laranjeiro /* Add MAC address flows. */ 332272733b5SNélio Laranjeiro for (i = 0; i != MLX5_MAX_MAC_ADDRESSES; ++i) { 333272733b5SNélio Laranjeiro struct ether_addr *mac = &dev->data->mac_addrs[i]; 334272733b5SNélio Laranjeiro 335272733b5SNélio Laranjeiro if (!memcmp(mac, &cmp, sizeof(*mac))) 336272733b5SNélio Laranjeiro continue; 337272733b5SNélio Laranjeiro memcpy(&unicast.dst.addr_bytes, 338272733b5SNélio Laranjeiro mac->addr_bytes, 339272733b5SNélio Laranjeiro ETHER_ADDR_LEN); 340272733b5SNélio Laranjeiro for (j = 0; j != vlan_filter_n; ++j) { 341272733b5SNélio Laranjeiro uint16_t vlan = priv->vlan_filter[j]; 342272733b5SNélio Laranjeiro 343272733b5SNélio Laranjeiro struct rte_flow_item_vlan vlan_spec = { 344272733b5SNélio Laranjeiro .tci = rte_cpu_to_be_16(vlan), 345272733b5SNélio Laranjeiro }; 346272733b5SNélio Laranjeiro struct rte_flow_item_vlan vlan_mask = { 347272733b5SNélio Laranjeiro .tci = 0xffff, 348272733b5SNélio Laranjeiro }; 349272733b5SNélio Laranjeiro 350272733b5SNélio Laranjeiro ret = mlx5_ctrl_flow_vlan(dev, &unicast, 351272733b5SNélio Laranjeiro &unicast_mask, 352272733b5SNélio Laranjeiro &vlan_spec, 353272733b5SNélio Laranjeiro &vlan_mask); 354272733b5SNélio Laranjeiro if (ret) 355272733b5SNélio Laranjeiro goto error; 356272733b5SNélio Laranjeiro } 357272733b5SNélio Laranjeiro if (!vlan_filter_n) { 358a6d83b6aSNélio Laranjeiro ret = mlx5_ctrl_flow(dev, &unicast, &unicast_mask); 359272733b5SNélio Laranjeiro if (ret) 360272733b5SNélio Laranjeiro goto error; 361272733b5SNélio Laranjeiro } 362272733b5SNélio Laranjeiro } 363272733b5SNélio Laranjeiro return 0; 364272733b5SNélio Laranjeiro error: 365a6d83b6aSNélio Laranjeiro ret = rte_errno; /* Save rte_errno before cleanup. */ 366a6d83b6aSNélio Laranjeiro mlx5_flow_list_flush(dev, &priv->ctrl_flows); 367a6d83b6aSNélio Laranjeiro rte_errno = ret; /* Restore rte_errno. */ 368a6d83b6aSNélio Laranjeiro return -rte_errno; 369272733b5SNélio Laranjeiro } 370272733b5SNélio Laranjeiro 371272733b5SNélio Laranjeiro 372272733b5SNélio Laranjeiro /** 373272733b5SNélio Laranjeiro * Disable traffic flows configured by control plane 374272733b5SNélio Laranjeiro * 375272733b5SNélio Laranjeiro * @param dev 376af4f09f2SNélio Laranjeiro * Pointer to Ethernet device private data. 377272733b5SNélio Laranjeiro */ 378925061b5SNélio Laranjeiro void 379af4f09f2SNélio Laranjeiro mlx5_traffic_disable(struct rte_eth_dev *dev) 380272733b5SNélio Laranjeiro { 381af4f09f2SNélio Laranjeiro struct priv *priv = dev->data->dev_private; 382272733b5SNélio Laranjeiro 383af4f09f2SNélio Laranjeiro mlx5_flow_list_flush(dev, &priv->ctrl_flows); 384272733b5SNélio Laranjeiro } 385272733b5SNélio Laranjeiro 386272733b5SNélio Laranjeiro /** 387272733b5SNélio Laranjeiro * Restart traffic flows configured by control plane 388272733b5SNélio Laranjeiro * 389272733b5SNélio Laranjeiro * @param dev 390af4f09f2SNélio Laranjeiro * Pointer to Ethernet device private data. 391272733b5SNélio Laranjeiro * 392272733b5SNélio Laranjeiro * @return 393a6d83b6aSNélio Laranjeiro * 0 on success, a negative errno value otherwise and rte_errno is set. 394272733b5SNélio Laranjeiro */ 395272733b5SNélio Laranjeiro int 396272733b5SNélio Laranjeiro mlx5_traffic_restart(struct rte_eth_dev *dev) 397272733b5SNélio Laranjeiro { 398af4f09f2SNélio Laranjeiro if (dev->data->dev_started) { 399af4f09f2SNélio Laranjeiro mlx5_traffic_disable(dev); 400a6d83b6aSNélio Laranjeiro return mlx5_traffic_enable(dev); 401af4f09f2SNélio Laranjeiro } 402272733b5SNélio Laranjeiro return 0; 403272733b5SNélio Laranjeiro } 404