f5a16d118b79621d737eda6cf28ffa75bda6f39f
[dpdk.git] / drivers / net / mlx5 / windows / mlx5_os.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4
5 #include <errno.h>
6 #include <stdalign.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10
11 #include <rte_windows.h>
12
13 #include <mlx5_glue.h>
14 #include <mlx5_devx_cmds.h>
15 #include <mlx5_common.h>
16 #include <mlx5_common_mp.h>
17 #include <mlx5_common_mr.h>
18 #include <mlx5_malloc.h>
19
20 #include "mlx5_defs.h"
21 #include "mlx5.h"
22 #include "mlx5_common_os.h"
23 #include "mlx5_utils.h"
24 #include "mlx5_rxtx.h"
25 #include "mlx5_autoconf.h"
26 #include "mlx5_mr.h"
27 #include "mlx5_flow.h"
28
29 /**
30  * Get mlx5 device attributes.
31  *
32  * @param ctx
33  *   Pointer to device context.
34  *
35  * @param device_attr
36  *   Pointer to mlx5 device attributes.
37  *
38  * @return
39  *   0 on success, non zero error number otherwise
40  */
41 int
42 mlx5_os_get_dev_attr(void *ctx, struct mlx5_dev_attr *device_attr)
43 {
44         struct mlx5_context *mlx5_ctx;
45         struct mlx5_hca_attr hca_attr;
46         void *pv_iseg = NULL;
47         u32 cb_iseg = 0;
48         int err = 0;
49
50         if (!ctx)
51                 return -EINVAL;
52         mlx5_ctx = (struct mlx5_context *)ctx;
53         memset(device_attr, 0, sizeof(*device_attr));
54         err = mlx5_devx_cmd_query_hca_attr(mlx5_ctx, &hca_attr);
55         if (err) {
56                 DRV_LOG(ERR, "Failed to get device hca_cap");
57                 return err;
58         }
59         device_attr->max_cq = 1 << hca_attr.log_max_cq;
60         device_attr->max_qp = 1 << hca_attr.log_max_qp;
61         device_attr->max_qp_wr = 1 << hca_attr.log_max_qp_sz;
62         device_attr->max_cqe = 1 << hca_attr.log_max_cq_sz;
63         device_attr->max_mr = 1 << hca_attr.log_max_mrw_sz;
64         device_attr->max_pd = 1 << hca_attr.log_max_pd;
65         device_attr->max_srq = 1 << hca_attr.log_max_srq;
66         device_attr->max_srq_wr = 1 << hca_attr.log_max_srq_sz;
67         if (hca_attr.rss_ind_tbl_cap) {
68                 device_attr->max_rwq_indirection_table_size =
69                         1 << hca_attr.rss_ind_tbl_cap;
70         }
71         pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
72         if (pv_iseg == NULL) {
73                 DRV_LOG(ERR, "Failed to get device hca_iseg");
74                 return errno;
75         }
76         if (!err) {
77                 snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
78                         MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
79                         MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
80                         MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
81         }
82         return err;
83 }
84
85 /**
86  * Set the completion channel file descriptor interrupt as non-blocking.
87  * Currently it has no support under Windows.
88  *
89  * @param[in] rxq_obj
90  *   Pointer to RQ channel object, which includes the channel fd
91  *
92  * @param[out] fd
93  *   The file descriptor (representing the intetrrupt) used in this channel.
94  *
95  * @return
96  *   0 on successfully setting the fd to non-blocking, non-zero otherwise.
97  */
98 int
99 mlx5_os_set_nonblock_channel_fd(int fd)
100 {
101         (void)fd;
102         DRV_LOG(WARNING, "%s: is not supported", __func__);
103         return -ENOTSUP;
104 }
105
106 /**
107  * Function API open device under Windows
108  *
109  * This function calls the Windows glue APIs to open a device.
110  *
111  * @param[in] spawn
112  *   Pointer to the device attributes (name, port, etc).
113  * @param[out] config
114  *   Pointer to device configuration structure.
115  * @param[out] sh
116  *   Pointer to shared context structure.
117  *
118  * @return
119  *   0 on success, a positive error value otherwise.
120  */
121 int
122 mlx5_os_open_device(const struct mlx5_dev_spawn_data *spawn,
123                  const struct mlx5_dev_config *config,
124                  struct mlx5_dev_ctx_shared *sh)
125 {
126         RTE_SET_USED(config);
127         int err = 0;
128         struct mlx5_context *mlx5_ctx;
129
130         pthread_mutex_init(&sh->txpp.mutex, NULL);
131         /* Set numa node from pci probe */
132         sh->numa_node = spawn->pci_dev->device.numa_node;
133
134         /* Try to open device with DevX */
135         rte_errno = 0;
136         sh->ctx = mlx5_glue->open_device(spawn->phys_dev);
137         if (!sh->ctx) {
138                 DRV_LOG(ERR, "open_device failed");
139                 err = errno;
140                 return err;
141         }
142         sh->devx = 1;
143         mlx5_ctx = (struct mlx5_context *)sh->ctx;
144         err = mlx5_glue->query_device(spawn->phys_dev, &mlx5_ctx->mlx5_dev);
145         if (err)
146                 DRV_LOG(ERR, "Failed to query device context fields.");
147         return err;
148 }
149
150 /**
151  * This function should share events between multiple ports of single IB
152  * device.  Currently it has no support under Windows.
153  *
154  * @param sh
155  *   Pointer to mlx5_dev_ctx_shared object.
156  */
157 void
158 mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh)
159 {
160         (void)sh;
161         DRV_LOG(WARNING, "%s: is not supported", __func__);
162 }
163
164 /**
165  * This function should share events between multiple ports of single IB
166  * device.  Currently it has no support under Windows.
167  *
168  * @param dev
169  *   Pointer to mlx5_dev_ctx_shared object.
170  */
171 void
172 mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh)
173 {
174         (void)sh;
175         DRV_LOG(WARNING, "%s: is not supported", __func__);
176 }
177
178 /**
179  * Read statistics by a named counter.
180  *
181  * @param[in] priv
182  *   Pointer to the private device data structure.
183  * @param[in] ctr_name
184  *   Pointer to the name of the statistic counter to read
185  * @param[out] stat
186  *   Pointer to read statistic value.
187  * @return
188  *   0 on success and stat is valud, 1 if failed to read the value
189  *   rte_errno is set.
190  *
191  */
192 int
193 mlx5_os_read_dev_stat(struct mlx5_priv *priv, const char *ctr_name,
194                       uint64_t *stat)
195 {
196         RTE_SET_USED(priv);
197         RTE_SET_USED(ctr_name);
198         RTE_SET_USED(stat);
199         DRV_LOG(WARNING, "%s: is not supported", __func__);
200         return -ENOTSUP;
201 }
202
203 /**
204  * Flush device MAC addresses
205  * Currently it has no support under Windows.
206  *
207  * @param dev
208  *   Pointer to Ethernet device structure.
209  *
210  */
211 void
212 mlx5_os_mac_addr_flush(struct rte_eth_dev *dev)
213 {
214         (void)dev;
215         DRV_LOG(WARNING, "%s: is not supported", __func__);
216 }
217
218 /**
219  * Remove a MAC address from device
220  * Currently it has no support under Windows.
221  *
222  * @param dev
223  *   Pointer to Ethernet device structure.
224  * @param index
225  *   MAC address index.
226  */
227 void
228 mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
229 {
230         (void)dev;
231         (void)(index);
232         DRV_LOG(WARNING, "%s: is not supported", __func__);
233 }
234
235 /**
236  * Adds a MAC address to the device
237  * Currently it has no support under Windows.
238  *
239  * @param dev
240  *   Pointer to Ethernet device structure.
241  * @param mac_addr
242  *   MAC address to register.
243  * @param index
244  *   MAC address index.
245  *
246  * @return
247  *   0 on success, a negative errno value otherwise
248  */
249 int
250 mlx5_os_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
251                      uint32_t index)
252 {
253         (void)index;
254         struct rte_ether_addr lmac;
255
256         if (mlx5_get_mac(dev, &lmac.addr_bytes)) {
257                 DRV_LOG(ERR,
258                         "port %u cannot get MAC address, is mlx5_en"
259                         " loaded? (errno: %s)",
260                         dev->data->port_id, strerror(rte_errno));
261                 return rte_errno;
262         }
263         if (!rte_is_same_ether_addr(&lmac, mac)) {
264                 DRV_LOG(ERR,
265                         "adding new mac address to device is unsupported");
266                 return -ENOTSUP;
267         }
268         return 0;
269 }
270
271 /**
272  * Modify a VF MAC address
273  * Currently it has no support under Windows.
274  *
275  * @param priv
276  *   Pointer to device private data.
277  * @param mac_addr
278  *   MAC address to modify into.
279  * @param iface_idx
280  *   Net device interface index
281  * @param vf_index
282  *   VF index
283  *
284  * @return
285  *   0 on success, a negative errno value otherwise
286  */
287 int
288 mlx5_os_vf_mac_addr_modify(struct mlx5_priv *priv,
289                            unsigned int iface_idx,
290                            struct rte_ether_addr *mac_addr,
291                            int vf_index)
292 {
293         (void)priv;
294         (void)iface_idx;
295         (void)mac_addr;
296         (void)vf_index;
297         DRV_LOG(WARNING, "%s: is not supported", __func__);
298         return -ENOTSUP;
299 }
300
301 /**
302  * Set device promiscuous mode
303  * Currently it has no support under Windows.
304  *
305  * @param dev
306  *   Pointer to Ethernet device structure.
307  * @param enable
308  *   0 - promiscuous is disabled, otherwise - enabled
309  *
310  * @return
311  *   0 on success, a negative error value otherwise
312  */
313 int
314 mlx5_os_set_promisc(struct rte_eth_dev *dev, int enable)
315 {
316         (void)dev;
317         (void)enable;
318         DRV_LOG(WARNING, "%s: is not supported", __func__);
319         return -ENOTSUP;
320 }
321
322 /**
323  * Set device allmulti mode
324  *
325  * @param dev
326  *   Pointer to Ethernet device structure.
327  * @param enable
328  *   0 - all multicase is disabled, otherwise - enabled
329  *
330  * @return
331  *   0 on success, a negative error value otherwise
332  */
333 int
334 mlx5_os_set_allmulti(struct rte_eth_dev *dev, int enable)
335 {
336         (void)dev;
337         (void)enable;
338         DRV_LOG(WARNING, "%s: is not supported", __func__);
339         return -ENOTSUP;
340 }
341
342 /**
343  * Set the reg_mr and dereg_mr call backs
344  *
345  * @param reg_mr_cb[out]
346  *   Pointer to reg_mr func
347  * @param dereg_mr_cb[out]
348  *   Pointer to dereg_mr func
349  *
350  */
351 void
352 mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb,
353                       mlx5_dereg_mr_t *dereg_mr_cb)
354 {
355         *reg_mr_cb = mlx5_os_reg_mr;
356         *dereg_mr_cb = mlx5_os_dereg_mr;
357 }
358
359 /**
360  * Extract pdn of PD object using DevX
361  *
362  * @param[in] pd
363  *   Pointer to the DevX PD object.
364  * @param[out] pdn
365  *   Pointer to the PD object number variable.
366  *
367  * @return
368  *   0 on success, error value otherwise.
369  */
370 int
371 mlx5_os_get_pdn(void *pd, uint32_t *pdn)
372 {
373         if (!pd)
374                 return -EINVAL;
375
376         *pdn = ((struct mlx5_pd *)pd)->pdn;
377         return 0;
378 }
379
380 const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {0};
381
382 const struct eth_dev_ops mlx5_os_dev_ops = {
383         .dev_configure = mlx5_dev_configure,
384         .dev_start = mlx5_dev_start,
385         .dev_stop = mlx5_dev_stop,
386         .dev_close = mlx5_dev_close,
387         .mtu_set = mlx5_dev_set_mtu,
388         .link_update = mlx5_link_update,
389         .stats_get = mlx5_stats_get,
390         .stats_reset = mlx5_stats_reset,
391         .dev_infos_get = mlx5_dev_infos_get,
392         .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
393         .promiscuous_enable = mlx5_promiscuous_enable,
394         .promiscuous_disable = mlx5_promiscuous_disable,
395         .allmulticast_enable = mlx5_allmulticast_enable,
396         .allmulticast_disable = mlx5_allmulticast_disable,
397         .xstats_get = mlx5_xstats_get,
398         .xstats_reset = mlx5_xstats_reset,
399         .xstats_get_names = mlx5_xstats_get_names,
400         .fw_version_get = mlx5_fw_version_get,
401         .read_clock = mlx5_read_clock,
402         .vlan_filter_set = mlx5_vlan_filter_set,
403         .rx_queue_setup = mlx5_rx_queue_setup,
404         .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
405         .tx_queue_setup = mlx5_tx_queue_setup,
406         .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
407         .rx_queue_release = mlx5_rx_queue_release,
408         .tx_queue_release = mlx5_tx_queue_release,
409         .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
410         .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
411         .mac_addr_remove = mlx5_mac_addr_remove,
412         .mac_addr_add = mlx5_mac_addr_add,
413         .mac_addr_set = mlx5_mac_addr_set,
414         .set_mc_addr_list = mlx5_set_mc_addr_list,
415         .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
416         .vlan_offload_set = mlx5_vlan_offload_set,
417         .reta_update = mlx5_dev_rss_reta_update,
418         .reta_query = mlx5_dev_rss_reta_query,
419         .rss_hash_update = mlx5_rss_hash_update,
420         .rss_hash_conf_get = mlx5_rss_hash_conf_get,
421         .filter_ctrl = mlx5_dev_filter_ctrl,
422         .rxq_info_get = mlx5_rxq_info_get,
423         .txq_info_get = mlx5_txq_info_get,
424         .rx_burst_mode_get = mlx5_rx_burst_mode_get,
425         .tx_burst_mode_get = mlx5_tx_burst_mode_get,
426         .rx_queue_intr_enable = mlx5_rx_intr_enable,
427         .rx_queue_intr_disable = mlx5_rx_intr_disable,
428         .is_removed = mlx5_is_removed,
429         .udp_tunnel_port_add  = mlx5_udp_tunnel_port_add,
430         .get_module_info = mlx5_get_module_info,
431         .get_module_eeprom = mlx5_get_module_eeprom,
432         .hairpin_cap_get = mlx5_hairpin_cap_get,
433         .mtr_ops_get = mlx5_flow_meter_ops_get,
434 };
435
436 /* Available operations from secondary process. */
437 const struct eth_dev_ops mlx5_os_dev_sec_ops = {0};
438
439 /* Available operations in flow isolated mode. */
440 const struct eth_dev_ops mlx5_os_dev_ops_isolate = {
441         .dev_configure = mlx5_dev_configure,
442         .dev_start = mlx5_dev_start,
443         .dev_stop = mlx5_dev_stop,
444         .dev_close = mlx5_dev_close,
445         .mtu_set = mlx5_dev_set_mtu,
446         .link_update = mlx5_link_update,
447         .stats_get = mlx5_stats_get,
448         .stats_reset = mlx5_stats_reset,
449         .dev_infos_get = mlx5_dev_infos_get,
450         .dev_set_link_down = mlx5_set_link_down,
451         .dev_set_link_up = mlx5_set_link_up,
452         .promiscuous_enable = mlx5_promiscuous_enable,
453         .promiscuous_disable = mlx5_promiscuous_disable,
454         .allmulticast_enable = mlx5_allmulticast_enable,
455         .allmulticast_disable = mlx5_allmulticast_disable,
456         .xstats_get = mlx5_xstats_get,
457         .xstats_reset = mlx5_xstats_reset,
458         .xstats_get_names = mlx5_xstats_get_names,
459         .fw_version_get = mlx5_fw_version_get,
460         .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
461         .vlan_filter_set = mlx5_vlan_filter_set,
462         .rx_queue_setup = mlx5_rx_queue_setup,
463         .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
464         .tx_queue_setup = mlx5_tx_queue_setup,
465         .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
466         .rx_queue_release = mlx5_rx_queue_release,
467         .tx_queue_release = mlx5_tx_queue_release,
468         .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
469         .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
470         .mac_addr_remove = mlx5_mac_addr_remove,
471         .mac_addr_add = mlx5_mac_addr_add,
472         .mac_addr_set = mlx5_mac_addr_set,
473         .set_mc_addr_list = mlx5_set_mc_addr_list,
474         .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
475         .vlan_offload_set = mlx5_vlan_offload_set,
476         .filter_ctrl = mlx5_dev_filter_ctrl,
477         .rxq_info_get = mlx5_rxq_info_get,
478         .txq_info_get = mlx5_txq_info_get,
479         .rx_burst_mode_get = mlx5_rx_burst_mode_get,
480         .tx_burst_mode_get = mlx5_tx_burst_mode_get,
481         .rx_queue_intr_enable = mlx5_rx_intr_enable,
482         .rx_queue_intr_disable = mlx5_rx_intr_disable,
483         .is_removed = mlx5_is_removed,
484         .get_module_info = mlx5_get_module_info,
485         .get_module_eeprom = mlx5_get_module_eeprom,
486         .hairpin_cap_get = mlx5_hairpin_cap_get,
487         .mtr_ops_get = mlx5_flow_meter_ops_get,
488 };