xref: /dpdk/drivers/net/cnxk/cnxk_rep_msg.c (revision 30d38a718b9f63f0bda9e24dae90486303f1b206)
1804c5856SHarman Kalra /* SPDX-License-Identifier: BSD-3-Clause
2804c5856SHarman Kalra  * Copyright(C) 2024 Marvell.
3804c5856SHarman Kalra  */
4804c5856SHarman Kalra 
5804c5856SHarman Kalra #include <cnxk_rep.h>
6804c5856SHarman Kalra #include <cnxk_rep_msg.h>
7804c5856SHarman Kalra 
8804c5856SHarman Kalra #define CTRL_MSG_RCV_TIMEOUT_MS 2000
9804c5856SHarman Kalra #define CTRL_MSG_READY_WAIT_US	2000
10804c5856SHarman Kalra #define CTRL_MSG_THRD_NAME_LEN	35
11804c5856SHarman Kalra #define CTRL_MSG_BUFFER_SZ	1500
12804c5856SHarman Kalra #define CTRL_MSG_SIGNATURE	0xcdacdeadbeefcadc
13804c5856SHarman Kalra 
14804c5856SHarman Kalra static void
close_socket(int fd)15804c5856SHarman Kalra close_socket(int fd)
16804c5856SHarman Kalra {
17804c5856SHarman Kalra 	close(fd);
18804c5856SHarman Kalra 	unlink(CNXK_ESWITCH_CTRL_MSG_SOCK_PATH);
19804c5856SHarman Kalra }
20804c5856SHarman Kalra 
21804c5856SHarman Kalra static int
receive_control_message(int socketfd,void * data,uint32_t len)22804c5856SHarman Kalra receive_control_message(int socketfd, void *data, uint32_t len)
23804c5856SHarman Kalra {
24804c5856SHarman Kalra 	char ctl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred))] = {0};
25804c5856SHarman Kalra 	struct ucred *cr __rte_unused;
26804c5856SHarman Kalra 	struct msghdr mh = {0};
27804c5856SHarman Kalra 	struct cmsghdr *cmsg;
28804c5856SHarman Kalra 	static uint64_t rec;
29804c5856SHarman Kalra 	struct iovec iov[1];
30804c5856SHarman Kalra 	ssize_t size;
31804c5856SHarman Kalra 	int afd = -1;
32804c5856SHarman Kalra 
33804c5856SHarman Kalra 	iov[0].iov_base = data;
34804c5856SHarman Kalra 	iov[0].iov_len = len;
35804c5856SHarman Kalra 	mh.msg_iov = iov;
36804c5856SHarman Kalra 	mh.msg_iovlen = 1;
37804c5856SHarman Kalra 	mh.msg_control = ctl;
38804c5856SHarman Kalra 	mh.msg_controllen = sizeof(ctl);
39804c5856SHarman Kalra 
40804c5856SHarman Kalra 	size = recvmsg(socketfd, &mh, MSG_DONTWAIT);
41804c5856SHarman Kalra 	if (size < 0) {
42804c5856SHarman Kalra 		if (errno == EAGAIN)
43804c5856SHarman Kalra 			return 0;
44804c5856SHarman Kalra 		plt_err("recvmsg err %d size %zu", errno, size);
45804c5856SHarman Kalra 		return -errno;
46804c5856SHarman Kalra 	} else if (size == 0) {
47804c5856SHarman Kalra 		return 0;
48804c5856SHarman Kalra 	}
49804c5856SHarman Kalra 
50804c5856SHarman Kalra 	rec++;
51804c5856SHarman Kalra 	plt_rep_dbg("Packet %" PRId64 " Received %" PRId64 " bytes over socketfd %d",
52804c5856SHarman Kalra 		    rec, size, socketfd);
53804c5856SHarman Kalra 
54804c5856SHarman Kalra 	cr = 0;
55804c5856SHarman Kalra 	cmsg = CMSG_FIRSTHDR(&mh);
56804c5856SHarman Kalra 	while (cmsg) {
57804c5856SHarman Kalra 		if (cmsg->cmsg_level == SOL_SOCKET) {
58804c5856SHarman Kalra 			if (cmsg->cmsg_type == SCM_CREDENTIALS) {
59804c5856SHarman Kalra 				cr = (struct ucred *)CMSG_DATA(cmsg);
60804c5856SHarman Kalra 			} else if (cmsg->cmsg_type == SCM_RIGHTS) {
61804c5856SHarman Kalra 				rte_memcpy(&afd, CMSG_DATA(cmsg), sizeof(int));
62804c5856SHarman Kalra 				plt_rep_dbg("afd %d", afd);
63804c5856SHarman Kalra 			}
64804c5856SHarman Kalra 		}
65804c5856SHarman Kalra 		cmsg = CMSG_NXTHDR(&mh, cmsg);
66804c5856SHarman Kalra 	}
67804c5856SHarman Kalra 	return size;
68804c5856SHarman Kalra }
69804c5856SHarman Kalra 
70804c5856SHarman Kalra static int
send_message_on_socket(int socketfd,void * data,uint32_t len,int afd)71804c5856SHarman Kalra send_message_on_socket(int socketfd, void *data, uint32_t len, int afd)
72804c5856SHarman Kalra {
73804c5856SHarman Kalra 	char ctl[CMSG_SPACE(sizeof(int))];
74804c5856SHarman Kalra 	struct msghdr mh = {0};
75804c5856SHarman Kalra 	struct cmsghdr *cmsg;
76804c5856SHarman Kalra 	static uint64_t sent;
77804c5856SHarman Kalra 	struct iovec iov[1];
78804c5856SHarman Kalra 	int size;
79804c5856SHarman Kalra 
80804c5856SHarman Kalra 	iov[0].iov_base = data;
81804c5856SHarman Kalra 	iov[0].iov_len = len;
82804c5856SHarman Kalra 	mh.msg_iov = iov;
83804c5856SHarman Kalra 	mh.msg_iovlen = 1;
84804c5856SHarman Kalra 
85804c5856SHarman Kalra 	if (afd > 0) {
86804c5856SHarman Kalra 		memset(&ctl, 0, sizeof(ctl));
87804c5856SHarman Kalra 		mh.msg_control = ctl;
88804c5856SHarman Kalra 		mh.msg_controllen = sizeof(ctl);
89804c5856SHarman Kalra 		cmsg = CMSG_FIRSTHDR(&mh);
90804c5856SHarman Kalra 		cmsg->cmsg_len = CMSG_LEN(sizeof(int));
91804c5856SHarman Kalra 		cmsg->cmsg_level = SOL_SOCKET;
92804c5856SHarman Kalra 		cmsg->cmsg_type = SCM_RIGHTS;
93804c5856SHarman Kalra 		rte_memcpy(CMSG_DATA(cmsg), &afd, sizeof(int));
94804c5856SHarman Kalra 	}
95804c5856SHarman Kalra 
96804c5856SHarman Kalra 	size = sendmsg(socketfd, &mh, MSG_DONTWAIT);
97804c5856SHarman Kalra 	if (size < 0) {
98804c5856SHarman Kalra 		if (errno == EAGAIN)
99804c5856SHarman Kalra 			return 0;
100804c5856SHarman Kalra 		plt_err("Failed to send message, err %d", -errno);
101804c5856SHarman Kalra 		return -errno;
102804c5856SHarman Kalra 	} else if (size == 0) {
103804c5856SHarman Kalra 		return 0;
104804c5856SHarman Kalra 	}
105804c5856SHarman Kalra 	sent++;
106804c5856SHarman Kalra 	plt_rep_dbg("Sent %" PRId64 " packets of size %d on socketfd %d", sent, size, socketfd);
107804c5856SHarman Kalra 
108804c5856SHarman Kalra 	return size;
109804c5856SHarman Kalra }
110804c5856SHarman Kalra 
111804c5856SHarman Kalra static int
open_socket_ctrl_channel(void)112804c5856SHarman Kalra open_socket_ctrl_channel(void)
113804c5856SHarman Kalra {
114804c5856SHarman Kalra 	struct sockaddr_un un;
115804c5856SHarman Kalra 	int sock_fd;
116804c5856SHarman Kalra 
117804c5856SHarman Kalra 	sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
118804c5856SHarman Kalra 	if (sock_fd < 0) {
119*30d38a71SDavid Marchand 		plt_err("Failed to create unix socket");
120804c5856SHarman Kalra 		return -1;
121804c5856SHarman Kalra 	}
122804c5856SHarman Kalra 
123804c5856SHarman Kalra 	/* Set unix socket path and bind */
124804c5856SHarman Kalra 	memset(&un, 0, sizeof(un));
125804c5856SHarman Kalra 	un.sun_family = AF_UNIX;
126804c5856SHarman Kalra 
127804c5856SHarman Kalra 	if (strlen(CNXK_ESWITCH_CTRL_MSG_SOCK_PATH) > sizeof(un.sun_path) - 1) {
128804c5856SHarman Kalra 		plt_err("Server socket path too long: %s", CNXK_ESWITCH_CTRL_MSG_SOCK_PATH);
129804c5856SHarman Kalra 		close(sock_fd);
130804c5856SHarman Kalra 		return -E2BIG;
131804c5856SHarman Kalra 	}
132804c5856SHarman Kalra 
133804c5856SHarman Kalra 	if (remove(CNXK_ESWITCH_CTRL_MSG_SOCK_PATH) == -1 && errno != ENOENT) {
134804c5856SHarman Kalra 		plt_err("remove-%s", CNXK_ESWITCH_CTRL_MSG_SOCK_PATH);
135804c5856SHarman Kalra 		close(sock_fd);
136804c5856SHarman Kalra 		return -errno;
137804c5856SHarman Kalra 	}
138804c5856SHarman Kalra 
139804c5856SHarman Kalra 	memset(&un, 0, sizeof(struct sockaddr_un));
140804c5856SHarman Kalra 	un.sun_family = AF_UNIX;
141804c5856SHarman Kalra 	strncpy(un.sun_path, CNXK_ESWITCH_CTRL_MSG_SOCK_PATH, sizeof(un.sun_path) - 1);
142804c5856SHarman Kalra 
143804c5856SHarman Kalra 	if (bind(sock_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
144804c5856SHarman Kalra 		plt_err("Failed to bind %s: %s", un.sun_path, strerror(errno));
145804c5856SHarman Kalra 		close(sock_fd);
146804c5856SHarman Kalra 		return -errno;
147804c5856SHarman Kalra 	}
148804c5856SHarman Kalra 
149804c5856SHarman Kalra 	if (listen(sock_fd, 1) < 0) {
150804c5856SHarman Kalra 		plt_err("Failed to listen, err %s", strerror(errno));
151804c5856SHarman Kalra 		close(sock_fd);
152804c5856SHarman Kalra 		return -errno;
153804c5856SHarman Kalra 	}
154804c5856SHarman Kalra 
155804c5856SHarman Kalra 	plt_rep_dbg("Unix socket path %s", un.sun_path);
156804c5856SHarman Kalra 	return sock_fd;
157804c5856SHarman Kalra }
158804c5856SHarman Kalra 
159804c5856SHarman Kalra static int
send_control_message(struct cnxk_eswitch_dev * eswitch_dev,void * buffer,uint32_t len)160804c5856SHarman Kalra send_control_message(struct cnxk_eswitch_dev *eswitch_dev, void *buffer, uint32_t len)
161804c5856SHarman Kalra {
162804c5856SHarman Kalra 	int sz;
163804c5856SHarman Kalra 	int rc = 0;
164804c5856SHarman Kalra 
165804c5856SHarman Kalra 	sz = send_message_on_socket(eswitch_dev->sock_fd, buffer, len, 0);
166804c5856SHarman Kalra 	if (sz < 0) {
167804c5856SHarman Kalra 		plt_err("Error sending message, err %d", sz);
168804c5856SHarman Kalra 		rc = sz;
169804c5856SHarman Kalra 		goto done;
170804c5856SHarman Kalra 	}
171804c5856SHarman Kalra 
172804c5856SHarman Kalra 	/* Ensuring entire message has been processed */
173804c5856SHarman Kalra 	if (sz != (int)len) {
174804c5856SHarman Kalra 		plt_err("Out of %d bytes only %d bytes sent", sz, len);
175804c5856SHarman Kalra 		rc = -EFAULT;
176804c5856SHarman Kalra 		goto done;
177804c5856SHarman Kalra 	}
178804c5856SHarman Kalra 	plt_rep_dbg("Sent %d bytes of buffer", sz);
179804c5856SHarman Kalra done:
180804c5856SHarman Kalra 	return rc;
181804c5856SHarman Kalra }
182804c5856SHarman Kalra 
183804c5856SHarman Kalra void
cnxk_rep_msg_populate_msg_end(void * buffer,uint32_t * length)184804c5856SHarman Kalra cnxk_rep_msg_populate_msg_end(void *buffer, uint32_t *length)
185804c5856SHarman Kalra {
186804c5856SHarman Kalra 	cnxk_rep_msg_populate_command(buffer, length, CNXK_REP_MSG_END, 0);
187804c5856SHarman Kalra }
188804c5856SHarman Kalra 
189804c5856SHarman Kalra void
cnxk_rep_msg_populate_type(void * buffer,uint32_t * length,cnxk_type_t type,uint32_t sz)190804c5856SHarman Kalra cnxk_rep_msg_populate_type(void *buffer, uint32_t *length, cnxk_type_t type, uint32_t sz)
191804c5856SHarman Kalra {
192804c5856SHarman Kalra 	uint32_t len = *length;
193804c5856SHarman Kalra 	cnxk_type_data_t data;
194804c5856SHarman Kalra 
195804c5856SHarman Kalra 	memset(&data, 0, sizeof(cnxk_type_data_t));
196804c5856SHarman Kalra 	/* Prepare type data */
197804c5856SHarman Kalra 	data.type = type;
198804c5856SHarman Kalra 	data.length = sz;
199804c5856SHarman Kalra 
200804c5856SHarman Kalra 	/* Populate the type data */
201804c5856SHarman Kalra 	rte_memcpy(RTE_PTR_ADD(buffer, len), &data, sizeof(cnxk_type_data_t));
202804c5856SHarman Kalra 	len += sizeof(cnxk_type_data_t);
203804c5856SHarman Kalra 
204804c5856SHarman Kalra 	*length = len;
205804c5856SHarman Kalra }
206804c5856SHarman Kalra 
207804c5856SHarman Kalra void
cnxk_rep_msg_populate_header(void * buffer,uint32_t * length)208804c5856SHarman Kalra cnxk_rep_msg_populate_header(void *buffer, uint32_t *length)
209804c5856SHarman Kalra {
210804c5856SHarman Kalra 	cnxk_header_t hdr;
211804c5856SHarman Kalra 	int len;
212804c5856SHarman Kalra 
213804c5856SHarman Kalra 	cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_HEADER, sizeof(cnxk_header_t));
214804c5856SHarman Kalra 
215804c5856SHarman Kalra 	memset(&hdr, 0, sizeof(cnxk_header_t));
216804c5856SHarman Kalra 	len = *length;
217804c5856SHarman Kalra 	/* Prepare header data */
218804c5856SHarman Kalra 	hdr.signature = CTRL_MSG_SIGNATURE;
219804c5856SHarman Kalra 
220804c5856SHarman Kalra 	/* Populate header data */
221804c5856SHarman Kalra 	rte_memcpy(RTE_PTR_ADD(buffer, len), &hdr, sizeof(cnxk_header_t));
222804c5856SHarman Kalra 	len += sizeof(cnxk_header_t);
223804c5856SHarman Kalra 
224804c5856SHarman Kalra 	*length = len;
225804c5856SHarman Kalra }
226804c5856SHarman Kalra 
227804c5856SHarman Kalra void
cnxk_rep_msg_populate_command(void * buffer,uint32_t * length,cnxk_rep_msg_t type,uint32_t size)228804c5856SHarman Kalra cnxk_rep_msg_populate_command(void *buffer, uint32_t *length, cnxk_rep_msg_t type, uint32_t size)
229804c5856SHarman Kalra {
230804c5856SHarman Kalra 	cnxk_rep_msg_data_t msg_data;
231804c5856SHarman Kalra 	uint32_t len;
232804c5856SHarman Kalra 	uint16_t sz = sizeof(cnxk_rep_msg_data_t);
233804c5856SHarman Kalra 
234804c5856SHarman Kalra 	memset(&msg_data, 0, sz);
235804c5856SHarman Kalra 	cnxk_rep_msg_populate_type(buffer, length, CNXK_TYPE_MSG, sz);
236804c5856SHarman Kalra 
237804c5856SHarman Kalra 	len = *length;
238804c5856SHarman Kalra 	/* Prepare command data */
239804c5856SHarman Kalra 	msg_data.type = type;
240804c5856SHarman Kalra 	msg_data.length = size;
241804c5856SHarman Kalra 
242804c5856SHarman Kalra 	/* Populate the command */
243804c5856SHarman Kalra 	rte_memcpy(RTE_PTR_ADD(buffer, len), &msg_data, sz);
244804c5856SHarman Kalra 	len += sz;
245804c5856SHarman Kalra 
246804c5856SHarman Kalra 	*length = len;
247804c5856SHarman Kalra }
248804c5856SHarman Kalra 
249804c5856SHarman Kalra void
cnxk_rep_msg_populate_command_meta(void * buffer,uint32_t * length,void * msg_meta,uint32_t sz,cnxk_rep_msg_t msg)250804c5856SHarman Kalra cnxk_rep_msg_populate_command_meta(void *buffer, uint32_t *length, void *msg_meta, uint32_t sz,
251804c5856SHarman Kalra 				   cnxk_rep_msg_t msg)
252804c5856SHarman Kalra {
253804c5856SHarman Kalra 	uint32_t len;
254804c5856SHarman Kalra 
255804c5856SHarman Kalra 	cnxk_rep_msg_populate_command(buffer, length, msg, sz);
256804c5856SHarman Kalra 
257804c5856SHarman Kalra 	len = *length;
258804c5856SHarman Kalra 	/* Populate command data */
259804c5856SHarman Kalra 	rte_memcpy(RTE_PTR_ADD(buffer, len), msg_meta, sz);
260804c5856SHarman Kalra 	len += sz;
261804c5856SHarman Kalra 
262804c5856SHarman Kalra 	*length = len;
263804c5856SHarman Kalra }
264804c5856SHarman Kalra 
265804c5856SHarman Kalra static int
parse_validate_header(void * msg_buf,uint32_t * buf_trav_len)266804c5856SHarman Kalra parse_validate_header(void *msg_buf, uint32_t *buf_trav_len)
267804c5856SHarman Kalra {
268804c5856SHarman Kalra 	cnxk_type_data_t *tdata = NULL;
269804c5856SHarman Kalra 	cnxk_header_t *hdr = NULL;
270804c5856SHarman Kalra 	void *data = NULL;
271804c5856SHarman Kalra 	uint16_t len = 0;
272804c5856SHarman Kalra 
273804c5856SHarman Kalra 	/* Read first bytes of type data */
274804c5856SHarman Kalra 	data = msg_buf;
275804c5856SHarman Kalra 	tdata = (cnxk_type_data_t *)data;
276804c5856SHarman Kalra 	if (tdata->type != CNXK_TYPE_HEADER) {
277804c5856SHarman Kalra 		plt_err("Invalid type %d, type header expected", tdata->type);
278804c5856SHarman Kalra 		goto fail;
279804c5856SHarman Kalra 	}
280804c5856SHarman Kalra 
281804c5856SHarman Kalra 	/* Get the header value */
282804c5856SHarman Kalra 	data = RTE_PTR_ADD(msg_buf, sizeof(cnxk_type_data_t));
283804c5856SHarman Kalra 	len += sizeof(cnxk_type_data_t);
284804c5856SHarman Kalra 
285804c5856SHarman Kalra 	/* Validate the header */
286804c5856SHarman Kalra 	hdr = (cnxk_header_t *)data;
287804c5856SHarman Kalra 	if (hdr->signature != CTRL_MSG_SIGNATURE) {
288804c5856SHarman Kalra 		plt_err("Invalid signature %" PRIu64 " detected", hdr->signature);
289804c5856SHarman Kalra 		goto fail;
290804c5856SHarman Kalra 	}
291804c5856SHarman Kalra 
292804c5856SHarman Kalra 	/* Update length read till point */
293804c5856SHarman Kalra 	len += tdata->length;
294804c5856SHarman Kalra 
295804c5856SHarman Kalra 	*buf_trav_len = len;
296804c5856SHarman Kalra 	return 0;
297804c5856SHarman Kalra fail:
298804c5856SHarman Kalra 	return errno;
299804c5856SHarman Kalra }
300804c5856SHarman Kalra 
301804c5856SHarman Kalra static cnxk_rep_msg_data_t *
message_data_extract(void * msg_buf,uint32_t * buf_trav_len)302804c5856SHarman Kalra message_data_extract(void *msg_buf, uint32_t *buf_trav_len)
303804c5856SHarman Kalra {
304804c5856SHarman Kalra 	cnxk_type_data_t *tdata = NULL;
305804c5856SHarman Kalra 	cnxk_rep_msg_data_t *msg = NULL;
306804c5856SHarman Kalra 	uint16_t len = *buf_trav_len;
307804c5856SHarman Kalra 	void *data;
308804c5856SHarman Kalra 
309804c5856SHarman Kalra 	tdata = (cnxk_type_data_t *)RTE_PTR_ADD(msg_buf, len);
310804c5856SHarman Kalra 	if (tdata->type != CNXK_TYPE_MSG) {
311804c5856SHarman Kalra 		plt_err("Invalid type %d, type MSG expected", tdata->type);
312804c5856SHarman Kalra 		goto fail;
313804c5856SHarman Kalra 	}
314804c5856SHarman Kalra 
315804c5856SHarman Kalra 	/* Get the message type */
316804c5856SHarman Kalra 	len += sizeof(cnxk_type_data_t);
317804c5856SHarman Kalra 	data = RTE_PTR_ADD(msg_buf, len);
318804c5856SHarman Kalra 	msg = (cnxk_rep_msg_data_t *)data;
319804c5856SHarman Kalra 
320804c5856SHarman Kalra 	/* Advance to actual message data */
321804c5856SHarman Kalra 	len += tdata->length;
322804c5856SHarman Kalra 	*buf_trav_len = len;
323804c5856SHarman Kalra 
324804c5856SHarman Kalra 	return msg;
325804c5856SHarman Kalra fail:
326804c5856SHarman Kalra 	return NULL;
327804c5856SHarman Kalra }
328804c5856SHarman Kalra 
329804c5856SHarman Kalra static void
process_ack_message(void * msg_buf,uint32_t * buf_trav_len,uint32_t msg_len,void * data)330804c5856SHarman Kalra process_ack_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data)
331804c5856SHarman Kalra {
332804c5856SHarman Kalra 	cnxk_rep_msg_ack_data_t *adata = (cnxk_rep_msg_ack_data_t *)data;
333804c5856SHarman Kalra 	uint16_t len = *buf_trav_len;
334804c5856SHarman Kalra 	void *buf;
335804c5856SHarman Kalra 
336804c5856SHarman Kalra 	/* Get the message type data viz ack data */
337804c5856SHarman Kalra 	buf = RTE_PTR_ADD(msg_buf, len);
338804c5856SHarman Kalra 	adata->u.data = rte_zmalloc("Ack data", msg_len, 0);
339804c5856SHarman Kalra 	adata->size = msg_len;
340804c5856SHarman Kalra 	if (adata->size == sizeof(uint64_t))
341804c5856SHarman Kalra 		rte_memcpy(&adata->u.data, buf, msg_len);
342804c5856SHarman Kalra 	else
343804c5856SHarman Kalra 		rte_memcpy(adata->u.data, buf, msg_len);
344804c5856SHarman Kalra 	plt_rep_dbg("Address %p val 0x%" PRIu64 " sval %" PRId64 " msg_len %d",
345804c5856SHarman Kalra 		    adata->u.data, adata->u.val, adata->u.sval, msg_len);
346804c5856SHarman Kalra 
347804c5856SHarman Kalra 	/* Advance length to nex message */
348804c5856SHarman Kalra 	len += msg_len;
349804c5856SHarman Kalra 	*buf_trav_len = len;
350804c5856SHarman Kalra }
351804c5856SHarman Kalra 
352804c5856SHarman Kalra static int
notify_rep_dev_ready(cnxk_rep_msg_ready_data_t * rdata,void * data,cnxk_rep_msg_ack_data1_t ** padata)353804c5856SHarman Kalra notify_rep_dev_ready(cnxk_rep_msg_ready_data_t *rdata, void *data,
354804c5856SHarman Kalra 		     cnxk_rep_msg_ack_data1_t **padata)
355804c5856SHarman Kalra {
356804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev;
357804c5856SHarman Kalra 	uint64_t rep_id_arr[RTE_MAX_ETHPORTS];
358804c5856SHarman Kalra 	cnxk_rep_msg_ack_data1_t *adata;
359804c5856SHarman Kalra 	uint16_t rep_id, sz, total_sz;
360804c5856SHarman Kalra 	int rc, i, j = 0;
361804c5856SHarman Kalra 
362804c5856SHarman Kalra 	PLT_SET_USED(data);
363804c5856SHarman Kalra 	eswitch_dev = cnxk_eswitch_pmd_priv();
364804c5856SHarman Kalra 	if (!eswitch_dev) {
365804c5856SHarman Kalra 		plt_err("Failed to get PF ethdev handle");
366804c5856SHarman Kalra 		rc = -EINVAL;
367804c5856SHarman Kalra 		goto fail;
368804c5856SHarman Kalra 	}
369804c5856SHarman Kalra 
370804c5856SHarman Kalra 	memset(rep_id_arr, 0, RTE_MAX_ETHPORTS * sizeof(uint64_t));
371804c5856SHarman Kalra 	/* For ready state */
372eeb4b1d1SHanumanth Pothula 	if (rdata->nb_ports > eswitch_dev->repr_cnt.nb_repr_probed) {
373804c5856SHarman Kalra 		rc = CNXK_REP_CTRL_MSG_NACK_INV_REP_CNT;
374804c5856SHarman Kalra 		goto fail;
375804c5856SHarman Kalra 	}
376804c5856SHarman Kalra 
377eeb4b1d1SHanumanth Pothula 	for (i = 0; i < rdata->nb_ports; i++) {
378804c5856SHarman Kalra 		rep_id = UINT16_MAX;
379804c5856SHarman Kalra 		rc = cnxk_rep_state_update(eswitch_dev, rdata->data[i], &rep_id);
380804c5856SHarman Kalra 		if (rc) {
381804c5856SHarman Kalra 			rc = CNXK_REP_CTRL_MSG_NACK_REP_STAT_UP_FAIL;
382804c5856SHarman Kalra 			goto fail;
383804c5856SHarman Kalra 		}
384804c5856SHarman Kalra 		if (rep_id != UINT16_MAX)
385804c5856SHarman Kalra 			rep_id_arr[j++] = rep_id;
386804c5856SHarman Kalra 	}
387804c5856SHarman Kalra 
388804c5856SHarman Kalra 	/* Send Rep Id array to companian app */
389804c5856SHarman Kalra 	sz = j * sizeof(uint64_t);
390804c5856SHarman Kalra 	total_sz = sizeof(cnxk_rep_msg_ack_data1_t) + sz;
391804c5856SHarman Kalra 	adata = plt_zmalloc(total_sz, 0);
392804c5856SHarman Kalra 	rte_memcpy(adata->data, rep_id_arr, sz);
393804c5856SHarman Kalra 	adata->size = sz;
394804c5856SHarman Kalra 	*padata = adata;
395804c5856SHarman Kalra 
396804c5856SHarman Kalra 	plt_rep_dbg("Installing NPC rules for Eswitch VF");
397804c5856SHarman Kalra 	/* Install RX VLAN rule for eswitch VF */
398804c5856SHarman Kalra 	if (!eswitch_dev->eswitch_vf_rules_setup) {
399804c5856SHarman Kalra 		rc = cnxk_eswitch_pfvf_flow_rules_install(eswitch_dev, true);
400804c5856SHarman Kalra 		if (rc) {
401804c5856SHarman Kalra 			plt_err("Failed to install rxtx rules, rc %d", rc);
402804c5856SHarman Kalra 			goto fail;
403804c5856SHarman Kalra 		}
404804c5856SHarman Kalra 
405804c5856SHarman Kalra 		/* Configure TPID for Eswitch PF LFs */
406804c5856SHarman Kalra 		rc = roc_eswitch_nix_vlan_tpid_set(&eswitch_dev->nix, ROC_NIX_VLAN_TYPE_OUTER,
407804c5856SHarman Kalra 						   CNXK_ESWITCH_VLAN_TPID, true);
408804c5856SHarman Kalra 		if (rc) {
409804c5856SHarman Kalra 			plt_err("Failed to configure tpid, rc %d", rc);
410804c5856SHarman Kalra 			goto fail;
411804c5856SHarman Kalra 		}
412804c5856SHarman Kalra 		eswitch_dev->eswitch_vf_rules_setup = true;
413804c5856SHarman Kalra 	}
414804c5856SHarman Kalra 
415804c5856SHarman Kalra 	return 0;
416804c5856SHarman Kalra fail:
417804c5856SHarman Kalra 	sz = sizeof(cnxk_rep_msg_ack_data1_t) + sizeof(uint64_t);
418804c5856SHarman Kalra 	adata = plt_zmalloc(sz, 0);
419804c5856SHarman Kalra 	adata->data[0] = rc;
420804c5856SHarman Kalra 	adata->size = sizeof(uint64_t);
421804c5856SHarman Kalra 	*padata = adata;
422804c5856SHarman Kalra 
423804c5856SHarman Kalra 	return rc;
424804c5856SHarman Kalra }
425804c5856SHarman Kalra 
426804c5856SHarman Kalra static int
process_ready_message(void * msg_buf,uint32_t * buf_trav_len,uint32_t msg_len,void * data,cnxk_rep_msg_ack_data1_t ** padata)427804c5856SHarman Kalra process_ready_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data,
428804c5856SHarman Kalra 		      cnxk_rep_msg_ack_data1_t **padata)
429804c5856SHarman Kalra {
430804c5856SHarman Kalra 	cnxk_rep_msg_ready_data_t *rdata = NULL;
431804c5856SHarman Kalra 	cnxk_rep_msg_ack_data1_t *adata;
432804c5856SHarman Kalra 	uint16_t len = *buf_trav_len;
433804c5856SHarman Kalra 	void *buf;
434804c5856SHarman Kalra 	int rc = 0, sz;
435804c5856SHarman Kalra 
436804c5856SHarman Kalra 	/* Get the message type data viz ready data */
437804c5856SHarman Kalra 	buf = RTE_PTR_ADD(msg_buf, len);
438804c5856SHarman Kalra 	rdata = (cnxk_rep_msg_ready_data_t *)buf;
439804c5856SHarman Kalra 
440804c5856SHarman Kalra 	plt_rep_dbg("Ready data received %d, nb_ports %d", rdata->val, rdata->nb_ports);
441804c5856SHarman Kalra 
442804c5856SHarman Kalra 	/* Wait required to ensure other side ready for receiving the ack */
443804c5856SHarman Kalra 	usleep(CTRL_MSG_READY_WAIT_US);
444804c5856SHarman Kalra 
445804c5856SHarman Kalra 	/* Update all representor about ready message */
446804c5856SHarman Kalra 	if (rdata->val) {
447804c5856SHarman Kalra 		rc = notify_rep_dev_ready(rdata, data, padata);
448804c5856SHarman Kalra 	} else {
449804c5856SHarman Kalra 		sz = sizeof(cnxk_rep_msg_ack_data1_t) + sizeof(uint64_t);
450804c5856SHarman Kalra 		adata = plt_zmalloc(sz, 0);
451804c5856SHarman Kalra 		adata->data[0] = CNXK_REP_CTRL_MSG_NACK_INV_RDY_DATA;
452804c5856SHarman Kalra 		adata->size = sizeof(uint64_t);
453804c5856SHarman Kalra 		*padata = adata;
454804c5856SHarman Kalra 	}
455804c5856SHarman Kalra 
456804c5856SHarman Kalra 	/* Advance length to nex message */
457804c5856SHarman Kalra 	len += msg_len;
458804c5856SHarman Kalra 	*buf_trav_len = len;
459804c5856SHarman Kalra 
460804c5856SHarman Kalra 	return rc;
461804c5856SHarman Kalra }
462804c5856SHarman Kalra 
463804c5856SHarman Kalra static int
notify_rep_dev_exit(cnxk_rep_msg_exit_data_t * edata,void * data)464804c5856SHarman Kalra notify_rep_dev_exit(cnxk_rep_msg_exit_data_t *edata, void *data)
465804c5856SHarman Kalra {
466804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev;
467804c5856SHarman Kalra 	struct cnxk_rep_dev *rep_dev = NULL;
468804c5856SHarman Kalra 	struct rte_eth_dev *rep_eth_dev;
469804c5856SHarman Kalra 	int i, rc = 0;
470804c5856SHarman Kalra 
471804c5856SHarman Kalra 	PLT_SET_USED(data);
472804c5856SHarman Kalra 	eswitch_dev = cnxk_eswitch_pmd_priv();
473804c5856SHarman Kalra 	if (!eswitch_dev) {
474804c5856SHarman Kalra 		plt_err("Failed to get PF ethdev handle");
475804c5856SHarman Kalra 		rc = -EINVAL;
476804c5856SHarman Kalra 		goto fail;
477804c5856SHarman Kalra 	}
478eeb4b1d1SHanumanth Pothula 	if (edata->nb_ports > eswitch_dev->repr_cnt.nb_repr_probed) {
479804c5856SHarman Kalra 		rc = CNXK_REP_CTRL_MSG_NACK_INV_REP_CNT;
480804c5856SHarman Kalra 		goto fail;
481804c5856SHarman Kalra 	}
482804c5856SHarman Kalra 
483804c5856SHarman Kalra 	for (i = 0; i < eswitch_dev->repr_cnt.nb_repr_probed; i++) {
484804c5856SHarman Kalra 		rep_eth_dev = eswitch_dev->rep_info[i].rep_eth_dev;
485804c5856SHarman Kalra 		if (!rep_eth_dev) {
486804c5856SHarman Kalra 			plt_err("Failed to get rep ethdev handle");
487804c5856SHarman Kalra 			rc = -EINVAL;
488804c5856SHarman Kalra 			goto fail;
489804c5856SHarman Kalra 		}
490804c5856SHarman Kalra 
491804c5856SHarman Kalra 		rep_dev = cnxk_rep_pmd_priv(rep_eth_dev);
492804c5856SHarman Kalra 		if (!rep_dev->native_repte)
493804c5856SHarman Kalra 			rep_dev->is_vf_active = false;
494804c5856SHarman Kalra 	}
495804c5856SHarman Kalra 	/* For Exit message */
496804c5856SHarman Kalra 	eswitch_dev->client_connected = false;
497804c5856SHarman Kalra 	return 0;
498804c5856SHarman Kalra fail:
499804c5856SHarman Kalra 	return rc;
500804c5856SHarman Kalra }
501804c5856SHarman Kalra 
502804c5856SHarman Kalra static void
process_exit_message(void * msg_buf,uint32_t * buf_trav_len,uint32_t msg_len,void * data)503804c5856SHarman Kalra process_exit_message(void *msg_buf, uint32_t *buf_trav_len, uint32_t msg_len, void *data)
504804c5856SHarman Kalra {
505804c5856SHarman Kalra 	cnxk_rep_msg_exit_data_t *edata = NULL;
506804c5856SHarman Kalra 	uint16_t len = *buf_trav_len;
507804c5856SHarman Kalra 	void *buf;
508804c5856SHarman Kalra 
509804c5856SHarman Kalra 	/* Get the message type data viz exit data */
510804c5856SHarman Kalra 	buf = RTE_PTR_ADD(msg_buf, len);
511804c5856SHarman Kalra 	edata = (cnxk_rep_msg_exit_data_t *)buf;
512804c5856SHarman Kalra 
513804c5856SHarman Kalra 	plt_rep_dbg("Exit data received %d", edata->val);
514804c5856SHarman Kalra 
515804c5856SHarman Kalra 	/* Update all representor about ready/exit message */
516804c5856SHarman Kalra 	if (edata->val)
517804c5856SHarman Kalra 		notify_rep_dev_exit(edata, data);
518804c5856SHarman Kalra 
519804c5856SHarman Kalra 	/* Advance length to nex message */
520804c5856SHarman Kalra 	len += msg_len;
521804c5856SHarman Kalra 	*buf_trav_len = len;
522804c5856SHarman Kalra }
523804c5856SHarman Kalra 
524804c5856SHarman Kalra static void
populate_ack_msg(void * buffer,uint32_t * length,cnxk_rep_msg_ack_data1_t * adata)525804c5856SHarman Kalra populate_ack_msg(void *buffer, uint32_t *length, cnxk_rep_msg_ack_data1_t *adata)
526804c5856SHarman Kalra {
527804c5856SHarman Kalra 	uint32_t sz = sizeof(cnxk_rep_msg_ack_data1_t) + adata->size;
528804c5856SHarman Kalra 	uint32_t len;
529804c5856SHarman Kalra 
530804c5856SHarman Kalra 	cnxk_rep_msg_populate_command(buffer, length, CNXK_REP_MSG_ACK, sz);
531804c5856SHarman Kalra 
532804c5856SHarman Kalra 	len = *length;
533804c5856SHarman Kalra 
534804c5856SHarman Kalra 	/* Populate ACK message data */
535804c5856SHarman Kalra 	rte_memcpy(RTE_PTR_ADD(buffer, len), adata, sz);
536804c5856SHarman Kalra 
537804c5856SHarman Kalra 	len += sz;
538804c5856SHarman Kalra 
539804c5856SHarman Kalra 	*length = len;
540804c5856SHarman Kalra }
541804c5856SHarman Kalra 
542804c5856SHarman Kalra static int
send_ack_message(void * data,cnxk_rep_msg_ack_data1_t * adata)543804c5856SHarman Kalra send_ack_message(void *data, cnxk_rep_msg_ack_data1_t *adata)
544804c5856SHarman Kalra {
545804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev = (struct cnxk_eswitch_dev *)data;
546804c5856SHarman Kalra 	uint32_t len = 0, size;
547804c5856SHarman Kalra 	void *buffer;
548804c5856SHarman Kalra 	int rc = 0;
549804c5856SHarman Kalra 
550804c5856SHarman Kalra 	/* Allocate memory for preparing a message */
551804c5856SHarman Kalra 	size = CTRL_MSG_BUFFER_SZ;
552804c5856SHarman Kalra 	buffer = rte_zmalloc("ACK msg", size, 0);
553804c5856SHarman Kalra 	if (!buffer) {
554804c5856SHarman Kalra 		plt_err("Failed to allocate mem");
555804c5856SHarman Kalra 		return -ENOMEM;
556804c5856SHarman Kalra 	}
557804c5856SHarman Kalra 
558804c5856SHarman Kalra 	/* Prepare the ACK message */
559804c5856SHarman Kalra 	cnxk_rep_msg_populate_header(buffer, &len);
560804c5856SHarman Kalra 	populate_ack_msg(buffer, &len, adata);
561804c5856SHarman Kalra 	cnxk_rep_msg_populate_msg_end(buffer, &len);
562804c5856SHarman Kalra 
563804c5856SHarman Kalra 	/* Length check to avoid buffer overflow */
564804c5856SHarman Kalra 	if (len > CTRL_MSG_BUFFER_SZ) {
565804c5856SHarman Kalra 		plt_err("Invalid length %d for max sized buffer %d", len, CTRL_MSG_BUFFER_SZ);
566804c5856SHarman Kalra 		rc = -EFAULT;
567804c5856SHarman Kalra 		goto done;
568804c5856SHarman Kalra 	}
569804c5856SHarman Kalra 
570804c5856SHarman Kalra 	/* Send it to the peer */
571804c5856SHarman Kalra 	rc = send_control_message(eswitch_dev, buffer, len);
572804c5856SHarman Kalra 	if (rc)
573804c5856SHarman Kalra 		plt_err("Failed send ack");
574804c5856SHarman Kalra 
575804c5856SHarman Kalra done:
576804c5856SHarman Kalra 	return rc;
577804c5856SHarman Kalra }
578804c5856SHarman Kalra 
579804c5856SHarman Kalra static int
process_message(void * msg_buf,uint32_t * buf_trav_len,void * data)580804c5856SHarman Kalra process_message(void *msg_buf, uint32_t *buf_trav_len, void *data)
581804c5856SHarman Kalra {
582804c5856SHarman Kalra 	cnxk_rep_msg_data_t *msg = NULL;
583804c5856SHarman Kalra 	cnxk_rep_msg_ack_data1_t *adata = NULL;
584804c5856SHarman Kalra 	bool send_ack;
585804c5856SHarman Kalra 	int rc = 0, sz;
586804c5856SHarman Kalra 
587804c5856SHarman Kalra 	/* Get the message data */
588804c5856SHarman Kalra 	msg = message_data_extract(msg_buf, buf_trav_len);
589804c5856SHarman Kalra 	if (!msg) {
590804c5856SHarman Kalra 		plt_err("Failed to get message data");
591804c5856SHarman Kalra 		rc = -EINVAL;
592804c5856SHarman Kalra 		goto fail;
593804c5856SHarman Kalra 	}
594804c5856SHarman Kalra 
595804c5856SHarman Kalra 	/* Different message type processing */
596804c5856SHarman Kalra 	while (msg->type != CNXK_REP_MSG_END) {
597804c5856SHarman Kalra 		send_ack = true;
598804c5856SHarman Kalra 		switch (msg->type) {
599804c5856SHarman Kalra 		case CNXK_REP_MSG_ACK:
600804c5856SHarman Kalra 			plt_rep_dbg("Received ack response");
601804c5856SHarman Kalra 			process_ack_message(msg_buf, buf_trav_len, msg->length, data);
602804c5856SHarman Kalra 			send_ack = false;
603804c5856SHarman Kalra 			break;
604804c5856SHarman Kalra 		case CNXK_REP_MSG_READY:
605804c5856SHarman Kalra 			plt_rep_dbg("Received ready message");
606804c5856SHarman Kalra 			process_ready_message(msg_buf, buf_trav_len, msg->length, data, &adata);
607804c5856SHarman Kalra 			adata->type = CNXK_REP_MSG_READY;
608804c5856SHarman Kalra 			break;
609804c5856SHarman Kalra 		case CNXK_REP_MSG_EXIT:
610804c5856SHarman Kalra 			plt_rep_dbg("Received exit message");
611804c5856SHarman Kalra 			process_exit_message(msg_buf, buf_trav_len, msg->length, data);
612804c5856SHarman Kalra 			sz = sizeof(cnxk_rep_msg_ack_data1_t) + sizeof(uint64_t);
613804c5856SHarman Kalra 			adata = plt_zmalloc(sz, 0);
614804c5856SHarman Kalra 			adata->type = CNXK_REP_MSG_EXIT;
615804c5856SHarman Kalra 			adata->data[0] = 0;
616804c5856SHarman Kalra 			adata->size = sizeof(uint64_t);
617804c5856SHarman Kalra 			break;
618804c5856SHarman Kalra 		default:
619804c5856SHarman Kalra 			send_ack = false;
620804c5856SHarman Kalra 			plt_err("Invalid message type: %d", msg->type);
621804c5856SHarman Kalra 			rc = -EINVAL;
622804c5856SHarman Kalra 		};
623804c5856SHarman Kalra 
624804c5856SHarman Kalra 		/* Send ACK */
625804c5856SHarman Kalra 		if (send_ack)
626804c5856SHarman Kalra 			send_ack_message(data, adata);
627804c5856SHarman Kalra 
628804c5856SHarman Kalra 		/* Advance to next message */
629804c5856SHarman Kalra 		msg = message_data_extract(msg_buf, buf_trav_len);
630804c5856SHarman Kalra 		if (!msg) {
631804c5856SHarman Kalra 			plt_err("Failed to get message data");
632804c5856SHarman Kalra 			rc = -EINVAL;
633804c5856SHarman Kalra 			goto fail;
634804c5856SHarman Kalra 		}
635804c5856SHarman Kalra 	}
636804c5856SHarman Kalra 
637804c5856SHarman Kalra 	return 0;
638804c5856SHarman Kalra fail:
639804c5856SHarman Kalra 	return rc;
640804c5856SHarman Kalra }
641804c5856SHarman Kalra 
642804c5856SHarman Kalra static int
process_control_message(void * msg_buf,void * data,size_t sz)643804c5856SHarman Kalra process_control_message(void *msg_buf, void *data, size_t sz)
644804c5856SHarman Kalra {
645804c5856SHarman Kalra 	uint32_t buf_trav_len = 0;
646804c5856SHarman Kalra 	int rc;
647804c5856SHarman Kalra 
648804c5856SHarman Kalra 	/* Validate the validity of the received message */
649804c5856SHarman Kalra 	parse_validate_header(msg_buf, &buf_trav_len);
650804c5856SHarman Kalra 
651804c5856SHarman Kalra 	/* Detect message and process */
652804c5856SHarman Kalra 	rc = process_message(msg_buf, &buf_trav_len, data);
653804c5856SHarman Kalra 	if (rc) {
654804c5856SHarman Kalra 		plt_err("Failed to process message");
655804c5856SHarman Kalra 		goto fail;
656804c5856SHarman Kalra 	}
657804c5856SHarman Kalra 
658804c5856SHarman Kalra 	/* Ensuring entire message has been processed */
659804c5856SHarman Kalra 	if (sz != buf_trav_len) {
660804c5856SHarman Kalra 		plt_err("Out of %" PRId64 " bytes %d bytes of msg_buf processed", sz, buf_trav_len);
661804c5856SHarman Kalra 		rc = -EFAULT;
662804c5856SHarman Kalra 		goto fail;
663804c5856SHarman Kalra 	}
664804c5856SHarman Kalra 
665804c5856SHarman Kalra 	return 0;
666804c5856SHarman Kalra fail:
667804c5856SHarman Kalra 	return rc;
668804c5856SHarman Kalra }
669804c5856SHarman Kalra 
670804c5856SHarman Kalra static int
receive_control_msg_resp(struct cnxk_eswitch_dev * eswitch_dev,void * data)671804c5856SHarman Kalra receive_control_msg_resp(struct cnxk_eswitch_dev *eswitch_dev, void *data)
672804c5856SHarman Kalra {
673804c5856SHarman Kalra 	uint32_t wait_us = CTRL_MSG_RCV_TIMEOUT_MS * 1000;
674804c5856SHarman Kalra 	uint32_t timeout = 0, sleep = 1;
675804c5856SHarman Kalra 	int sz = 0;
676804c5856SHarman Kalra 	int rc = -1;
677804c5856SHarman Kalra 	uint32_t len = BUFSIZ;
678804c5856SHarman Kalra 	void *msg_buf;
679804c5856SHarman Kalra 
680804c5856SHarman Kalra 	msg_buf = plt_zmalloc(len, 0);
681804c5856SHarman Kalra 
682804c5856SHarman Kalra 	do {
683804c5856SHarman Kalra 		sz = receive_control_message(eswitch_dev->sock_fd, msg_buf, len);
684804c5856SHarman Kalra 		if (sz != 0)
685804c5856SHarman Kalra 			break;
686804c5856SHarman Kalra 
687804c5856SHarman Kalra 		/* Timeout after CTRL_MSG_RCV_TIMEOUT_MS */
688804c5856SHarman Kalra 		if (timeout >= wait_us) {
689804c5856SHarman Kalra 			plt_err("Control message wait timedout");
690804c5856SHarman Kalra 			return -ETIMEDOUT;
691804c5856SHarman Kalra 		}
692804c5856SHarman Kalra 
693804c5856SHarman Kalra 		plt_delay_us(sleep);
694804c5856SHarman Kalra 		timeout += sleep;
695804c5856SHarman Kalra 	} while ((sz == 0) || (timeout < wait_us));
696804c5856SHarman Kalra 
697804c5856SHarman Kalra 	if (sz > 0) {
698804c5856SHarman Kalra 		plt_rep_dbg("Received %d sized response packet", sz);
699804c5856SHarman Kalra 		rc = process_control_message(msg_buf, data, sz);
700804c5856SHarman Kalra 		plt_free(msg_buf);
701804c5856SHarman Kalra 	}
702804c5856SHarman Kalra 
703804c5856SHarman Kalra 	return rc;
704804c5856SHarman Kalra }
705804c5856SHarman Kalra 
706804c5856SHarman Kalra int
cnxk_rep_msg_send_process(struct cnxk_rep_dev * rep_dev,void * buffer,uint32_t len,cnxk_rep_msg_ack_data_t * adata)707804c5856SHarman Kalra cnxk_rep_msg_send_process(struct cnxk_rep_dev *rep_dev, void *buffer, uint32_t len,
708804c5856SHarman Kalra 			  cnxk_rep_msg_ack_data_t *adata)
709804c5856SHarman Kalra {
710804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev;
711804c5856SHarman Kalra 	int rc = 0;
712804c5856SHarman Kalra 
713804c5856SHarman Kalra 	eswitch_dev = rep_dev->parent_dev;
714804c5856SHarman Kalra 	if (!eswitch_dev) {
715804c5856SHarman Kalra 		plt_err("Failed to get parent eswitch handle");
716804c5856SHarman Kalra 		rc = -1;
717804c5856SHarman Kalra 		goto fail;
718804c5856SHarman Kalra 	}
719804c5856SHarman Kalra 
720804c5856SHarman Kalra 	plt_spinlock_lock(&eswitch_dev->rep_lock);
721804c5856SHarman Kalra 	rc = send_control_message(eswitch_dev, buffer, len);
722804c5856SHarman Kalra 	if (rc) {
723804c5856SHarman Kalra 		plt_err("Failed to send the message, err %d", rc);
724804c5856SHarman Kalra 		goto free;
725804c5856SHarman Kalra 	}
726804c5856SHarman Kalra 
727804c5856SHarman Kalra 	/* Get response of the command sent */
728804c5856SHarman Kalra 	rc = receive_control_msg_resp(eswitch_dev, adata);
729804c5856SHarman Kalra 	if (rc) {
730804c5856SHarman Kalra 		plt_err("Failed to receive the response, err %d", rc);
731804c5856SHarman Kalra 		goto free;
732804c5856SHarman Kalra 	}
733804c5856SHarman Kalra 	plt_spinlock_unlock(&eswitch_dev->rep_lock);
734804c5856SHarman Kalra 
735804c5856SHarman Kalra 	return 0;
736804c5856SHarman Kalra free:
737804c5856SHarman Kalra 	plt_spinlock_unlock(&eswitch_dev->rep_lock);
738804c5856SHarman Kalra fail:
739804c5856SHarman Kalra 	return rc;
740804c5856SHarman Kalra }
741804c5856SHarman Kalra 
742804c5856SHarman Kalra static void
poll_for_control_msg(void * data)743804c5856SHarman Kalra poll_for_control_msg(void *data)
744804c5856SHarman Kalra {
745804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev = (struct cnxk_eswitch_dev *)data;
746804c5856SHarman Kalra 	uint32_t len = BUFSIZ;
747804c5856SHarman Kalra 	int sz = 0;
748804c5856SHarman Kalra 	void *msg_buf;
749804c5856SHarman Kalra 
750804c5856SHarman Kalra 	while (eswitch_dev->client_connected) {
751804c5856SHarman Kalra 		msg_buf = plt_zmalloc(len, 0);
752804c5856SHarman Kalra 		do {
753804c5856SHarman Kalra 			plt_spinlock_lock(&eswitch_dev->rep_lock);
754804c5856SHarman Kalra 			sz = receive_control_message(eswitch_dev->sock_fd, msg_buf, len);
755804c5856SHarman Kalra 			plt_spinlock_unlock(&eswitch_dev->rep_lock);
756804c5856SHarman Kalra 			if (sz != 0)
757804c5856SHarman Kalra 				break;
758804c5856SHarman Kalra 			plt_delay_us(2000);
759804c5856SHarman Kalra 		} while (sz == 0);
760804c5856SHarman Kalra 
761804c5856SHarman Kalra 		if (sz > 0) {
762804c5856SHarman Kalra 			plt_rep_dbg("Received new %d bytes control message", sz);
763804c5856SHarman Kalra 			plt_spinlock_lock(&eswitch_dev->rep_lock);
764804c5856SHarman Kalra 			process_control_message(msg_buf, data, sz);
765804c5856SHarman Kalra 			plt_spinlock_unlock(&eswitch_dev->rep_lock);
766804c5856SHarman Kalra 			plt_free(msg_buf);
767804c5856SHarman Kalra 		}
768804c5856SHarman Kalra 	}
769804c5856SHarman Kalra 	plt_rep_dbg("Exiting poll for control message loop");
770804c5856SHarman Kalra }
771804c5856SHarman Kalra 
772804c5856SHarman Kalra static uint32_t
rep_ctrl_msg_thread_main(void * arg)773804c5856SHarman Kalra rep_ctrl_msg_thread_main(void *arg)
774804c5856SHarman Kalra {
775804c5856SHarman Kalra 	struct cnxk_eswitch_dev *eswitch_dev = (struct cnxk_eswitch_dev *)arg;
776804c5856SHarman Kalra 	struct sockaddr_un client;
777804c5856SHarman Kalra 	int addr_len;
778804c5856SHarman Kalra 	int ssock_fd;
779804c5856SHarman Kalra 	int sock_fd;
780804c5856SHarman Kalra 
781804c5856SHarman Kalra 	ssock_fd = open_socket_ctrl_channel();
782804c5856SHarman Kalra 	if (ssock_fd < 0) {
783804c5856SHarman Kalra 		plt_err("Failed to open socket for ctrl channel, err %d", ssock_fd);
784804c5856SHarman Kalra 		return UINT32_MAX;
785804c5856SHarman Kalra 	}
786804c5856SHarman Kalra 
787804c5856SHarman Kalra 	addr_len = sizeof(client);
788804c5856SHarman Kalra 	while (eswitch_dev->start_ctrl_msg_thrd) {
789804c5856SHarman Kalra 		/* Accept client connection until the thread is running */
790804c5856SHarman Kalra 		sock_fd = accept(ssock_fd, (struct sockaddr *)&client, (socklen_t *)&addr_len);
791804c5856SHarman Kalra 		if (sock_fd < 0) {
792804c5856SHarman Kalra 			plt_err("Failed to accept connection request on socket fd %d", ssock_fd);
793804c5856SHarman Kalra 			break;
794804c5856SHarman Kalra 		}
795804c5856SHarman Kalra 
796804c5856SHarman Kalra 		plt_rep_dbg("Client %s: Connection request accepted.", client.sun_path);
797804c5856SHarman Kalra 		eswitch_dev->sock_fd = sock_fd;
798804c5856SHarman Kalra 		if (eswitch_dev->start_ctrl_msg_thrd) {
799804c5856SHarman Kalra 			eswitch_dev->client_connected = true;
800804c5856SHarman Kalra 			poll_for_control_msg(eswitch_dev);
801804c5856SHarman Kalra 		}
802804c5856SHarman Kalra 		eswitch_dev->sock_fd = -1;
803804c5856SHarman Kalra 		close(sock_fd);
804804c5856SHarman Kalra 	}
805804c5856SHarman Kalra 
806804c5856SHarman Kalra 	/* Closing the opened socket */
807804c5856SHarman Kalra 	close_socket(ssock_fd);
808804c5856SHarman Kalra 	plt_rep_dbg("Exiting representor ctrl thread");
809804c5856SHarman Kalra 
810804c5856SHarman Kalra 	return 0;
811804c5856SHarman Kalra }
812804c5856SHarman Kalra 
813804c5856SHarman Kalra int
cnxk_rep_msg_control_thread_launch(struct cnxk_eswitch_dev * eswitch_dev)814804c5856SHarman Kalra cnxk_rep_msg_control_thread_launch(struct cnxk_eswitch_dev *eswitch_dev)
815804c5856SHarman Kalra {
816804c5856SHarman Kalra 	char name[CTRL_MSG_THRD_NAME_LEN];
817804c5856SHarman Kalra 	int rc = 0;
818804c5856SHarman Kalra 
819804c5856SHarman Kalra 	rte_strscpy(name, "rep_ctrl_msg_hndlr", CTRL_MSG_THRD_NAME_LEN);
820804c5856SHarman Kalra 	eswitch_dev->start_ctrl_msg_thrd = true;
821804c5856SHarman Kalra 	rc = rte_thread_create_internal_control(&eswitch_dev->rep_ctrl_msg_thread, name,
822804c5856SHarman Kalra 						rep_ctrl_msg_thread_main, eswitch_dev);
823804c5856SHarman Kalra 	if (rc)
824804c5856SHarman Kalra 		plt_err("Failed to create rep control message handling");
825804c5856SHarman Kalra 
826804c5856SHarman Kalra 	return rc;
827804c5856SHarman Kalra }
828