1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2019 Hisilicon Limited.
8 #include <rte_ethdev_driver.h>
9 #include <rte_string_fns.h>
12 #include "hns3_ethdev.h"
13 #include "hns3_logs.h"
14 #include "hns3_rxtx.h"
17 static bool hns3_inited;
20 * Initialize IPC message.
23 * Pointer to Ethernet structure.
25 * Pointer to message to fill in.
30 mp_init_msg(struct rte_eth_dev *dev, struct rte_mp_msg *msg,
31 enum hns3_mp_req_type type)
33 struct hns3_mp_param *param = (struct hns3_mp_param *)msg->param;
35 memset(msg, 0, sizeof(*msg));
36 strlcpy(msg->name, HNS3_MP_NAME, sizeof(msg->name));
37 msg->len_param = sizeof(*param);
39 param->port_id = dev->data->port_id;
43 * IPC message handler of primary process.
46 * Pointer to Ethernet structure.
48 * Pointer to the peer socket path.
51 * 0 on success, a negative errno value otherwise and rte_errno is set.
54 mp_primary_handle(const struct rte_mp_msg *mp_msg __rte_unused,
55 const void *peer __rte_unused)
61 * IPC message handler of a secondary process.
64 * Pointer to Ethernet structure.
66 * Pointer to the peer socket path.
69 * 0 on success, a negative errno value otherwise and rte_errno is set.
72 mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
74 struct rte_mp_msg mp_res;
75 struct hns3_mp_param *res = (struct hns3_mp_param *)mp_res.param;
76 const struct hns3_mp_param *param =
77 (const struct hns3_mp_param *)mp_msg->param;
78 struct rte_eth_dev *dev;
81 if (!rte_eth_dev_is_valid_port(param->port_id)) {
83 PMD_INIT_LOG(ERR, "port %u invalid port ID", param->port_id);
86 dev = &rte_eth_devices[param->port_id];
87 switch (param->type) {
88 case HNS3_MP_REQ_START_RXTX:
89 PMD_INIT_LOG(INFO, "port %u starting datapath",
92 hns3_set_rxtx_function(dev);
93 mp_init_msg(dev, &mp_res, param->type);
95 ret = rte_mp_reply(&mp_res, peer);
97 case HNS3_MP_REQ_STOP_RXTX:
98 PMD_INIT_LOG(INFO, "port %u stopping datapath",
100 hns3_set_rxtx_function(dev);
102 mp_init_msg(dev, &mp_res, param->type);
104 ret = rte_mp_reply(&mp_res, peer);
108 PMD_INIT_LOG(ERR, "port %u invalid mp request type",
116 * Broadcast request of stopping/starting data-path to secondary processes.
119 * Pointer to Ethernet structure.
124 mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type)
126 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
127 struct rte_mp_msg mp_req;
128 struct rte_mp_msg *mp_res;
129 struct rte_mp_reply mp_rep;
130 struct hns3_mp_param *res;
135 if (!hw->secondary_cnt)
137 if (type != HNS3_MP_REQ_START_RXTX && type != HNS3_MP_REQ_STOP_RXTX) {
138 hns3_err(hw, "port %u unknown request (req_type %d)",
139 dev->data->port_id, type);
142 mp_init_msg(dev, &mp_req, type);
143 ts.tv_sec = HNS3_MP_REQ_TIMEOUT_SEC;
145 ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
147 hns3_err(hw, "port %u failed to request stop/start Rx/Tx (%d)",
148 dev->data->port_id, type);
151 if (mp_rep.nb_sent != mp_rep.nb_received) {
153 "port %u not all secondaries responded (req_type %d)",
154 dev->data->port_id, type);
157 for (i = 0; i < mp_rep.nb_received; i++) {
158 mp_res = &mp_rep.msgs[i];
159 res = (struct hns3_mp_param *)mp_res->param;
161 hns3_err(hw, "port %u request failed on secondary #%d",
162 dev->data->port_id, i);
171 * Broadcast request of starting data-path to secondary processes. The request
175 * Pointer to Ethernet structure.
177 void hns3_mp_req_start_rxtx(struct rte_eth_dev *dev)
179 mp_req_on_rxtx(dev, HNS3_MP_REQ_START_RXTX);
183 * Broadcast request of stopping data-path to secondary processes. The request
187 * Pointer to Ethernet structure.
189 void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev)
191 mp_req_on_rxtx(dev, HNS3_MP_REQ_STOP_RXTX);
195 * Initialize by primary process.
197 int hns3_mp_init_primary(void)
202 /* primary is allowed to not support IPC */
203 ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle);
204 if (ret && rte_errno != ENOTSUP)
214 * Un-initialize by primary process.
216 void hns3_mp_uninit_primary(void)
219 rte_mp_action_unregister(HNS3_MP_NAME);
223 * Initialize by secondary process.
225 int hns3_mp_init_secondary(void)
230 ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle);