net/mlx5: add external Rx queue mapping API
[dpdk.git] / drivers / net / mlx5 / windows / mlx5_ethdev_os.c
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 }