1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2019 6WIND S.A.
3 * Copyright 2019 Mellanox Technologies, Ltd
11 #include <rte_ethdev_driver.h>
12 #include <rte_string_fns.h>
15 #include "mlx5_utils.h"
18 * Initialize IPC message.
21 * Pointer to Ethernet structure.
23 * Pointer to message to fill in.
28 mp_init_msg(struct rte_eth_dev *dev, struct rte_mp_msg *msg,
29 enum mlx5_mp_req_type type)
31 struct mlx5_mp_param *param = (struct mlx5_mp_param *)msg->param;
33 memset(msg, 0, sizeof(*msg));
34 strlcpy(msg->name, MLX5_MP_NAME, sizeof(msg->name));
35 msg->len_param = sizeof(*param);
37 param->port_id = dev->data->port_id;
41 * IPC message handler of primary process.
44 * Pointer to Ethernet structure.
46 * Pointer to the peer socket path.
49 * 0 on success, a negative errno value otherwise and rte_errno is set.
52 mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
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;
62 assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
63 if (!rte_eth_dev_is_valid_port(param->port_id)) {
65 DRV_LOG(ERR, "port %u invalid port ID", param->port_id);
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);
74 mp_res.fds[0] = priv->sh->ctx->cmd_fd;
76 ret = rte_mp_reply(&mp_res, peer);
80 DRV_LOG(ERR, "port %u invalid mp request type",
88 * Request Verbs command file descriptor for mmap to the primary process.
91 * Pointer to Ethernet structure.
94 * fd on success, a negative errno value otherwise and rte_errno is set.
97 mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)
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};
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);
110 DRV_LOG(ERR, "port %u request to primary process failed",
114 assert(mp_rep.nb_received == 1);
115 mp_res = &mp_rep.msgs[0];
116 res = (struct mlx5_mp_param *)mp_res->param;
118 rte_errno = -res->result;
120 "port %u failed to get command FD from primary process",
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);
137 if (rte_eal_process_type() == RTE_PROC_PRIMARY)
138 rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);