1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2015 6WIND S.A.
3 * Copyright 2015 Mellanox Technologies, Ltd
11 #include <netinet/in.h>
13 #include <rte_ether.h>
14 #include <rte_ethdev_driver.h>
15 #include <rte_common.h>
17 #include "mlx5_defs.h"
19 #include "mlx5_utils.h"
20 #include "mlx5_rxtx.h"
23 * Remove a MAC address from the internal array.
26 * Pointer to Ethernet device structure.
31 mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
33 MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
34 if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index]))
36 mlx5_os_mac_addr_remove(dev, index);
37 memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
41 * Adds a MAC address to the internal array.
44 * Pointer to Ethernet device structure.
46 * MAC address to register.
51 * 0 on success, a negative errno value otherwise and rte_errno is set.
54 mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
60 MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
61 if (rte_is_zero_ether_addr(mac)) {
65 /* First, make sure this address isn't already configured. */
66 for (i = 0; (i != MLX5_MAX_MAC_ADDRESSES); ++i) {
67 /* Skip this index, it's going to be reconfigured. */
70 if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac)))
72 /* Address already configured elsewhere, return with error. */
73 rte_errno = EADDRINUSE;
76 ret = mlx5_os_mac_addr_add(dev, mac, index);
80 dev->data->mac_addrs[index] = *mac;
85 * DPDK callback to remove a MAC address.
88 * Pointer to Ethernet device structure.
93 mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
97 if (index >= MLX5_MAX_UC_MAC_ADDRESSES)
99 mlx5_internal_mac_addr_remove(dev, index);
100 if (!dev->data->promiscuous) {
101 ret = mlx5_traffic_restart(dev);
103 DRV_LOG(ERR, "port %u cannot restart traffic: %s",
104 dev->data->port_id, strerror(rte_errno));
109 * DPDK callback to add a MAC address.
112 * Pointer to Ethernet device structure.
114 * MAC address to register.
118 * VMDq pool index to associate address with (ignored).
121 * 0 on success, a negative errno value otherwise and rte_errno is set.
124 mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
125 uint32_t index, uint32_t vmdq __rte_unused)
129 if (index >= MLX5_MAX_UC_MAC_ADDRESSES) {
133 ret = mlx5_internal_mac_addr_add(dev, mac, index);
136 if (!dev->data->promiscuous)
137 return mlx5_traffic_restart(dev);
142 * DPDK callback to set primary MAC address.
145 * Pointer to Ethernet device structure.
147 * MAC address to register.
150 * 0 on success, a negative errno value otherwise and rte_errno is set.
153 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
156 struct mlx5_priv *priv = dev->data->dev_private;
159 * Configuring the VF instead of its representor,
160 * need to skip the special case of HPF on Bluefield.
162 if (priv->representor && priv->representor_id >= 0) {
163 DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address",
165 RTE_ETH_FOREACH_DEV_SIBLING(port_id, dev->data->port_id) {
166 priv = rte_eth_devices[port_id].data->dev_private;
167 if (priv->master == 1) {
168 priv = dev->data->dev_private;
169 return mlx5_os_vf_mac_addr_modify
171 mlx5_ifindex(&rte_eth_devices[port_id]),
172 mac_addr, priv->representor_id);
175 rte_errno = -ENOTSUP;
179 DRV_LOG(DEBUG, "port %u setting primary MAC address",
181 return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
185 * DPDK callback to set multicast addresses list.
187 * @see rte_eth_dev_set_mc_addr_list()
190 mlx5_set_mc_addr_list(struct rte_eth_dev *dev,
191 struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr)
196 if (nb_mc_addr >= MLX5_MAX_MC_MAC_ADDRESSES) {
200 for (i = MLX5_MAX_UC_MAC_ADDRESSES; i != MLX5_MAX_MAC_ADDRESSES; ++i)
201 mlx5_internal_mac_addr_remove(dev, i);
202 i = MLX5_MAX_UC_MAC_ADDRESSES;
203 while (nb_mc_addr--) {
204 ret = mlx5_internal_mac_addr_add(dev, mc_addr_set++, i++);
208 if (!dev->data->promiscuous)
209 return mlx5_traffic_restart(dev);