1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
3 */
4 #include <stdio.h>
5
6 #include <rte_errno.h>
7 #include <rte_ether.h>
8 #include <ethdev_driver.h>
9 #include <rte_interrupts.h>
10
11 #include <mlx5_glue.h>
12 #include <mlx5_devx_cmds.h>
13 #include <mlx5_common.h>
14 #include <mlx5_win_ext.h>
15 #include <mlx5_malloc.h>
16 #include <mlx5.h>
17 #include <mlx5_utils.h>
18
19 /**
20 * Get MAC address by querying netdevice.
21 *
22 * @param[in] dev
23 * Pointer to Ethernet device.
24 * @param[out] mac
25 * MAC address output buffer.
26 *
27 * @return
28 * 0 on success, a negative errno value otherwise and rte_errno is set.
29 */
30 int
mlx5_get_mac(struct rte_eth_dev * dev,uint8_t (* mac)[RTE_ETHER_ADDR_LEN])31 mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[RTE_ETHER_ADDR_LEN])
32 {
33 struct mlx5_priv *priv;
34 mlx5_context_st *context_obj;
35
36 if (!dev) {
37 rte_errno = EINVAL;
38 return -rte_errno;
39 }
40 priv = dev->data->dev_private;
41 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
42 memcpy(mac, context_obj->mlx5_dev.eth_mac, RTE_ETHER_ADDR_LEN);
43 return 0;
44 }
45
46 /**
47 * Get interface name from private structure.
48 *
49 *
50 * @param[in] dev
51 * Pointer to Ethernet device.
52 * @param[out] ifname
53 * Interface name output buffer.
54 *
55 * @return
56 * 0 on success, a negative errno value otherwise and rte_errno is set.
57 */
58 int
mlx5_get_ifname(const struct rte_eth_dev * dev,char (* ifname)[MLX5_NAMESIZE])59 mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[MLX5_NAMESIZE])
60 {
61 struct mlx5_priv *priv;
62 mlx5_context_st *context_obj;
63
64 if (!dev) {
65 rte_errno = EINVAL;
66 return -rte_errno;
67 }
68 priv = dev->data->dev_private;
69 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
70 strncpy(*ifname, context_obj->mlx5_dev.name, MLX5_NAMESIZE);
71 return 0;
72 }
73
74 /**
75 * Get device MTU.
76 *
77 * @param dev
78 * Pointer to Ethernet device.
79 * @param[out] mtu
80 * MTU value output buffer.
81 *
82 * @return
83 * 0 on success, a negative errno value otherwise and rte_errno is set.
84 */
85 int
mlx5_get_mtu(struct rte_eth_dev * dev,uint16_t * mtu)86 mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu)
87 {
88 int err;
89 uint32_t curr_mtu;
90 struct mlx5_priv *priv;
91 mlx5_context_st *context_obj;
92
93 if (!dev) {
94 rte_errno = EINVAL;
95 return -rte_errno;
96 }
97 priv = dev->data->dev_private;
98 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
99
100 err = mlx5_glue->devx_get_mtu(context_obj, &curr_mtu);
101 if (err != 0) {
102 DRV_LOG(WARNING, "Could not get the MTU!");
103 return err;
104 }
105 *mtu = (uint16_t)curr_mtu;
106
107 return 0;
108 }
109
110 /**
111 * Set device MTU.
112 *
113 * @param dev
114 * Pointer to Ethernet device.
115 * @param mtu
116 * MTU value to set.
117 *
118 * @return
119 * 0 on success, a negative errno value otherwise and rte_errno is set.
120 */
121 int
mlx5_set_mtu(struct rte_eth_dev * dev,uint16_t mtu)122 mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
123 {
124 int err;
125 struct mlx5_priv *priv;
126 mlx5_context_st *context_obj;
127
128 if (!dev) {
129 rte_errno = EINVAL;
130 return -rte_errno;
131 }
132 priv = dev->data->dev_private;
133 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
134
135 err = mlx5_glue->devx_set_mtu(context_obj, mtu);
136 if (err != 0) {
137 DRV_LOG(WARNING, "Could not set the MTU!");
138 return err;
139 }
140 return 0;
141 }
142
143 /**
144 * DPDK callback to get flow control status.
145 *
146 * @param dev
147 * Pointer to Ethernet device structure.
148 * @param[out] fc_conf
149 * Flow control output buffer.
150 *
151 * @return
152 * 0 on success, a negative errno value otherwise and rte_errno is set.
153 */
154 int
mlx5_dev_get_flow_ctrl(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)155 mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
156 {
157 RTE_SET_USED(dev);
158 RTE_SET_USED(fc_conf);
159 return -ENOTSUP;
160 }
161
162 /**
163 * DPDK callback to modify flow control parameters.
164 *
165 * @param dev
166 * Pointer to Ethernet device structure.
167 * @param[in] fc_conf
168 * Flow control parameters.
169 *
170 * @return
171 * 0 on success, a negative errno value otherwise and rte_errno is set.
172 */
173 int
mlx5_dev_set_flow_ctrl(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)174 mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
175 {
176 RTE_SET_USED(dev);
177 RTE_SET_USED(fc_conf);
178 return -ENOTSUP;
179 }
180
181 /*
182 * Query the number of statistics provided by ETHTOOL.
183 *
184 * @param dev
185 * Pointer to Ethernet device.
186 * @param bond_master
187 * Indicate if the device is a bond master.
188 * @param n_stats
189 * Pointer to number of stats to store.
190 * @param n_stats_sec
191 * Pointer to number of stats to store for the 2nd port of the bond.
192 *
193 * @return
194 * 0 on success, negative errno value otherwise and rte_errno is set.
195 */
196 int
mlx5_os_get_stats_n(struct rte_eth_dev * dev,bool bond_master,uint16_t * n_stats,uint16_t * n_stats_sec)197 mlx5_os_get_stats_n(struct rte_eth_dev *dev, bool bond_master,
198 uint16_t *n_stats, uint16_t *n_stats_sec)
199 {
200 RTE_SET_USED(dev);
201 RTE_SET_USED(bond_master);
202 RTE_SET_USED(n_stats);
203 RTE_SET_USED(n_stats_sec);
204 return -ENOTSUP;
205 }
206
207 /**
208 * Init the structures to read device counters.
209 *
210 * @param dev
211 * Pointer to Ethernet device.
212 */
213 void
mlx5_os_stats_init(struct rte_eth_dev * dev)214 mlx5_os_stats_init(struct rte_eth_dev *dev)
215 {
216 struct mlx5_priv *priv = dev->data->dev_private;
217 struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
218 int ret;
219
220 /* Copy to base at first time. */
221 ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
222 if (ret)
223 DRV_LOG(ERR, "port %u cannot read device counters: %s",
224 dev->data->port_id, strerror(rte_errno));
225 stats_ctrl->imissed = 0;
226 }
227
228 /**
229 * Read device counters table.
230 *
231 * @param dev
232 * Pointer to Ethernet device.
233 * @param bond_master
234 * Indicate if the device is a bond master.
235 * @param[out] stats
236 * Counters table output buffer.
237 *
238 * @return
239 * 0 on success and stats is filled, negative errno value otherwise and
240 * rte_errno is set.
241 */
242 int
mlx5_os_read_dev_counters(struct rte_eth_dev * dev,bool bond_master,uint64_t * stats)243 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, bool bond_master, uint64_t *stats)
244 {
245 RTE_SET_USED(dev);
246 RTE_SET_USED(bond_master);
247 RTE_SET_USED(stats);
248 return -ENOTSUP;
249 }
250
251 /**
252 * DPDK callback to retrieve physical link information.
253 *
254 * @param dev
255 * Pointer to Ethernet device structure.
256 * @param wait_to_complete
257 * Wait for request completion.
258 *
259 * @return
260 * 0 if link status was not updated, positive if it was, a negative errno
261 * value otherwise and rte_errno is set.
262 */
263 int
mlx5_link_update(struct rte_eth_dev * dev,int wait_to_complete)264 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
265 {
266 RTE_SET_USED(wait_to_complete);
267 struct mlx5_priv *priv;
268 mlx5_context_st *context_obj;
269 struct rte_eth_link dev_link;
270 int ret;
271
272 ret = 0;
273 if (!dev) {
274 rte_errno = EINVAL;
275 return -rte_errno;
276 }
277 priv = dev->data->dev_private;
278 context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
279 dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1000 * 1000);
280 dev_link.link_status =
281 (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev))
282 ? 1 : 0;
283 dev_link.link_duplex = 1;
284 if (dev->data->dev_link.link_speed != dev_link.link_speed ||
285 dev->data->dev_link.link_duplex != dev_link.link_duplex ||
286 dev->data->dev_link.link_autoneg != dev_link.link_autoneg ||
287 dev->data->dev_link.link_status != dev_link.link_status)
288 ret = 1;
289 else
290 ret = 0;
291 dev->data->dev_link = dev_link;
292 return ret;
293 }
294
295 /**
296 * DPDK callback to bring the link DOWN.
297 *
298 * @param dev
299 * Pointer to Ethernet device structure.
300 *
301 * @return
302 * 0 on success, a negative errno value otherwise
303 */
304 int
mlx5_set_link_down(struct rte_eth_dev * dev)305 mlx5_set_link_down(struct rte_eth_dev *dev)
306 {
307 RTE_SET_USED(dev);
308 return -ENOTSUP;
309 }
310
311 /**
312 * DPDK callback to bring the link UP.
313 *
314 * @param dev
315 * Pointer to Ethernet device structure.
316 *
317 * @return
318 * 0 on success, a negative errno value otherwise
319 */
320 int
mlx5_set_link_up(struct rte_eth_dev * dev)321 mlx5_set_link_up(struct rte_eth_dev *dev)
322 {
323 RTE_SET_USED(dev);
324 return -ENOTSUP;
325 }
326
327 /**
328 * DPDK callback to retrieve plug-in module EEPROM information (type and size).
329 *
330 * @param dev
331 * Pointer to Ethernet device structure.
332 * @param[out] modinfo
333 * Storage for plug-in module EEPROM information.
334 *
335 * @return
336 * 0 on success, a negative errno value otherwise and rte_errno is set.
337 */
338 int
mlx5_get_module_info(struct rte_eth_dev * dev,struct rte_eth_dev_module_info * modinfo)339 mlx5_get_module_info(struct rte_eth_dev *dev,
340 struct rte_eth_dev_module_info *modinfo)
341 {
342 RTE_SET_USED(dev);
343 RTE_SET_USED(modinfo);
344 return -ENOTSUP;
345 }
346
347 /**
348 * DPDK callback to retrieve plug-in module EEPROM data.
349 *
350 * @param dev
351 * Pointer to Ethernet device structure.
352 * @param[out] info
353 * Storage for plug-in module EEPROM data.
354 *
355 * @return
356 * 0 on success, a negative errno value otherwise and rte_errno is set.
357 */
mlx5_get_module_eeprom(struct rte_eth_dev * dev,struct rte_dev_eeprom_info * info)358 int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
359 struct rte_dev_eeprom_info *info)
360 {
361 RTE_SET_USED(dev);
362 RTE_SET_USED(info);
363 return -ENOTSUP;
364 }
365
366 /**
367 * Get device current raw clock counter
368 *
369 * @param dev
370 * Pointer to Ethernet device structure.
371 * @param[out] time
372 * Current raw clock counter of the device.
373 *
374 * @return
375 * 0 if the clock has correctly been read
376 * The value of errno in case of error
377 */
378 int
mlx5_read_clock(struct rte_eth_dev * dev,uint64_t * clock)379 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock)
380 {
381 int err;
382 struct mlx5_devx_clock mlx5_clock;
383 struct mlx5_priv *priv = dev->data->dev_private;
384 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
385
386 err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock);
387 if (err != 0) {
388 DRV_LOG(WARNING, "Could not query the clock");
389 return err;
390 }
391 *clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer;
392 return 0;
393 }
394
395 /**
396 * Check if mlx5 device was removed.
397 *
398 * @param dev
399 * Pointer to Ethernet device structure.
400 *
401 * @return
402 * 1 when device is removed, otherwise 0.
403 */
404 int
mlx5_is_removed(struct rte_eth_dev * dev)405 mlx5_is_removed(struct rte_eth_dev *dev)
406 {
407 struct mlx5_priv *priv = dev->data->dev_private;
408 mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
409
410 if (*context_obj->shutdown_event_obj.p_flag)
411 return 1;
412 return 0;
413 }
414
415 /*
416 * Query dropless_rq private flag value provided by ETHTOOL.
417 *
418 * @param dev
419 * Pointer to Ethernet device.
420 *
421 * @return
422 * - 0 on success, flag is not set.
423 * - 1 on success, flag is set.
424 * - negative errno value otherwise and rte_errno is set.
425 */
mlx5_get_flag_dropless_rq(struct rte_eth_dev * dev)426 int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev)
427 {
428 RTE_SET_USED(dev);
429 return -ENOTSUP;
430 }
431
432 /**
433 * Unmaps HCA PCI BAR from the current process address space.
434 *
435 * @param dev
436 * Pointer to Ethernet device structure.
437 */
mlx5_txpp_unmap_hca_bar(struct rte_eth_dev * dev)438 void mlx5_txpp_unmap_hca_bar(struct rte_eth_dev *dev)
439 {
440 RTE_SET_USED(dev);
441 }
442
443 /**
444 * Maps HCA PCI BAR to the current process address space.
445 * Stores pointer in the process private structure allowing
446 * to read internal and real time counter directly from the HW.
447 *
448 * @param dev
449 * Pointer to Ethernet device structure.
450 *
451 * @return
452 * 0 on success and not NULL pointer to mapped area in process structure.
453 * negative otherwise and NULL pointer
454 */
mlx5_txpp_map_hca_bar(struct rte_eth_dev * dev)455 int mlx5_txpp_map_hca_bar(struct rte_eth_dev *dev)
456 {
457 RTE_SET_USED(dev);
458 rte_errno = ENOTSUP;
459 return -ENOTSUP;
460 }
461