/** * DPDK callback to start the device. * * Simulate device start by attaching all configured flows. * * @param dev * Pointer to Ethernet device structure. * * @return * 0 on success, negative errno value on failure. */ int mlx5_dev_start(struct rte_eth_dev *dev) { struct priv *priv = dev->data->dev_private; int err; if (mlx5_is_secondary()) return -E_RTE_SECONDARY; priv_lock(priv); if (priv->started) { priv_unlock(priv); return 0; } DEBUG("%p: allocating and configuring hash RX queues", (void *)dev); err = priv_create_hash_rxqs(priv); if (!err) err = priv_rehash_flows(priv); if (!err) priv->started = 1; else { ERROR("%p: an error occurred while configuring hash RX queues:" " %s", (void *)priv, strerror(err)); /* Rollback. */ priv_special_flow_disable_all(priv); priv_mac_addrs_disable(priv); priv_destroy_hash_rxqs(priv); } if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE) priv_fdir_enable(priv); priv_dev_interrupt_handler_install(priv, dev); priv_unlock(priv); return -err; }
/** * DPDK callback to enable allmulti mode. * * @param dev * Pointer to Ethernet device structure. */ void mlx5_allmulticast_enable(struct rte_eth_dev *dev) { if (mlx5_is_secondary()) return; dev->data->all_multicast = 1; mlx5_traffic_restart(dev); }
/** * DPDK callback to disable promiscuous mode. * * @param dev * Pointer to Ethernet device structure. */ void mlx5_promiscuous_disable(struct rte_eth_dev *dev) { if (mlx5_is_secondary()) return; dev->data->promiscuous = 0; mlx5_traffic_restart(dev); }
/** * Return private structure associated with an Ethernet device. * * @param dev * Pointer to Ethernet device structure. * * @return * Pointer to private structure. */ struct priv * mlx5_get_priv(struct rte_eth_dev *dev) { struct mlx5_secondary_data *sd; if (!mlx5_is_secondary()) return dev->data->dev_private; sd = &mlx5_secondary_data[dev->data->port_id]; return sd->data.dev_private; }
/** * DPDK callback for Ethernet device configuration. * * @param dev * Pointer to Ethernet device structure. * * @return * 0 on success, negative errno value on failure. */ int mlx5_dev_configure(struct rte_eth_dev *dev) { struct priv *priv = dev->data->dev_private; int ret; if (mlx5_is_secondary()) return -E_RTE_SECONDARY; priv_lock(priv); ret = dev_configure(dev); assert(ret >= 0); priv_unlock(priv); return -ret; }
/** * DPDK callback to modify flow control parameters. * * @param dev * Pointer to Ethernet device structure. * @param[in] fc_conf * Flow control parameters. * * @return * 0 on success, negative errno value on failure. */ int mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { struct priv *priv = dev->data->dev_private; struct ifreq ifr; struct ethtool_pauseparam ethpause = { .cmd = ETHTOOL_SPAUSEPARAM }; int ret; if (mlx5_is_secondary()) return -E_RTE_SECONDARY; ifr.ifr_data = ðpause; ethpause.autoneg = fc_conf->autoneg; if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) || (fc_conf->mode & RTE_FC_RX_PAUSE)) ethpause.rx_pause = 1; else ethpause.rx_pause = 0; if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) || (fc_conf->mode & RTE_FC_TX_PAUSE)) ethpause.tx_pause = 1; else ethpause.tx_pause = 0; priv_lock(priv); if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) { ret = errno; WARN("ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)" " failed: %s", strerror(ret)); goto out; } ret = 0; out: priv_unlock(priv); assert(ret >= 0); return -ret; }
/** * DPDK callback to stop the device. * * Simulate device stop by detaching all configured flows. * * @param dev * Pointer to Ethernet device structure. */ void mlx5_dev_stop(struct rte_eth_dev *dev) { struct priv *priv = dev->data->dev_private; if (mlx5_is_secondary()) return; priv_lock(priv); if (!priv->started) { priv_unlock(priv); return; } DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev); priv_special_flow_disable_all(priv); priv_mac_addrs_disable(priv); priv_destroy_hash_rxqs(priv); priv_fdir_disable(priv); priv_dev_interrupt_handler_uninstall(priv, dev); priv->started = 0; priv_unlock(priv); }
/** * DPDK callback to change the MTU. * * Setting the MTU affects hardware MRU (packets larger than the MTU cannot be * received). Use this as a hint to enable/disable scattered packets support * and improve performance when not needed. * Since failure is not an option, reconfiguring queues on the fly is not * recommended. * * @param dev * Pointer to Ethernet device structure. * @param in_mtu * New MTU. * * @return * 0 on success, negative errno value on failure. */ int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) { struct priv *priv = dev->data->dev_private; int ret = 0; unsigned int i; uint16_t (*rx_func)(void *, struct rte_mbuf **, uint16_t) = mlx5_rx_burst; if (mlx5_is_secondary()) return -E_RTE_SECONDARY; priv_lock(priv); /* Set kernel interface MTU first. */ if (priv_set_mtu(priv, mtu)) { ret = errno; WARN("cannot set port %u MTU to %u: %s", priv->port, mtu, strerror(ret)); goto out; } else DEBUG("adapter port %u MTU set to %u", priv->port, mtu); priv->mtu = mtu; /* Temporarily replace RX handler with a fake one, assuming it has not * been copied elsewhere. */ dev->rx_pkt_burst = removed_rx_burst; /* Make sure everyone has left mlx5_rx_burst() and uses * removed_rx_burst() instead. */ rte_wmb(); usleep(1000); /* Reconfigure each RX queue. */ for (i = 0; (i != priv->rxqs_n); ++i) { struct rxq *rxq = (*priv->rxqs)[i]; unsigned int max_frame_len; int sp; if (rxq == NULL) continue; /* Calculate new maximum frame length according to MTU and * toggle scattered support (sp) if necessary. */ max_frame_len = (priv->mtu + ETHER_HDR_LEN + (ETHER_MAX_VLAN_FRAME_LEN - ETHER_MAX_LEN)); sp = (max_frame_len > (rxq->mb_len - RTE_PKTMBUF_HEADROOM)); /* Provide new values to rxq_setup(). */ dev->data->dev_conf.rxmode.jumbo_frame = sp; dev->data->dev_conf.rxmode.max_rx_pkt_len = max_frame_len; ret = rxq_rehash(dev, rxq); if (ret) { /* Force SP RX if that queue requires it and abort. */ if (rxq->sp) rx_func = mlx5_rx_burst_sp; break; } /* Scattered burst function takes priority. */ if (rxq->sp) rx_func = mlx5_rx_burst_sp; } /* Burst functions can now be called again. */ rte_wmb(); dev->rx_pkt_burst = rx_func; out: priv_unlock(priv); assert(ret >= 0); return -ret; }