net/mlx5: replace IPC socket with EAL API
[dpdk.git] / drivers / net / mlx5 / mlx5_mp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2019 6WIND S.A.
3  * Copyright 2019 Mellanox Technologies, Ltd
4  */
5
6 #include <assert.h>
7 #include <stdio.h>
8 #include <time.h>
9
10 #include <rte_eal.h>
11 #include <rte_ethdev_driver.h>
12 #include <rte_string_fns.h>
13
14 #include "mlx5.h"
15 #include "mlx5_utils.h"
16
17 /**
18  * Initialize IPC message.
19  *
20  * @param[in] dev
21  *   Pointer to Ethernet structure.
22  * @param[out] msg
23  *   Pointer to message to fill in.
24  * @param[in] type
25  *   Message type.
26  */
27 static inline void
28 mp_init_msg(struct rte_eth_dev *dev, struct rte_mp_msg *msg,
29             enum mlx5_mp_req_type type)
30 {
31         struct mlx5_mp_param *param = (struct mlx5_mp_param *)msg->param;
32
33         memset(msg, 0, sizeof(*msg));
34         strlcpy(msg->name, MLX5_MP_NAME, sizeof(msg->name));
35         msg->len_param = sizeof(*param);
36         param->type = type;
37         param->port_id = dev->data->port_id;
38 }
39
40 /**
41  * IPC message handler of primary process.
42  *
43  * @param[in] dev
44  *   Pointer to Ethernet structure.
45  * @param[in] peer
46  *   Pointer to the peer socket path.
47  *
48  * @return
49  *   0 on success, a negative errno value otherwise and rte_errno is set.
50  */
51 static int
52 mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
53 {
54         struct rte_mp_msg mp_res;
55         struct mlx5_mp_param *res = (struct mlx5_mp_param *)mp_res.param;
56         const struct mlx5_mp_param *param =
57                 (const struct mlx5_mp_param *)mp_msg->param;
58         struct rte_eth_dev *dev;
59         struct mlx5_priv *priv;
60         int ret;
61
62         assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
63         if (!rte_eth_dev_is_valid_port(param->port_id)) {
64                 rte_errno = ENODEV;
65                 DRV_LOG(ERR, "port %u invalid port ID", param->port_id);
66                 return -rte_errno;
67         }
68         dev = &rte_eth_devices[param->port_id];
69         priv = dev->data->dev_private;
70         switch (param->type) {
71         case MLX5_MP_REQ_VERBS_CMD_FD:
72                 mp_init_msg(dev, &mp_res, param->type);
73                 mp_res.num_fds = 1;
74                 mp_res.fds[0] = priv->sh->ctx->cmd_fd;
75                 res->result = 0;
76                 ret = rte_mp_reply(&mp_res, peer);
77                 break;
78         default:
79                 rte_errno = EINVAL;
80                 DRV_LOG(ERR, "port %u invalid mp request type",
81                         dev->data->port_id);
82                 return -rte_errno;
83         }
84         return ret;
85 }
86
87 /**
88  * Request Verbs command file descriptor for mmap to the primary process.
89  *
90  * @param[in] dev
91  *   Pointer to Ethernet structure.
92  *
93  * @return
94  *   fd on success, a negative errno value otherwise and rte_errno is set.
95  */
96 int
97 mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
98 {
99         struct rte_mp_msg mp_req;
100         struct rte_mp_msg *mp_res;
101         struct rte_mp_reply mp_rep;
102         struct mlx5_mp_param *res;
103         struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
104         int ret;
105
106         assert(rte_eal_process_type() == RTE_PROC_SECONDARY);
107         mp_init_msg(dev, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD);
108         ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
109         if (ret) {
110                 DRV_LOG(ERR, "port %u request to primary process failed",
111                         dev->data->port_id);
112                 return -rte_errno;
113         }
114         assert(mp_rep.nb_received == 1);
115         mp_res = &mp_rep.msgs[0];
116         res = (struct mlx5_mp_param *)mp_res->param;
117         if (res->result) {
118                 rte_errno = -res->result;
119                 DRV_LOG(ERR,
120                         "port %u failed to get command FD from primary process",
121                         dev->data->port_id);
122                 ret = -rte_errno;
123                 goto exit;
124         }
125         assert(mp_res->num_fds == 1);
126         ret = mp_res->fds[0];
127         DRV_LOG(DEBUG, "port %u command FD from primary is %d",
128                 dev->data->port_id, ret);
129 exit:
130         free(mp_rep.msgs);
131         return ret;
132 }
133
134 void
135 mlx5_mp_init(void)
136 {
137         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
138                 rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);
139 }