X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_mac.c;h=19981d26d846db52961f1259c401ca206efd5ffd;hb=f70dcb2bab09f21f8f73a192eb7ba6fc0255b48b;hp=f7e1cf6888a494ce4470ae0959cd92d2c47cf2b8;hpb=771fa900b73aae1ac8ec0ae6ac086e9e164da7b2;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c index f7e1cf6888..19981d26d8 100644 --- a/drivers/net/mlx5/mlx5_mac.c +++ b/drivers/net/mlx5/mlx5_mac.c @@ -1,150 +1,217 @@ -/*- - * BSD LICENSE - * - * Copyright 2015 6WIND S.A. - * Copyright 2015 Mellanox. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of 6WIND S.A. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2015 6WIND S.A. + * Copyright 2015 Mellanox Technologies, Ltd */ #include -#include #include #include #include #include -#include -#include -#include -#include - -/* Verbs header. */ -/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-pedantic" -#endif -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-pedantic" -#endif - -/* DPDK headers don't like -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-pedantic" -#endif + #include -#include +#include #include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-pedantic" -#endif +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" +#include "mlx5_rxtx.h" + +/** + * Remove a MAC address from the internal array. + * + * @param dev + * Pointer to Ethernet device structure. + * @param index + * MAC address index. + */ +static void +mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) +{ + MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); + if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index])) + return; + mlx5_os_mac_addr_remove(dev, index); + memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr)); +} /** - * Get MAC address by querying netdevice. + * Adds a MAC address to the internal array. * - * @param[in] priv - * struct priv for the requested device. - * @param[out] mac - * MAC address output buffer. + * @param dev + * Pointer to Ethernet device structure. + * @param mac_addr + * MAC address to register. + * @param index + * MAC address index. * * @return - * 0 on success, -1 on failure and errno is set. + * 0 on success, a negative errno value otherwise and rte_errno is set. */ -int -priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN]) +static int +mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, + uint32_t index) { - struct ifreq request; + unsigned int i; + int ret; - if (priv_ifreq(priv, SIOCGIFHWADDR, &request)) - return -1; - memcpy(mac, request.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); + MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES); + if (rte_is_zero_ether_addr(mac)) { + rte_errno = EINVAL; + return -rte_errno; + } + /* First, make sure this address isn't already configured. */ + for (i = 0; (i != MLX5_MAX_MAC_ADDRESSES); ++i) { + /* Skip this index, it's going to be reconfigured. */ + if (i == index) + continue; + if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac))) + continue; + /* Address already configured elsewhere, return with error. */ + rte_errno = EADDRINUSE; + return -rte_errno; + } + ret = mlx5_os_mac_addr_add(dev, mac, index); + if (ret) + return ret; + + dev->data->mac_addrs[index] = *mac; return 0; } /** - * Unregister a MAC address. + * DPDK callback to remove a MAC address. * - * @param priv - * Pointer to private structure. - * @param mac_index + * @param dev + * Pointer to Ethernet device structure. + * @param index * MAC address index. */ -static void -priv_mac_addr_del(struct priv *priv, unsigned int mac_index) +void +mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) { - assert(mac_index < RTE_DIM(priv->mac)); - if (!BITFIELD_ISSET(priv->mac_configured, mac_index)) + int ret; + + if (index >= MLX5_MAX_UC_MAC_ADDRESSES) return; - BITFIELD_RESET(priv->mac_configured, mac_index); + mlx5_internal_mac_addr_remove(dev, index); + if (!dev->data->promiscuous) { + ret = mlx5_traffic_restart(dev); + if (ret) + DRV_LOG(ERR, "port %u cannot restart traffic: %s", + dev->data->port_id, strerror(rte_errno)); + } } /** - * Register a MAC address. + * DPDK callback to add a MAC address. * - * @param priv - * Pointer to private structure. - * @param mac_index - * MAC address index to use. - * @param mac + * @param dev + * Pointer to Ethernet device structure. + * @param mac_addr * MAC address to register. + * @param index + * MAC address index. + * @param vmdq + * VMDq pool index to associate address with (ignored). * * @return - * 0 on success, errno value on failure. + * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -priv_mac_addr_add(struct priv *priv, unsigned int mac_index, - const uint8_t (*mac)[ETHER_ADDR_LEN]) +mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, + uint32_t index, uint32_t vmdq __rte_unused) { - unsigned int i; + int ret; - assert(mac_index < RTE_DIM(priv->mac)); - /* First, make sure this address isn't already configured. */ - for (i = 0; (i != RTE_DIM(priv->mac)); ++i) { - /* Skip this index, it's going to be reconfigured. */ - if (i == mac_index) - continue; - if (!BITFIELD_ISSET(priv->mac_configured, i)) - continue; - if (memcmp(priv->mac[i].addr_bytes, *mac, sizeof(*mac))) - continue; - /* Address already configured elsewhere, return with error. */ - return EADDRINUSE; + if (index >= MLX5_MAX_UC_MAC_ADDRESSES) { + rte_errno = EINVAL; + return -rte_errno; } - if (BITFIELD_ISSET(priv->mac_configured, mac_index)) - priv_mac_addr_del(priv, mac_index); - priv->mac[mac_index] = (struct ether_addr){ - { - (*mac)[0], (*mac)[1], (*mac)[2], - (*mac)[3], (*mac)[4], (*mac)[5] + ret = mlx5_internal_mac_addr_add(dev, mac, index); + if (ret < 0) + return ret; + if (!dev->data->promiscuous) + return mlx5_traffic_restart(dev); + return 0; +} + +/** + * DPDK callback to set primary MAC address. + * + * @param dev + * Pointer to Ethernet device structure. + * @param mac_addr + * MAC address to register. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) +{ + uint16_t port_id; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_priv *pf_priv; + + /* + * Configuring the VF instead of its representor, + * need to skip the special case of HPF on Bluefield. + */ + if (priv->representor && !mlx5_is_hpf(dev)) { + DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address", + dev->data->port_id); + if (priv->pf_bond >= 0) { + /* Bonding, get owner PF ifindex from shared data. */ + return mlx5_os_vf_mac_addr_modify + (priv, + priv->sh->bond.ports[priv->pf_bond].ifindex, + mac_addr, + MLX5_REPRESENTOR_REPR(priv->representor_id)); } - }; - BITFIELD_SET(priv->mac_configured, mac_index); + RTE_ETH_FOREACH_DEV_SIBLING(port_id, dev->data->port_id) { + pf_priv = rte_eth_devices[port_id].data->dev_private; + if (pf_priv->master == 1) + return mlx5_os_vf_mac_addr_modify + (priv, pf_priv->if_index, mac_addr, + MLX5_REPRESENTOR_REPR + (priv->representor_id)); + } + rte_errno = -ENOTSUP; + return rte_errno; + } + + DRV_LOG(DEBUG, "port %u setting primary MAC address", + dev->data->port_id); + return mlx5_mac_addr_add(dev, mac_addr, 0, 0); +} + +/** + * DPDK callback to set multicast addresses list. + * + * @see rte_eth_dev_set_mc_addr_list() + */ +int +mlx5_set_mc_addr_list(struct rte_eth_dev *dev, + struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr) +{ + uint32_t i; + int ret; + + if (nb_mc_addr >= MLX5_MAX_MC_MAC_ADDRESSES) { + rte_errno = ENOSPC; + return -rte_errno; + } + for (i = MLX5_MAX_UC_MAC_ADDRESSES; i != MLX5_MAX_MAC_ADDRESSES; ++i) + mlx5_internal_mac_addr_remove(dev, i); + i = MLX5_MAX_UC_MAC_ADDRESSES; + while (nb_mc_addr--) { + ret = mlx5_internal_mac_addr_add(dev, mc_addr_set++, i++); + if (ret) + return ret; + } + if (!dev->data->promiscuous) + return mlx5_traffic_restart(dev); return 0; }