xref: /dpdk/drivers/net/octeon_ep/otx_ep_mbox.c (revision 304ba46be396d2ec5ddf1d6b02793015785cd823)
1c836a7baSSathesh Edara /* SPDX-License-Identifier: BSD-3-Clause
2c836a7baSSathesh Edara  * Copyright(C) 2021 Marvell.
3c836a7baSSathesh Edara  */
4c836a7baSSathesh Edara 
5c836a7baSSathesh Edara #include <ethdev_pci.h>
6c836a7baSSathesh Edara #include <rte_ether.h>
7c836a7baSSathesh Edara #include <rte_kvargs.h>
8c836a7baSSathesh Edara 
9c836a7baSSathesh Edara #include "otx_ep_common.h"
10c836a7baSSathesh Edara #include "otx_ep_vf.h"
11c836a7baSSathesh Edara #include "otx2_ep_vf.h"
12c836a7baSSathesh Edara #include "cnxk_ep_vf.h"
13c836a7baSSathesh Edara #include "otx_ep_mbox.h"
14c836a7baSSathesh Edara 
15cab13b70SSathesh Edara /*
16cab13b70SSathesh Edara  * When a new command is implemented, the below table should be updated
17cab13b70SSathesh Edara  * with new command and it's version info.
18cab13b70SSathesh Edara  */
19cab13b70SSathesh Edara static uint32_t otx_ep_cmd_versions[OTX_EP_MBOX_CMD_MAX] = {
20826da0f5SVamsi Attunuru 	[0 ... OTX_EP_MBOX_CMD_DEV_REMOVE] = OTX_EP_MBOX_VERSION_V1,
21826da0f5SVamsi Attunuru 	[OTX_EP_MBOX_CMD_GET_FW_INFO ... OTX_EP_MBOX_NOTIF_LINK_STATUS] = OTX_EP_MBOX_VERSION_V2,
22826da0f5SVamsi Attunuru 	[OTX_EP_MBOX_NOTIF_PF_FLR] = OTX_EP_MBOX_VERSION_V3
23826da0f5SVamsi Attunuru 
24cab13b70SSathesh Edara };
25cab13b70SSathesh Edara 
26c836a7baSSathesh Edara static int
27c836a7baSSathesh Edara __otx_ep_send_mbox_cmd(struct otx_ep_device *otx_ep,
28c836a7baSSathesh Edara 		       union otx_ep_mbox_word cmd,
29c836a7baSSathesh Edara 		       union otx_ep_mbox_word *rsp)
30c836a7baSSathesh Edara {
31c836a7baSSathesh Edara 	volatile uint64_t reg_val = 0ull;
32c836a7baSSathesh Edara 	int count = 0;
33c836a7baSSathesh Edara 
34*304ba46bSVamsi Attunuru 	reg_val = otx2_read64(otx_ep->hw_addr + CNXK_EP_R_MBOX_VF_PF_DATA(0));
35*304ba46bSVamsi Attunuru 	if (reg_val == UINT64_MAX)
36*304ba46bSVamsi Attunuru 		return -ENODEV;
37*304ba46bSVamsi Attunuru 
38c836a7baSSathesh Edara 	cmd.s.type = OTX_EP_MBOX_TYPE_CMD;
39c836a7baSSathesh Edara 	otx2_write64(cmd.u64, otx_ep->hw_addr + CNXK_EP_R_MBOX_VF_PF_DATA(0));
40c836a7baSSathesh Edara 
41c836a7baSSathesh Edara 	/* No response for notification messages */
42c836a7baSSathesh Edara 	if (!rsp)
43c836a7baSSathesh Edara 		return 0;
44c836a7baSSathesh Edara 
45c836a7baSSathesh Edara 	for (count = 0; count < OTX_EP_MBOX_TIMEOUT_MS; count++) {
46c836a7baSSathesh Edara 		rte_delay_ms(1);
47c836a7baSSathesh Edara 		reg_val = otx2_read64(otx_ep->hw_addr + CNXK_EP_R_MBOX_VF_PF_DATA(0));
48*304ba46bSVamsi Attunuru 		if (reg_val == UINT64_MAX)
49*304ba46bSVamsi Attunuru 			return -ENODEV;
50c836a7baSSathesh Edara 		if (reg_val != cmd.u64) {
51c836a7baSSathesh Edara 			rsp->u64 = reg_val;
52c836a7baSSathesh Edara 			break;
53c836a7baSSathesh Edara 		}
54c836a7baSSathesh Edara 	}
55c836a7baSSathesh Edara 	if (count == OTX_EP_MBOX_TIMEOUT_MS) {
56f665790aSDavid Marchand 		otx_ep_err("mbox send Timeout count:%d", count);
57c836a7baSSathesh Edara 		return OTX_EP_MBOX_TIMEOUT_MS;
58c836a7baSSathesh Edara 	}
59c836a7baSSathesh Edara 	if (rsp->s.type != OTX_EP_MBOX_TYPE_RSP_ACK) {
60f665790aSDavid Marchand 		otx_ep_err("mbox received  NACK from PF");
61c836a7baSSathesh Edara 		return OTX_EP_MBOX_CMD_STATUS_NACK;
62c836a7baSSathesh Edara 	}
63c836a7baSSathesh Edara 
64c836a7baSSathesh Edara 	rsp->u64 = reg_val;
65c836a7baSSathesh Edara 	return 0;
66c836a7baSSathesh Edara }
67c836a7baSSathesh Edara 
68c836a7baSSathesh Edara static int
69c836a7baSSathesh Edara otx_ep_send_mbox_cmd(struct otx_ep_device *otx_ep,
70c836a7baSSathesh Edara 		     union otx_ep_mbox_word cmd,
71c836a7baSSathesh Edara 		     union otx_ep_mbox_word *rsp)
72c836a7baSSathesh Edara {
73c836a7baSSathesh Edara 	int ret;
74c836a7baSSathesh Edara 
75c836a7baSSathesh Edara 	rte_spinlock_lock(&otx_ep->mbox_lock);
76cab13b70SSathesh Edara 	if (otx_ep_cmd_versions[cmd.s.opcode] > otx_ep->mbox_neg_ver) {
77f665790aSDavid Marchand 		otx_ep_dbg("CMD:%d not supported in Version:%d", cmd.s.opcode,
78cab13b70SSathesh Edara 			    otx_ep->mbox_neg_ver);
79cab13b70SSathesh Edara 		rte_spinlock_unlock(&otx_ep->mbox_lock);
80cab13b70SSathesh Edara 		return -EOPNOTSUPP;
81cab13b70SSathesh Edara 	}
82c836a7baSSathesh Edara 	ret = __otx_ep_send_mbox_cmd(otx_ep, cmd, rsp);
83c836a7baSSathesh Edara 	rte_spinlock_unlock(&otx_ep->mbox_lock);
84c836a7baSSathesh Edara 	return ret;
85c836a7baSSathesh Edara }
86c836a7baSSathesh Edara 
87c836a7baSSathesh Edara static int
88c836a7baSSathesh Edara otx_ep_mbox_bulk_read(struct otx_ep_device *otx_ep,
89c836a7baSSathesh Edara 		      enum otx_ep_mbox_opcode opcode,
90c836a7baSSathesh Edara 		      uint8_t *data, int32_t *size)
91c836a7baSSathesh Edara {
92c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
93c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
94c836a7baSSathesh Edara 	int read_cnt, i = 0, ret;
95c836a7baSSathesh Edara 	int data_len = 0, tmp_len = 0;
96c836a7baSSathesh Edara 
97c836a7baSSathesh Edara 	rte_spinlock_lock(&otx_ep->mbox_lock);
98c836a7baSSathesh Edara 	cmd.u64 = 0;
99c836a7baSSathesh Edara 	cmd.s_data.opcode = opcode;
100c836a7baSSathesh Edara 	cmd.s_data.frag = 0;
101c836a7baSSathesh Edara 	/* Send cmd to read data from PF */
102c836a7baSSathesh Edara 	ret = __otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
103c836a7baSSathesh Edara 	if (ret) {
104f665790aSDavid Marchand 		otx_ep_err("mbox bulk read data request failed");
105c836a7baSSathesh Edara 		rte_spinlock_unlock(&otx_ep->mbox_lock);
106c836a7baSSathesh Edara 		return ret;
107c836a7baSSathesh Edara 	}
108c836a7baSSathesh Edara 	/*  PF sends the data length of requested CMD
109c836a7baSSathesh Edara 	 *  in  ACK
110c836a7baSSathesh Edara 	 */
111c836a7baSSathesh Edara 	memcpy(&data_len, rsp.s_data.data, sizeof(data_len));
112c836a7baSSathesh Edara 	tmp_len = data_len;
113c836a7baSSathesh Edara 	cmd.u64 = 0;
114c836a7baSSathesh Edara 	rsp.u64 = 0;
115c836a7baSSathesh Edara 	cmd.s_data.opcode = opcode;
116c836a7baSSathesh Edara 	cmd.s_data.frag = 1;
117c836a7baSSathesh Edara 	while (data_len) {
118c836a7baSSathesh Edara 		ret = __otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
119c836a7baSSathesh Edara 		if (ret) {
120f665790aSDavid Marchand 			otx_ep_err("mbox bulk read data request failed");
121c836a7baSSathesh Edara 			otx_ep->mbox_data_index = 0;
122c836a7baSSathesh Edara 			memset(otx_ep->mbox_data_buf, 0, OTX_EP_MBOX_MAX_DATA_BUF_SIZE);
123c836a7baSSathesh Edara 			rte_spinlock_unlock(&otx_ep->mbox_lock);
124c836a7baSSathesh Edara 			return ret;
125c836a7baSSathesh Edara 		}
126c836a7baSSathesh Edara 		if (data_len > OTX_EP_MBOX_MAX_DATA_SIZE) {
127c836a7baSSathesh Edara 			data_len -= OTX_EP_MBOX_MAX_DATA_SIZE;
128c836a7baSSathesh Edara 			read_cnt = OTX_EP_MBOX_MAX_DATA_SIZE;
129c836a7baSSathesh Edara 		} else {
130c836a7baSSathesh Edara 			read_cnt = data_len;
131c836a7baSSathesh Edara 			data_len = 0;
132c836a7baSSathesh Edara 		}
133c836a7baSSathesh Edara 		for (i = 0; i < read_cnt; i++) {
134c836a7baSSathesh Edara 			otx_ep->mbox_data_buf[otx_ep->mbox_data_index] =
135c836a7baSSathesh Edara 				rsp.s_data.data[i];
136c836a7baSSathesh Edara 			otx_ep->mbox_data_index++;
137c836a7baSSathesh Edara 		}
138c836a7baSSathesh Edara 		cmd.u64 = 0;
139c836a7baSSathesh Edara 		rsp.u64 = 0;
140c836a7baSSathesh Edara 		cmd.s_data.opcode = opcode;
141c836a7baSSathesh Edara 		cmd.s_data.frag = 1;
142c836a7baSSathesh Edara 	}
143c836a7baSSathesh Edara 	memcpy(data, otx_ep->mbox_data_buf, tmp_len);
144c836a7baSSathesh Edara 	*size = tmp_len;
145c836a7baSSathesh Edara 	otx_ep->mbox_data_index = 0;
146c836a7baSSathesh Edara 	memset(otx_ep->mbox_data_buf, 0, OTX_EP_MBOX_MAX_DATA_BUF_SIZE);
147c836a7baSSathesh Edara 	rte_spinlock_unlock(&otx_ep->mbox_lock);
148c836a7baSSathesh Edara 	return 0;
149c836a7baSSathesh Edara }
150c836a7baSSathesh Edara 
151c836a7baSSathesh Edara int
152c836a7baSSathesh Edara otx_ep_mbox_set_mtu(struct rte_eth_dev *eth_dev, uint16_t mtu)
153c836a7baSSathesh Edara {
154c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
155c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
156c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
157c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
158c836a7baSSathesh Edara 	int ret = 0;
159c836a7baSSathesh Edara 
160c836a7baSSathesh Edara 	cmd.u64 = 0;
161c836a7baSSathesh Edara 	cmd.s_set_mtu.opcode = OTX_EP_MBOX_CMD_SET_MTU;
162c836a7baSSathesh Edara 	cmd.s_set_mtu.mtu = mtu;
163c836a7baSSathesh Edara 
164c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
165c836a7baSSathesh Edara 	if (ret) {
166f665790aSDavid Marchand 		otx_ep_err("set MTU failed");
167c836a7baSSathesh Edara 		return -EINVAL;
168c836a7baSSathesh Edara 	}
169f665790aSDavid Marchand 	otx_ep_dbg("mtu set  success mtu %u", mtu);
170c836a7baSSathesh Edara 
171c836a7baSSathesh Edara 	return 0;
172c836a7baSSathesh Edara }
173c836a7baSSathesh Edara 
174c836a7baSSathesh Edara int
175c836a7baSSathesh Edara otx_ep_mbox_set_mac_addr(struct rte_eth_dev *eth_dev,
176c836a7baSSathesh Edara 			 struct rte_ether_addr *mac_addr)
177c836a7baSSathesh Edara {
178c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
179c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
180c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
181c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
182c836a7baSSathesh Edara 	int i, ret;
183c836a7baSSathesh Edara 
184c836a7baSSathesh Edara 	cmd.u64 = 0;
185c836a7baSSathesh Edara 	cmd.s_set_mac.opcode = OTX_EP_MBOX_CMD_SET_MAC_ADDR;
186c836a7baSSathesh Edara 	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
187c836a7baSSathesh Edara 		cmd.s_set_mac.mac_addr[i] = mac_addr->addr_bytes[i];
188c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
189c836a7baSSathesh Edara 	if (ret) {
190f665790aSDavid Marchand 		otx_ep_err("set MAC address failed");
191c836a7baSSathesh Edara 		return -EINVAL;
192c836a7baSSathesh Edara 	}
193f665790aSDavid Marchand 	otx_ep_dbg("%s VF MAC " RTE_ETHER_ADDR_PRT_FMT,
194c836a7baSSathesh Edara 		    __func__, RTE_ETHER_ADDR_BYTES(mac_addr));
195c836a7baSSathesh Edara 	rte_ether_addr_copy(mac_addr, eth_dev->data->mac_addrs);
196c836a7baSSathesh Edara 	return 0;
197c836a7baSSathesh Edara }
198c836a7baSSathesh Edara 
199c836a7baSSathesh Edara int
200c836a7baSSathesh Edara otx_ep_mbox_get_mac_addr(struct rte_eth_dev *eth_dev,
201c836a7baSSathesh Edara 			 struct rte_ether_addr *mac_addr)
202c836a7baSSathesh Edara {
203c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
204c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
205c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
206c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
207c836a7baSSathesh Edara 	int i, ret;
208c836a7baSSathesh Edara 
209c836a7baSSathesh Edara 	cmd.u64 = 0;
210c836a7baSSathesh Edara 	cmd.s_set_mac.opcode = OTX_EP_MBOX_CMD_GET_MAC_ADDR;
211c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
212c836a7baSSathesh Edara 	if (ret) {
213f665790aSDavid Marchand 		otx_ep_err("get MAC address failed");
214c836a7baSSathesh Edara 		return -EINVAL;
215c836a7baSSathesh Edara 	}
216c836a7baSSathesh Edara 	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
217c836a7baSSathesh Edara 		mac_addr->addr_bytes[i] = rsp.s_set_mac.mac_addr[i];
218f665790aSDavid Marchand 	otx_ep_dbg("%s VF MAC " RTE_ETHER_ADDR_PRT_FMT,
219c836a7baSSathesh Edara 		    __func__, RTE_ETHER_ADDR_BYTES(mac_addr));
220c836a7baSSathesh Edara 	return 0;
221c836a7baSSathesh Edara }
222c836a7baSSathesh Edara 
223c836a7baSSathesh Edara int otx_ep_mbox_get_link_status(struct rte_eth_dev *eth_dev,
224c836a7baSSathesh Edara 				uint8_t *oper_up)
225c836a7baSSathesh Edara {
226c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
227c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
228c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
229c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
230c836a7baSSathesh Edara 	int ret;
231c836a7baSSathesh Edara 
232c836a7baSSathesh Edara 	cmd.u64 = 0;
233c836a7baSSathesh Edara 	cmd.s_link_status.opcode = OTX_EP_MBOX_CMD_GET_LINK_STATUS;
234c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
235c836a7baSSathesh Edara 	if (ret) {
236f665790aSDavid Marchand 		otx_ep_err("Get link status failed");
237c836a7baSSathesh Edara 		return -EINVAL;
238c836a7baSSathesh Edara 	}
239c836a7baSSathesh Edara 	*oper_up = rsp.s_link_status.status;
240c836a7baSSathesh Edara 	return 0;
241c836a7baSSathesh Edara }
242c836a7baSSathesh Edara 
243c836a7baSSathesh Edara int otx_ep_mbox_get_link_info(struct rte_eth_dev *eth_dev,
244c836a7baSSathesh Edara 			      struct rte_eth_link *link)
245c836a7baSSathesh Edara {
246c836a7baSSathesh Edara 	int32_t ret, size;
247c836a7baSSathesh Edara 	struct otx_ep_iface_link_info link_info;
248c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
249c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
250c836a7baSSathesh Edara 	memset(&link_info, 0, sizeof(struct otx_ep_iface_link_info));
251c836a7baSSathesh Edara 	ret = otx_ep_mbox_bulk_read(otx_ep, OTX_EP_MBOX_CMD_GET_LINK_INFO,
252c836a7baSSathesh Edara 				      (uint8_t *)&link_info, (int32_t *)&size);
253c836a7baSSathesh Edara 	if (ret) {
254f665790aSDavid Marchand 		otx_ep_err("Get link info failed");
255c836a7baSSathesh Edara 		return ret;
256c836a7baSSathesh Edara 	}
257c836a7baSSathesh Edara 	link->link_status = RTE_ETH_LINK_UP;
258c836a7baSSathesh Edara 	link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
259c836a7baSSathesh Edara 	link->link_autoneg = (link_info.autoneg ==
260c836a7baSSathesh Edara 			      OTX_EP_LINK_AUTONEG) ? RTE_ETH_LINK_AUTONEG : RTE_ETH_LINK_FIXED;
261c836a7baSSathesh Edara 
262c836a7baSSathesh Edara 	link->link_autoneg = link_info.autoneg;
263c836a7baSSathesh Edara 	link->link_speed = link_info.speed;
264c836a7baSSathesh Edara 	return 0;
265c836a7baSSathesh Edara }
266c836a7baSSathesh Edara 
267c836a7baSSathesh Edara void
268c836a7baSSathesh Edara otx_ep_mbox_enable_interrupt(struct otx_ep_device *otx_ep)
269c836a7baSSathesh Edara {
270c836a7baSSathesh Edara 	rte_write64(0x2, (uint8_t *)otx_ep->hw_addr +
271c836a7baSSathesh Edara 		   CNXK_EP_R_MBOX_PF_VF_INT(0));
272c836a7baSSathesh Edara }
273c836a7baSSathesh Edara 
274c836a7baSSathesh Edara void
275c836a7baSSathesh Edara otx_ep_mbox_disable_interrupt(struct otx_ep_device *otx_ep)
276c836a7baSSathesh Edara {
277c836a7baSSathesh Edara 	rte_write64(0x00, (uint8_t *)otx_ep->hw_addr +
278c836a7baSSathesh Edara 		   CNXK_EP_R_MBOX_PF_VF_INT(0));
279c836a7baSSathesh Edara }
280c836a7baSSathesh Edara 
281c836a7baSSathesh Edara int
282c836a7baSSathesh Edara otx_ep_mbox_get_max_pkt_len(struct rte_eth_dev *eth_dev)
283c836a7baSSathesh Edara {
284c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
285c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
286c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
287c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
288c836a7baSSathesh Edara 	int ret;
289c836a7baSSathesh Edara 
290c836a7baSSathesh Edara 	rsp.u64 = 0;
291c836a7baSSathesh Edara 	cmd.u64 = 0;
292c836a7baSSathesh Edara 	cmd.s_get_mtu.opcode = OTX_EP_MBOX_CMD_GET_MTU;
293c836a7baSSathesh Edara 
294c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
295c836a7baSSathesh Edara 	if (ret)
296c836a7baSSathesh Edara 		return ret;
297c836a7baSSathesh Edara 	return rsp.s_get_mtu.mtu;
298c836a7baSSathesh Edara }
299c836a7baSSathesh Edara 
300826da0f5SVamsi Attunuru static void
301826da0f5SVamsi Attunuru otx_ep_mbox_version_check(struct otx_ep_device *otx_ep)
302c836a7baSSathesh Edara {
303c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
304c836a7baSSathesh Edara 	union otx_ep_mbox_word rsp;
305c836a7baSSathesh Edara 	int ret;
306c836a7baSSathesh Edara 
307c836a7baSSathesh Edara 	cmd.u64 = 0;
308c836a7baSSathesh Edara 	cmd.s_version.opcode = OTX_EP_MBOX_CMD_VERSION;
309cab13b70SSathesh Edara 	cmd.s_version.version = OTX_EP_MBOX_VERSION_CURRENT;
310c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, &rsp);
311cab13b70SSathesh Edara 
312cab13b70SSathesh Edara 	/*
313cab13b70SSathesh Edara 	 * VF receives NACK or version info as zero
314cab13b70SSathesh Edara 	 * only if PF driver running old version of Mailbox
315cab13b70SSathesh Edara 	 * In this case VF mailbox version fallbacks to base
316cab13b70SSathesh Edara 	 * mailbox vesrion OTX_EP_MBOX_VERSION_V1.
317cab13b70SSathesh Edara 	 * Default VF mbox_neg_ver is set to OTX_EP_MBOX_VERSION_V1
318cab13b70SSathesh Edara 	 * during initialization of PMD driver.
319cab13b70SSathesh Edara 	 */
320cab13b70SSathesh Edara 	if (ret == OTX_EP_MBOX_CMD_STATUS_NACK || rsp.s_version.version == 0) {
321f665790aSDavid Marchand 		otx_ep_dbg("VF Mbox version fallback to base version from:%u",
322c836a7baSSathesh Edara 			(uint32_t)cmd.s_version.version);
323826da0f5SVamsi Attunuru 		return;
324c836a7baSSathesh Edara 	}
325cab13b70SSathesh Edara 	otx_ep->mbox_neg_ver = (uint32_t)rsp.s_version.version;
326f665790aSDavid Marchand 	otx_ep_dbg("VF Mbox version:%u Negotiated VF version with PF:%u",
327cab13b70SSathesh Edara 		    (uint32_t)cmd.s_version.version,
328cab13b70SSathesh Edara 		    (uint32_t)rsp.s_version.version);
329826da0f5SVamsi Attunuru }
330826da0f5SVamsi Attunuru 
331826da0f5SVamsi Attunuru static void
332826da0f5SVamsi Attunuru otx_ep_mbox_intr_handler(void *param)
333826da0f5SVamsi Attunuru {
334826da0f5SVamsi Attunuru 	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
335826da0f5SVamsi Attunuru 	struct otx_ep_device *otx_ep = (struct otx_ep_device *)eth_dev->data->dev_private;
336826da0f5SVamsi Attunuru 	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(eth_dev);
337826da0f5SVamsi Attunuru 	union otx_ep_mbox_word mbox_cmd;
338826da0f5SVamsi Attunuru 
339826da0f5SVamsi Attunuru 	if (otx2_read64(otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_INT(0)) & CNXK_EP_MBOX_INTR) {
340826da0f5SVamsi Attunuru 		mbox_cmd.u64 = otx2_read64(otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_DATA(0));
341826da0f5SVamsi Attunuru 		otx2_write64(CNXK_EP_MBOX_ENAB | CNXK_EP_MBOX_INTR,
342826da0f5SVamsi Attunuru 			     otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_INT(0));
343826da0f5SVamsi Attunuru 		if (mbox_cmd.s.opcode == OTX_EP_MBOX_NOTIF_PF_FLR) {
344826da0f5SVamsi Attunuru 			rte_spinlock_lock(&otx_ep->mbox_lock);
345826da0f5SVamsi Attunuru 			mbox_cmd.s.type = OTX_EP_MBOX_TYPE_RSP_ACK;
346826da0f5SVamsi Attunuru 			otx2_write64(mbox_cmd.u64, otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_DATA(0));
347826da0f5SVamsi Attunuru 			rte_spinlock_unlock(&otx_ep->mbox_lock);
348826da0f5SVamsi Attunuru 			rte_dev_event_callback_process(pdev->name, RTE_DEV_EVENT_REMOVE);
349826da0f5SVamsi Attunuru 		} else {
350826da0f5SVamsi Attunuru 			otx_ep_err("Invalid mbox opcode");
351826da0f5SVamsi Attunuru 		}
352826da0f5SVamsi Attunuru 	}
353826da0f5SVamsi Attunuru }
354826da0f5SVamsi Attunuru 
355826da0f5SVamsi Attunuru int
356826da0f5SVamsi Attunuru otx_ep_mbox_init(struct rte_eth_dev *eth_dev)
357826da0f5SVamsi Attunuru {
358826da0f5SVamsi Attunuru 	struct otx_ep_device *otx_ep = (struct otx_ep_device *)eth_dev->data->dev_private;
359826da0f5SVamsi Attunuru 	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(eth_dev);
360*304ba46bSVamsi Attunuru 	uint64_t reg_val;
361826da0f5SVamsi Attunuru 
362826da0f5SVamsi Attunuru 	otx_ep_mbox_version_check(otx_ep);
363826da0f5SVamsi Attunuru 
364826da0f5SVamsi Attunuru 	rte_intr_callback_register(pdev->intr_handle, otx_ep_mbox_intr_handler, (void *)eth_dev);
365826da0f5SVamsi Attunuru 
366826da0f5SVamsi Attunuru 	if (rte_intr_enable(pdev->intr_handle)) {
367826da0f5SVamsi Attunuru 		otx_ep_err("rte_intr_enable failed");
368826da0f5SVamsi Attunuru 		return -1;
369826da0f5SVamsi Attunuru 	}
370826da0f5SVamsi Attunuru 
371*304ba46bSVamsi Attunuru 	reg_val = otx2_read64(otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_INT(0));
372*304ba46bSVamsi Attunuru 	if (reg_val == UINT64_MAX)
373*304ba46bSVamsi Attunuru 		return -ENODEV;
374*304ba46bSVamsi Attunuru 
375826da0f5SVamsi Attunuru 	/* Enable pf-vf mbox interrupt & clear the status */
376826da0f5SVamsi Attunuru 	otx2_write64(CNXK_EP_MBOX_ENAB | CNXK_EP_MBOX_INTR,
377826da0f5SVamsi Attunuru 		     otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_INT(0));
378826da0f5SVamsi Attunuru 
379cab13b70SSathesh Edara 	return 0;
380c836a7baSSathesh Edara }
381c836a7baSSathesh Edara 
382826da0f5SVamsi Attunuru void
383826da0f5SVamsi Attunuru otx_ep_mbox_uninit(struct rte_eth_dev *eth_dev)
384826da0f5SVamsi Attunuru {
385826da0f5SVamsi Attunuru 	struct otx_ep_device *otx_ep = (struct otx_ep_device *)eth_dev->data->dev_private;
386826da0f5SVamsi Attunuru 	struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(eth_dev);
387826da0f5SVamsi Attunuru 
388826da0f5SVamsi Attunuru 	otx2_write64(0, otx_ep->hw_addr + CNXK_EP_R_MBOX_PF_VF_INT(0));
389826da0f5SVamsi Attunuru 
390826da0f5SVamsi Attunuru 	rte_intr_disable(pdev->intr_handle);
391826da0f5SVamsi Attunuru 
392826da0f5SVamsi Attunuru 	rte_intr_callback_unregister(pdev->intr_handle, otx_ep_mbox_intr_handler, (void *)eth_dev);
393826da0f5SVamsi Attunuru }
394826da0f5SVamsi Attunuru 
395c836a7baSSathesh Edara int otx_ep_mbox_send_dev_exit(struct rte_eth_dev *eth_dev)
396c836a7baSSathesh Edara {
397c836a7baSSathesh Edara 	struct otx_ep_device *otx_ep =
398c836a7baSSathesh Edara 		(struct otx_ep_device *)(eth_dev)->data->dev_private;
399c836a7baSSathesh Edara 	union otx_ep_mbox_word cmd;
400c836a7baSSathesh Edara 	int ret;
401c836a7baSSathesh Edara 
402c836a7baSSathesh Edara 	cmd.u64 = 0;
403c836a7baSSathesh Edara 	cmd.s_version.opcode = OTX_EP_MBOX_CMD_DEV_REMOVE;
404c836a7baSSathesh Edara 	ret = otx_ep_send_mbox_cmd(otx_ep, cmd, NULL);
405c836a7baSSathesh Edara 	return ret;
406c836a7baSSathesh Edara }
407