xref: /dpdk/drivers/net/mlx5/windows/mlx5_ethdev_os.c (revision 0dff3f26d6faad4e51f75e5245f0387ee9bb0c6d)
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
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
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
86 mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu)
87 {
88 	struct mlx5_priv *priv;
89 	mlx5_context_st *context_obj;
90 
91 	if (!dev) {
92 		rte_errno = EINVAL;
93 		return -rte_errno;
94 	}
95 	priv = dev->data->dev_private;
96 	context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
97 	*mtu = context_obj->mlx5_dev.mtu_bytes;
98 	return 0;
99 }
100 
101 /**
102  * Set device MTU.
103  *
104  * @param dev
105  *   Pointer to Ethernet device.
106  * @param mtu
107  *   MTU value to set.
108  *
109  * @return
110  *   0 on success, a negative errno value otherwise and rte_errno is set.
111  */
112 int
113 mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
114 {
115 	RTE_SET_USED(dev);
116 	RTE_SET_USED(mtu);
117 	return -ENOTSUP;
118 }
119 
120 /*
121  * Unregister callback handler safely. The handler may be active
122  * while we are trying to unregister it, in this case code -EAGAIN
123  * is returned by rte_intr_callback_unregister(). This routine checks
124  * the return code and tries to unregister handler again.
125  *
126  * @param handle
127  *   interrupt handle
128  * @param cb_fn
129  *   pointer to callback routine
130  * @cb_arg
131  *   opaque callback parameter
132  */
133 void
134 mlx5_intr_callback_unregister(const struct rte_intr_handle *handle,
135 			      rte_intr_callback_fn cb_fn, void *cb_arg)
136 {
137 	RTE_SET_USED(handle);
138 	RTE_SET_USED(cb_fn);
139 	RTE_SET_USED(cb_arg);
140 }
141 
142 /**
143  * DPDK callback to get flow control status.
144  *
145  * @param dev
146  *   Pointer to Ethernet device structure.
147  * @param[out] fc_conf
148  *   Flow control output buffer.
149  *
150  * @return
151  *   0 on success, a negative errno value otherwise and rte_errno is set.
152  */
153 int
154 mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
155 {
156 	RTE_SET_USED(dev);
157 	RTE_SET_USED(fc_conf);
158 	return -ENOTSUP;
159 }
160 
161 /**
162  * DPDK callback to modify flow control parameters.
163  *
164  * @param dev
165  *   Pointer to Ethernet device structure.
166  * @param[in] fc_conf
167  *   Flow control parameters.
168  *
169  * @return
170  *   0 on success, a negative errno value otherwise and rte_errno is set.
171  */
172 int
173 mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
174 {
175 	RTE_SET_USED(dev);
176 	RTE_SET_USED(fc_conf);
177 	return -ENOTSUP;
178 }
179 
180 /**
181  * Query the number of statistics provided by ETHTOOL.
182  *
183  * @param dev
184  *   Pointer to Ethernet device.
185  *
186  * @return
187  *   Number of statistics on success, negative errno value otherwise and
188  *   rte_errno is set.
189  */
190 int
191 mlx5_os_get_stats_n(struct rte_eth_dev *dev)
192 {
193 	RTE_SET_USED(dev);
194 	return -ENOTSUP;
195 }
196 
197 /**
198  * Init the structures to read device counters.
199  *
200  * @param dev
201  *   Pointer to Ethernet device.
202  */
203 void
204 mlx5_os_stats_init(struct rte_eth_dev *dev)
205 {
206 	struct mlx5_priv *priv = dev->data->dev_private;
207 	struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
208 	int ret;
209 
210 	/* Copy to base at first time. */
211 	ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
212 	if (ret)
213 		DRV_LOG(ERR, "port %u cannot read device counters: %s",
214 			dev->data->port_id, strerror(rte_errno));
215 	stats_ctrl->imissed = 0;
216 }
217 
218 /**
219  * Read device counters table.
220  *
221  * @param dev
222  *   Pointer to Ethernet device.
223  * @param[out] stats
224  *   Counters table output buffer.
225  *
226  * @return
227  *   0 on success and stats is filled, negative errno value otherwise and
228  *   rte_errno is set.
229  */
230 int
231 mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats)
232 {
233 	RTE_SET_USED(dev);
234 	RTE_SET_USED(stats);
235 	return -ENOTSUP;
236 }
237 
238 /**
239  * DPDK callback to retrieve physical link information.
240  *
241  * @param dev
242  *   Pointer to Ethernet device structure.
243  * @param wait_to_complete
244  *   Wait for request completion.
245  *
246  * @return
247  *   0 if link status was not updated, positive if it was, a negative errno
248  *   value otherwise and rte_errno is set.
249  */
250 int
251 mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
252 {
253 	RTE_SET_USED(wait_to_complete);
254 	struct mlx5_priv *priv;
255 	mlx5_context_st *context_obj;
256 	struct rte_eth_link dev_link;
257 	int ret;
258 
259 	ret = 0;
260 	if (!dev) {
261 		rte_errno = EINVAL;
262 		return -rte_errno;
263 	}
264 	priv = dev->data->dev_private;
265 	context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
266 	dev_link.link_speed = context_obj->mlx5_dev.link_speed / (1000 * 1000);
267 	dev_link.link_status =
268 	      (context_obj->mlx5_dev.link_state == 1 && !mlx5_is_removed(dev))
269 	      ? 1 : 0;
270 	dev_link.link_duplex = 1;
271 	if (dev->data->dev_link.link_speed != dev_link.link_speed ||
272 	    dev->data->dev_link.link_duplex != dev_link.link_duplex ||
273 	    dev->data->dev_link.link_autoneg != dev_link.link_autoneg ||
274 	    dev->data->dev_link.link_status != dev_link.link_status)
275 		ret = 1;
276 	else
277 		ret = 0;
278 	dev->data->dev_link = dev_link;
279 	return ret;
280 }
281 
282 /**
283  * DPDK callback to bring the link DOWN.
284  *
285  * @param dev
286  *   Pointer to Ethernet device structure.
287  *
288  * @return
289  *   0 on success, a negative errno value otherwise
290  */
291 int
292 mlx5_set_link_down(struct rte_eth_dev *dev)
293 {
294 	RTE_SET_USED(dev);
295 	return -ENOTSUP;
296 }
297 
298 /**
299  * DPDK callback to bring the link UP.
300  *
301  * @param dev
302  *   Pointer to Ethernet device structure.
303  *
304  * @return
305  *   0 on success, a negative errno value otherwise
306  */
307 int
308 mlx5_set_link_up(struct rte_eth_dev *dev)
309 {
310 	RTE_SET_USED(dev);
311 	return -ENOTSUP;
312 }
313 
314 /**
315  * DPDK callback to retrieve plug-in module EEPROM information (type and size).
316  *
317  * @param dev
318  *   Pointer to Ethernet device structure.
319  * @param[out] modinfo
320  *   Storage for plug-in module EEPROM information.
321  *
322  * @return
323  *   0 on success, a negative errno value otherwise and rte_errno is set.
324  */
325 int
326 mlx5_get_module_info(struct rte_eth_dev *dev,
327 		     struct rte_eth_dev_module_info *modinfo)
328 {
329 	RTE_SET_USED(dev);
330 	RTE_SET_USED(modinfo);
331 	return -ENOTSUP;
332 }
333 
334 /**
335  * DPDK callback to retrieve plug-in module EEPROM data.
336  *
337  * @param dev
338  *   Pointer to Ethernet device structure.
339  * @param[out] info
340  *   Storage for plug-in module EEPROM data.
341  *
342  * @return
343  *   0 on success, a negative errno value otherwise and rte_errno is set.
344  */
345 int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
346 			   struct rte_dev_eeprom_info *info)
347 {
348 	RTE_SET_USED(dev);
349 	RTE_SET_USED(info);
350 	return -ENOTSUP;
351 }
352 
353 /**
354  * Get device current raw clock counter
355  *
356  * @param dev
357  *   Pointer to Ethernet device structure.
358  * @param[out] time
359  *   Current raw clock counter of the device.
360  *
361  * @return
362  *   0 if the clock has correctly been read
363  *   The value of errno in case of error
364  */
365 int
366 mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock)
367 {
368 	int err;
369 	struct mlx5_devx_clock mlx5_clock;
370 	struct mlx5_priv *priv = dev->data->dev_private;
371 	mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
372 
373 	err = mlx5_glue->query_rt_values(context_obj, &mlx5_clock);
374 	if (err != 0) {
375 		DRV_LOG(WARNING, "Could not query the clock");
376 		return err;
377 	}
378 	*clock = *(uint64_t volatile *)mlx5_clock.p_iseg_internal_timer;
379 	return 0;
380 }
381 
382 /**
383  * Check if mlx5 device was removed.
384  *
385  * @param dev
386  *   Pointer to Ethernet device structure.
387  *
388  * @return
389  *   1 when device is removed, otherwise 0.
390  */
391 int
392 mlx5_is_removed(struct rte_eth_dev *dev)
393 {
394 	struct mlx5_priv *priv = dev->data->dev_private;
395 	mlx5_context_st *context_obj = (mlx5_context_st *)priv->sh->cdev->ctx;
396 
397 	if (*context_obj->shutdown_event_obj.p_flag)
398 		return 1;
399 	return 0;
400 }
401 
402 /*
403  * Query dropless_rq private flag value provided by ETHTOOL.
404  *
405  * @param dev
406  *   Pointer to Ethernet device.
407  *
408  * @return
409  *   - 0 on success, flag is not set.
410  *   - 1 on success, flag is set.
411  *   - negative errno value otherwise and rte_errno is set.
412  */
413 int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev)
414 {
415 	RTE_SET_USED(dev);
416 	return -ENOTSUP;
417 }
418