1
2
3
4
5#include <rte_eal.h>
6#include <ethdev_driver.h>
7#include <rte_string_fns.h>
8#include <rte_io.h>
9
10#include "hns3_ethdev.h"
11#include "hns3_logs.h"
12#include "hns3_rxtx.h"
13#include "hns3_mp.h"
14
15static bool hns3_inited;
16
17
18
19
20
21
22
23
24
25
26
27static inline void
28mp_init_msg(struct rte_eth_dev *dev, struct rte_mp_msg *msg,
29 enum hns3_mp_req_type type)
30{
31 struct hns3_mp_param *param = (struct hns3_mp_param *)msg->param;
32
33 memset(msg, 0, sizeof(*msg));
34 strlcpy(msg->name, HNS3_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
42
43
44
45
46
47
48
49
50
51static int
52mp_primary_handle(const struct rte_mp_msg *mp_msg __rte_unused,
53 const void *peer __rte_unused)
54{
55 return 0;
56}
57
58
59
60
61
62
63
64
65
66
67
68
69static int
70mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
71{
72 struct rte_mp_msg mp_res;
73 struct hns3_mp_param *res = (struct hns3_mp_param *)mp_res.param;
74 const struct hns3_mp_param *param =
75 (const struct hns3_mp_param *)mp_msg->param;
76 struct rte_eth_dev *dev;
77 int ret;
78
79 if (!rte_eth_dev_is_valid_port(param->port_id)) {
80 rte_errno = ENODEV;
81 PMD_INIT_LOG(ERR, "port %d invalid port ID", param->port_id);
82 return -rte_errno;
83 }
84 dev = &rte_eth_devices[param->port_id];
85 switch (param->type) {
86 case HNS3_MP_REQ_START_RXTX:
87 PMD_INIT_LOG(INFO, "port %u starting datapath",
88 dev->data->port_id);
89 hns3_set_rxtx_function(dev);
90 rte_mb();
91 mp_init_msg(dev, &mp_res, param->type);
92 res->result = 0;
93 ret = rte_mp_reply(&mp_res, peer);
94 break;
95 case HNS3_MP_REQ_STOP_RXTX:
96 PMD_INIT_LOG(INFO, "port %u stopping datapath",
97 dev->data->port_id);
98 hns3_set_rxtx_function(dev);
99 rte_mb();
100 mp_init_msg(dev, &mp_res, param->type);
101 res->result = 0;
102 ret = rte_mp_reply(&mp_res, peer);
103 break;
104 default:
105 rte_errno = EINVAL;
106 PMD_INIT_LOG(ERR, "port %u invalid mp request type",
107 dev->data->port_id);
108 return -rte_errno;
109 }
110 return ret;
111}
112
113
114
115
116
117
118
119
120
121static void
122mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type)
123{
124 struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
125 struct rte_mp_msg mp_req;
126 struct rte_mp_msg *mp_res;
127 struct rte_mp_reply mp_rep;
128 struct hns3_mp_param *res;
129 struct timespec ts;
130 int ret;
131 int i;
132
133 if (rte_eal_process_type() == RTE_PROC_SECONDARY || !hw->secondary_cnt)
134 return;
135 if (type != HNS3_MP_REQ_START_RXTX && type != HNS3_MP_REQ_STOP_RXTX) {
136 hns3_err(hw, "port %u unknown request (req_type %d)",
137 dev->data->port_id, type);
138 return;
139 }
140 mp_init_msg(dev, &mp_req, type);
141 ts.tv_sec = HNS3_MP_REQ_TIMEOUT_SEC;
142 ts.tv_nsec = 0;
143 ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
144 if (ret) {
145 hns3_err(hw, "port %u failed to request stop/start Rx/Tx (%d)",
146 dev->data->port_id, type);
147 goto exit;
148 }
149 if (mp_rep.nb_sent != mp_rep.nb_received) {
150 PMD_INIT_LOG(ERR,
151 "port %u not all secondaries responded (req_type %d)",
152 dev->data->port_id, type);
153 goto exit;
154 }
155 for (i = 0; i < mp_rep.nb_received; i++) {
156 mp_res = &mp_rep.msgs[i];
157 res = (struct hns3_mp_param *)mp_res->param;
158 if (res->result) {
159 hns3_err(hw, "port %u request failed on secondary #%d",
160 dev->data->port_id, i);
161 goto exit;
162 }
163 }
164exit:
165 free(mp_rep.msgs);
166}
167
168
169
170
171
172
173
174
175void hns3_mp_req_start_rxtx(struct rte_eth_dev *dev)
176{
177 mp_req_on_rxtx(dev, HNS3_MP_REQ_START_RXTX);
178}
179
180
181
182
183
184
185
186
187void hns3_mp_req_stop_rxtx(struct rte_eth_dev *dev)
188{
189 mp_req_on_rxtx(dev, HNS3_MP_REQ_STOP_RXTX);
190}
191
192
193
194
195int hns3_mp_init_primary(void)
196{
197 int ret;
198
199 if (!hns3_inited) {
200
201 ret = rte_mp_action_register(HNS3_MP_NAME, mp_primary_handle);
202 if (ret && rte_errno != ENOTSUP)
203 return ret;
204
205 hns3_inited = true;
206 }
207
208 return 0;
209}
210
211
212
213
214void hns3_mp_uninit_primary(void)
215{
216 if (hns3_inited)
217 rte_mp_action_unregister(HNS3_MP_NAME);
218}
219
220
221
222
223int hns3_mp_init_secondary(void)
224{
225 int ret;
226
227 if (!hns3_inited) {
228 ret = rte_mp_action_register(HNS3_MP_NAME, mp_secondary_handle);
229 if (ret)
230 return ret;
231
232 hns3_inited = true;
233 }
234
235 return 0;
236}
237