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