xref: /dpdk/drivers/net/mlx5/mlx5_mac.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2015 6WIND S.A.
3  * Copyright 2015 Mellanox Technologies, Ltd
4  */
5 
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include <inttypes.h>
10 #include <errno.h>
11 #include <netinet/in.h>
12 
13 #include <rte_ether.h>
14 #include <ethdev_driver.h>
15 #include <rte_common.h>
16 
17 #include "mlx5_defs.h"
18 #include "mlx5.h"
19 #include "mlx5_utils.h"
20 #include "mlx5_rxtx.h"
21 
22 /**
23  * Remove a MAC address from the internal array.
24  *
25  * @param dev
26  *   Pointer to Ethernet device structure.
27  * @param index
28  *   MAC address index.
29  */
30 static void
31 mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
32 {
33 	MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
34 	if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index]))
35 		return;
36 	mlx5_os_mac_addr_remove(dev, index);
37 	memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
38 }
39 
40 /**
41  * Adds a MAC address to the internal array.
42  *
43  * @param dev
44  *   Pointer to Ethernet device structure.
45  * @param mac_addr
46  *   MAC address to register.
47  * @param index
48  *   MAC address index.
49  *
50  * @return
51  *   0 on success, a negative errno value otherwise and rte_errno is set.
52  */
53 static int
54 mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
55 			   uint32_t index)
56 {
57 	unsigned int i;
58 	int ret;
59 
60 	MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
61 	if (rte_is_zero_ether_addr(mac)) {
62 		rte_errno = EINVAL;
63 		return -rte_errno;
64 	}
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. */
68 		if (i == index)
69 			continue;
70 		if (memcmp(&dev->data->mac_addrs[i], mac, sizeof(*mac)))
71 			continue;
72 		/* Address already configured elsewhere, return with error. */
73 		rte_errno = EADDRINUSE;
74 		return -rte_errno;
75 	}
76 	ret = mlx5_os_mac_addr_add(dev, mac, index);
77 	if (ret)
78 		return ret;
79 
80 	dev->data->mac_addrs[index] = *mac;
81 	return 0;
82 }
83 
84 /**
85  * DPDK callback to remove a MAC address.
86  *
87  * @param dev
88  *   Pointer to Ethernet device structure.
89  * @param index
90  *   MAC address index.
91  */
92 void
93 mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
94 {
95 	int ret;
96 
97 	if (index >= MLX5_MAX_UC_MAC_ADDRESSES)
98 		return;
99 	mlx5_internal_mac_addr_remove(dev, index);
100 	if (!dev->data->promiscuous) {
101 		ret = mlx5_traffic_restart(dev);
102 		if (ret)
103 			DRV_LOG(ERR, "port %u cannot restart traffic: %s",
104 				dev->data->port_id, strerror(rte_errno));
105 	}
106 }
107 
108 /**
109  * DPDK callback to add a MAC address.
110  *
111  * @param dev
112  *   Pointer to Ethernet device structure.
113  * @param mac_addr
114  *   MAC address to register.
115  * @param index
116  *   MAC address index.
117  * @param vmdq
118  *   VMDq pool index to associate address with (ignored).
119  *
120  * @return
121  *   0 on success, a negative errno value otherwise and rte_errno is set.
122  */
123 int
124 mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
125 		  uint32_t index, uint32_t vmdq __rte_unused)
126 {
127 	int ret;
128 
129 	if (index >= MLX5_MAX_UC_MAC_ADDRESSES) {
130 		rte_errno = EINVAL;
131 		return -rte_errno;
132 	}
133 	ret = mlx5_internal_mac_addr_add(dev, mac, index);
134 	if (ret < 0)
135 		return ret;
136 	if (!dev->data->promiscuous)
137 		return mlx5_traffic_restart(dev);
138 	return 0;
139 }
140 
141 /**
142  * DPDK callback to set primary MAC address.
143  *
144  * @param dev
145  *   Pointer to Ethernet device structure.
146  * @param mac_addr
147  *   MAC address to register.
148  *
149  * @return
150  *   0 on success, a negative errno value otherwise and rte_errno is set.
151  */
152 int
153 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
154 {
155 	uint16_t port_id;
156 	struct mlx5_priv *priv = dev->data->dev_private;
157 	struct mlx5_priv *pf_priv;
158 
159 	/*
160 	 * Configuring the VF instead of its representor,
161 	 * need to skip the special case of HPF on Bluefield.
162 	 */
163 	if (priv->representor && !mlx5_is_hpf(dev)) {
164 		DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address",
165 			dev->data->port_id);
166 		if (priv->pf_bond >= 0) {
167 			/* Bonding, get owner PF ifindex from shared data. */
168 			return mlx5_os_vf_mac_addr_modify
169 			       (priv,
170 				priv->sh->bond.ports[priv->pf_bond].ifindex,
171 				mac_addr,
172 				MLX5_REPRESENTOR_REPR(priv->representor_id));
173 		}
174 		RTE_ETH_FOREACH_DEV_SIBLING(port_id, dev->data->port_id) {
175 			pf_priv = rte_eth_devices[port_id].data->dev_private;
176 			if (pf_priv->master == 1)
177 				return mlx5_os_vf_mac_addr_modify
178 				       (priv, pf_priv->if_index, mac_addr,
179 					MLX5_REPRESENTOR_REPR
180 						(priv->representor_id));
181 		}
182 		rte_errno = -ENOTSUP;
183 		return rte_errno;
184 	}
185 
186 	DRV_LOG(DEBUG, "port %u setting primary MAC address",
187 		dev->data->port_id);
188 	return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
189 }
190 
191 /**
192  * DPDK callback to set multicast addresses list.
193  *
194  * @see rte_eth_dev_set_mc_addr_list()
195  */
196 int
197 mlx5_set_mc_addr_list(struct rte_eth_dev *dev,
198 		      struct rte_ether_addr *mc_addr_set, uint32_t nb_mc_addr)
199 {
200 	uint32_t i;
201 	int ret;
202 
203 	if (nb_mc_addr >= MLX5_MAX_MC_MAC_ADDRESSES) {
204 		rte_errno = ENOSPC;
205 		return -rte_errno;
206 	}
207 	for (i = MLX5_MAX_UC_MAC_ADDRESSES; i != MLX5_MAX_MAC_ADDRESSES; ++i)
208 		mlx5_internal_mac_addr_remove(dev, i);
209 	i = MLX5_MAX_UC_MAC_ADDRESSES;
210 	while (nb_mc_addr--) {
211 		ret = mlx5_internal_mac_addr_add(dev, mc_addr_set++, i++);
212 		if (ret)
213 			return ret;
214 	}
215 	if (!dev->data->promiscuous)
216 		return mlx5_traffic_restart(dev);
217 	return 0;
218 }
219