xref: /dpdk/drivers/net/mlx5/windows/mlx5_ethdev_os.c (revision a687c3e658c2d889052089af8340bc0b9299c856)
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