1cb7dd712SShinas Rasheed // SPDX-License-Identifier: GPL-2.0
2cb7dd712SShinas Rasheed /* Marvell Octeon EP (EndPoint) VF Ethernet Driver
3cb7dd712SShinas Rasheed  *
4cb7dd712SShinas Rasheed  * Copyright (C) 2020 Marvell.
5cb7dd712SShinas Rasheed  *
6cb7dd712SShinas Rasheed  */
7cb7dd712SShinas Rasheed #include <linux/types.h>
8cb7dd712SShinas Rasheed #include <linux/pci.h>
9cb7dd712SShinas Rasheed #include <linux/netdevice.h>
10*0069455bSKent Overstreet #include <linux/vmalloc.h>
11cb7dd712SShinas Rasheed #include "octep_vf_config.h"
12cb7dd712SShinas Rasheed #include "octep_vf_main.h"
13cb7dd712SShinas Rasheed 
14c5cb944dSShinas Rasheed /* When a new command is implemented, the below table should be updated
15c5cb944dSShinas Rasheed  * with new command and it's version info.
16c5cb944dSShinas Rasheed  */
17c5cb944dSShinas Rasheed static u32 pfvf_cmd_versions[OCTEP_PFVF_MBOX_CMD_MAX] = {
18c5cb944dSShinas Rasheed 	[0 ... OCTEP_PFVF_MBOX_CMD_DEV_REMOVE] = OCTEP_PFVF_MBOX_VERSION_V1,
19c5cb944dSShinas Rasheed 	[OCTEP_PFVF_MBOX_CMD_GET_FW_INFO ... OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS] =
20c5cb944dSShinas Rasheed 		OCTEP_PFVF_MBOX_VERSION_V2
21c5cb944dSShinas Rasheed };
22c5cb944dSShinas Rasheed 
octep_vf_setup_mbox(struct octep_vf_device * oct)23cb7dd712SShinas Rasheed int octep_vf_setup_mbox(struct octep_vf_device *oct)
24cb7dd712SShinas Rasheed {
25cb7dd712SShinas Rasheed 	int ring = 0;
26cb7dd712SShinas Rasheed 
27cb7dd712SShinas Rasheed 	oct->mbox = vzalloc(sizeof(*oct->mbox));
28cb7dd712SShinas Rasheed 	if (!oct->mbox)
29cb7dd712SShinas Rasheed 		return -1;
30cb7dd712SShinas Rasheed 
31cb7dd712SShinas Rasheed 	mutex_init(&oct->mbox->lock);
32cb7dd712SShinas Rasheed 
33cb7dd712SShinas Rasheed 	oct->hw_ops.setup_mbox_regs(oct, ring);
34cb7dd712SShinas Rasheed 	INIT_WORK(&oct->mbox->wk.work, octep_vf_mbox_work);
35cb7dd712SShinas Rasheed 	oct->mbox->wk.ctxptr = oct;
36c5cb944dSShinas Rasheed 	oct->mbox_neg_ver = OCTEP_PFVF_MBOX_VERSION_CURRENT;
37cb7dd712SShinas Rasheed 	dev_info(&oct->pdev->dev, "setup vf mbox successfully\n");
38cb7dd712SShinas Rasheed 	return 0;
39cb7dd712SShinas Rasheed }
40cb7dd712SShinas Rasheed 
octep_vf_delete_mbox(struct octep_vf_device * oct)41cb7dd712SShinas Rasheed void octep_vf_delete_mbox(struct octep_vf_device *oct)
42cb7dd712SShinas Rasheed {
43cb7dd712SShinas Rasheed 	if (oct->mbox) {
44cb7dd712SShinas Rasheed 		if (work_pending(&oct->mbox->wk.work))
45cb7dd712SShinas Rasheed 			cancel_work_sync(&oct->mbox->wk.work);
46cb7dd712SShinas Rasheed 
47cb7dd712SShinas Rasheed 		mutex_destroy(&oct->mbox->lock);
48cb7dd712SShinas Rasheed 		vfree(oct->mbox);
49cb7dd712SShinas Rasheed 		oct->mbox = NULL;
50cb7dd712SShinas Rasheed 		dev_info(&oct->pdev->dev, "Deleted vf mbox successfully\n");
51cb7dd712SShinas Rasheed 	}
52cb7dd712SShinas Rasheed }
53cb7dd712SShinas Rasheed 
octep_vf_mbox_version_check(struct octep_vf_device * oct)54cb7dd712SShinas Rasheed int octep_vf_mbox_version_check(struct octep_vf_device *oct)
55cb7dd712SShinas Rasheed {
56c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
57c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
58c5cb944dSShinas Rasheed 	int ret;
59c5cb944dSShinas Rasheed 
60c5cb944dSShinas Rasheed 	cmd.u64 = 0;
61c5cb944dSShinas Rasheed 	cmd.s_version.opcode = OCTEP_PFVF_MBOX_CMD_VERSION;
62c5cb944dSShinas Rasheed 	cmd.s_version.version = OCTEP_PFVF_MBOX_VERSION_CURRENT;
63c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
64c5cb944dSShinas Rasheed 	if (ret == OCTEP_PFVF_MBOX_CMD_STATUS_NACK) {
65c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev,
66c5cb944dSShinas Rasheed 			"VF Mbox version is incompatible with PF\n");
67c5cb944dSShinas Rasheed 		return -EINVAL;
68c5cb944dSShinas Rasheed 	}
69c5cb944dSShinas Rasheed 	oct->mbox_neg_ver = (u32)rsp.s_version.version;
70c5cb944dSShinas Rasheed 	dev_dbg(&oct->pdev->dev,
71c5cb944dSShinas Rasheed 		"VF Mbox version:%u Negotiated VF version with PF:%u\n",
72c5cb944dSShinas Rasheed 		 (u32)cmd.s_version.version,
73c5cb944dSShinas Rasheed 		 (u32)rsp.s_version.version);
74cb7dd712SShinas Rasheed 	return 0;
75cb7dd712SShinas Rasheed }
76cb7dd712SShinas Rasheed 
octep_vf_mbox_work(struct work_struct * work)77cb7dd712SShinas Rasheed void octep_vf_mbox_work(struct work_struct *work)
78cb7dd712SShinas Rasheed {
79c5cb944dSShinas Rasheed 	struct octep_vf_mbox_wk *wk = container_of(work, struct octep_vf_mbox_wk, work);
80c5cb944dSShinas Rasheed 	struct octep_vf_iface_link_info *link_info;
81c5cb944dSShinas Rasheed 	struct octep_vf_device *oct = NULL;
82c5cb944dSShinas Rasheed 	struct octep_vf_mbox *mbox = NULL;
83c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word *notif;
84c5cb944dSShinas Rasheed 	u64 pf_vf_data;
85c5cb944dSShinas Rasheed 
86c5cb944dSShinas Rasheed 	oct = (struct octep_vf_device *)wk->ctxptr;
87c5cb944dSShinas Rasheed 	link_info = &oct->link_info;
88c5cb944dSShinas Rasheed 	mbox = oct->mbox;
89c5cb944dSShinas Rasheed 	pf_vf_data = readq(mbox->mbox_read_reg);
90c5cb944dSShinas Rasheed 
91c5cb944dSShinas Rasheed 	notif = (union octep_pfvf_mbox_word *)&pf_vf_data;
92c5cb944dSShinas Rasheed 
93c5cb944dSShinas Rasheed 	switch (notif->s.opcode) {
94c5cb944dSShinas Rasheed 	case OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS:
95c5cb944dSShinas Rasheed 		if (notif->s_link_status.status) {
96c5cb944dSShinas Rasheed 			link_info->oper_up = OCTEP_PFVF_LINK_STATUS_UP;
97c5cb944dSShinas Rasheed 			netif_carrier_on(oct->netdev);
98c5cb944dSShinas Rasheed 			dev_info(&oct->pdev->dev, "netif_carrier_on\n");
99c5cb944dSShinas Rasheed 		} else {
100c5cb944dSShinas Rasheed 			link_info->oper_up = OCTEP_PFVF_LINK_STATUS_DOWN;
101c5cb944dSShinas Rasheed 			netif_carrier_off(oct->netdev);
102c5cb944dSShinas Rasheed 			dev_info(&oct->pdev->dev, "netif_carrier_off\n");
103c5cb944dSShinas Rasheed 		}
104c5cb944dSShinas Rasheed 		break;
105c5cb944dSShinas Rasheed 	default:
106c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev,
107c5cb944dSShinas Rasheed 			"Received unsupported notif %d\n", notif->s.opcode);
108c5cb944dSShinas Rasheed 		break;
109c5cb944dSShinas Rasheed 	}
110c5cb944dSShinas Rasheed }
111c5cb944dSShinas Rasheed 
__octep_vf_mbox_send_cmd(struct octep_vf_device * oct,union octep_pfvf_mbox_word cmd,union octep_pfvf_mbox_word * rsp)112c5cb944dSShinas Rasheed static int __octep_vf_mbox_send_cmd(struct octep_vf_device *oct,
113c5cb944dSShinas Rasheed 				    union octep_pfvf_mbox_word cmd,
114c5cb944dSShinas Rasheed 				    union octep_pfvf_mbox_word *rsp)
115c5cb944dSShinas Rasheed {
116c5cb944dSShinas Rasheed 	struct octep_vf_mbox *mbox = oct->mbox;
117c5cb944dSShinas Rasheed 	u64 reg_val = 0ull;
118c5cb944dSShinas Rasheed 	int count;
119c5cb944dSShinas Rasheed 
120c5cb944dSShinas Rasheed 	if (!mbox)
121c5cb944dSShinas Rasheed 		return OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP;
122c5cb944dSShinas Rasheed 
123c5cb944dSShinas Rasheed 	cmd.s.type = OCTEP_PFVF_MBOX_TYPE_CMD;
124c5cb944dSShinas Rasheed 	writeq(cmd.u64, mbox->mbox_write_reg);
125c5cb944dSShinas Rasheed 
126c5cb944dSShinas Rasheed 	/* No response for notification messages */
127c5cb944dSShinas Rasheed 	if (!rsp)
128c5cb944dSShinas Rasheed 		return 0;
129c5cb944dSShinas Rasheed 
130c5cb944dSShinas Rasheed 	for (count = 0; count < OCTEP_PFVF_MBOX_TIMEOUT_WAIT_COUNT; count++) {
131c5cb944dSShinas Rasheed 		usleep_range(1000, 1500);
132c5cb944dSShinas Rasheed 		reg_val = readq(mbox->mbox_write_reg);
133c5cb944dSShinas Rasheed 		if (reg_val != cmd.u64) {
134c5cb944dSShinas Rasheed 			rsp->u64 = reg_val;
135c5cb944dSShinas Rasheed 			break;
136c5cb944dSShinas Rasheed 		}
137c5cb944dSShinas Rasheed 	}
138c5cb944dSShinas Rasheed 	if (count == OCTEP_PFVF_MBOX_TIMEOUT_WAIT_COUNT) {
139c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "mbox send command timed out\n");
140c5cb944dSShinas Rasheed 		return OCTEP_PFVF_MBOX_CMD_STATUS_TIMEDOUT;
141c5cb944dSShinas Rasheed 	}
142c5cb944dSShinas Rasheed 	if (rsp->s.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
143c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "mbox_send: Received NACK\n");
144c5cb944dSShinas Rasheed 		return OCTEP_PFVF_MBOX_CMD_STATUS_NACK;
145c5cb944dSShinas Rasheed 	}
146c5cb944dSShinas Rasheed 	rsp->u64 = reg_val;
147c5cb944dSShinas Rasheed 	return 0;
148c5cb944dSShinas Rasheed }
149c5cb944dSShinas Rasheed 
octep_vf_mbox_send_cmd(struct octep_vf_device * oct,union octep_pfvf_mbox_word cmd,union octep_pfvf_mbox_word * rsp)150c5cb944dSShinas Rasheed int octep_vf_mbox_send_cmd(struct octep_vf_device *oct, union octep_pfvf_mbox_word cmd,
151c5cb944dSShinas Rasheed 			   union octep_pfvf_mbox_word *rsp)
152c5cb944dSShinas Rasheed {
153c5cb944dSShinas Rasheed 	struct octep_vf_mbox *mbox = oct->mbox;
154c5cb944dSShinas Rasheed 	int ret;
155c5cb944dSShinas Rasheed 
156c5cb944dSShinas Rasheed 	if (!mbox)
157c5cb944dSShinas Rasheed 		return OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP;
158c5cb944dSShinas Rasheed 	mutex_lock(&mbox->lock);
159c5cb944dSShinas Rasheed 	if (pfvf_cmd_versions[cmd.s.opcode] > oct->mbox_neg_ver) {
160c5cb944dSShinas Rasheed 		dev_dbg(&oct->pdev->dev, "CMD:%d not supported in Version:%d\n",
161c5cb944dSShinas Rasheed 			cmd.s.opcode, oct->mbox_neg_ver);
162c5cb944dSShinas Rasheed 		mutex_unlock(&mbox->lock);
163c5cb944dSShinas Rasheed 		return -EOPNOTSUPP;
164c5cb944dSShinas Rasheed 	}
165c5cb944dSShinas Rasheed 	ret = __octep_vf_mbox_send_cmd(oct, cmd, rsp);
166c5cb944dSShinas Rasheed 	mutex_unlock(&mbox->lock);
167c5cb944dSShinas Rasheed 	return ret;
168c5cb944dSShinas Rasheed }
169c5cb944dSShinas Rasheed 
octep_vf_mbox_bulk_read(struct octep_vf_device * oct,enum octep_pfvf_mbox_opcode opcode,u8 * data,int * size)170c5cb944dSShinas Rasheed int octep_vf_mbox_bulk_read(struct octep_vf_device *oct, enum octep_pfvf_mbox_opcode opcode,
171c5cb944dSShinas Rasheed 			    u8 *data, int *size)
172c5cb944dSShinas Rasheed {
173c5cb944dSShinas Rasheed 	struct octep_vf_mbox *mbox = oct->mbox;
174c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
175c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
176c5cb944dSShinas Rasheed 	int data_len = 0, tmp_len = 0;
177c5cb944dSShinas Rasheed 	int read_cnt, i = 0, ret;
178c5cb944dSShinas Rasheed 
179c5cb944dSShinas Rasheed 	if (!mbox)
180c5cb944dSShinas Rasheed 		return OCTEP_PFVF_MBOX_CMD_STATUS_NOT_SETUP;
181c5cb944dSShinas Rasheed 
182c5cb944dSShinas Rasheed 	mutex_lock(&mbox->lock);
183c5cb944dSShinas Rasheed 	cmd.u64 = 0;
184c5cb944dSShinas Rasheed 	cmd.s_data.opcode = opcode;
185c5cb944dSShinas Rasheed 	cmd.s_data.frag = 0;
186c5cb944dSShinas Rasheed 	/* Send cmd to read data from PF */
187c5cb944dSShinas Rasheed 	ret = __octep_vf_mbox_send_cmd(oct, cmd, &rsp);
188c5cb944dSShinas Rasheed 	if (ret) {
189c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "send mbox cmd fail for data request\n");
190c5cb944dSShinas Rasheed 		mutex_unlock(&mbox->lock);
191c5cb944dSShinas Rasheed 		return ret;
192c5cb944dSShinas Rasheed 	}
193c5cb944dSShinas Rasheed 	/*  PF sends the data length of requested CMD
194c5cb944dSShinas Rasheed 	 *  in  ACK
195c5cb944dSShinas Rasheed 	 */
196c5cb944dSShinas Rasheed 	data_len = *((int32_t *)rsp.s_data.data);
197c5cb944dSShinas Rasheed 	tmp_len = data_len;
198c5cb944dSShinas Rasheed 	cmd.u64 = 0;
199c5cb944dSShinas Rasheed 	rsp.u64 = 0;
200c5cb944dSShinas Rasheed 	cmd.s_data.opcode = opcode;
201c5cb944dSShinas Rasheed 	cmd.s_data.frag = 1;
202c5cb944dSShinas Rasheed 	while (data_len) {
203c5cb944dSShinas Rasheed 		ret = __octep_vf_mbox_send_cmd(oct, cmd, &rsp);
204c5cb944dSShinas Rasheed 		if (ret) {
205c5cb944dSShinas Rasheed 			dev_err(&oct->pdev->dev, "send mbox cmd fail for data request\n");
206c5cb944dSShinas Rasheed 			mutex_unlock(&mbox->lock);
207c5cb944dSShinas Rasheed 			mbox->mbox_data.data_index = 0;
208c5cb944dSShinas Rasheed 			memset(mbox->mbox_data.recv_data, 0, OCTEP_PFVF_MBOX_MAX_DATA_BUF_SIZE);
209c5cb944dSShinas Rasheed 			return ret;
210c5cb944dSShinas Rasheed 		}
211c5cb944dSShinas Rasheed 		if (data_len > OCTEP_PFVF_MBOX_MAX_DATA_SIZE) {
212c5cb944dSShinas Rasheed 			data_len -= OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
213c5cb944dSShinas Rasheed 			read_cnt = OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
214c5cb944dSShinas Rasheed 		} else {
215c5cb944dSShinas Rasheed 			read_cnt = data_len;
216c5cb944dSShinas Rasheed 			data_len = 0;
217c5cb944dSShinas Rasheed 		}
218c5cb944dSShinas Rasheed 		for (i = 0; i < read_cnt; i++) {
219c5cb944dSShinas Rasheed 			mbox->mbox_data.recv_data[mbox->mbox_data.data_index] =
220c5cb944dSShinas Rasheed 				rsp.s_data.data[i];
221c5cb944dSShinas Rasheed 			mbox->mbox_data.data_index++;
222c5cb944dSShinas Rasheed 		}
223c5cb944dSShinas Rasheed 		cmd.u64 = 0;
224c5cb944dSShinas Rasheed 		rsp.u64 = 0;
225c5cb944dSShinas Rasheed 		cmd.s_data.opcode = opcode;
226c5cb944dSShinas Rasheed 		cmd.s_data.frag = 1;
227c5cb944dSShinas Rasheed 	}
228c5cb944dSShinas Rasheed 	memcpy(data, mbox->mbox_data.recv_data, tmp_len);
229c5cb944dSShinas Rasheed 	*size = tmp_len;
230c5cb944dSShinas Rasheed 	mbox->mbox_data.data_index = 0;
231c5cb944dSShinas Rasheed 	memset(mbox->mbox_data.recv_data, 0, OCTEP_PFVF_MBOX_MAX_DATA_BUF_SIZE);
232c5cb944dSShinas Rasheed 	mutex_unlock(&mbox->lock);
233c5cb944dSShinas Rasheed 	return 0;
234cb7dd712SShinas Rasheed }
235cb7dd712SShinas Rasheed 
octep_vf_mbox_set_mtu(struct octep_vf_device * oct,int mtu)236cb7dd712SShinas Rasheed int octep_vf_mbox_set_mtu(struct octep_vf_device *oct, int mtu)
237cb7dd712SShinas Rasheed {
238c5cb944dSShinas Rasheed 	int frame_size = mtu + ETH_HLEN + ETH_FCS_LEN;
239c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
240c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
241c5cb944dSShinas Rasheed 	int ret = 0;
242c5cb944dSShinas Rasheed 
243c5cb944dSShinas Rasheed 	if (mtu < ETH_MIN_MTU || frame_size > ETH_MAX_MTU) {
244c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev,
245c5cb944dSShinas Rasheed 			"Failed to set MTU to %d MIN MTU:%d MAX MTU:%d\n",
246c5cb944dSShinas Rasheed 			mtu, ETH_MIN_MTU, ETH_MAX_MTU);
247c5cb944dSShinas Rasheed 		return -EINVAL;
248c5cb944dSShinas Rasheed 	}
249c5cb944dSShinas Rasheed 
250c5cb944dSShinas Rasheed 	cmd.u64 = 0;
251c5cb944dSShinas Rasheed 	cmd.s_set_mtu.opcode = OCTEP_PFVF_MBOX_CMD_SET_MTU;
252c5cb944dSShinas Rasheed 	cmd.s_set_mtu.mtu = mtu;
253c5cb944dSShinas Rasheed 
254c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
255c5cb944dSShinas Rasheed 	if (ret) {
256c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Mbox send failed; err=%d\n", ret);
257c5cb944dSShinas Rasheed 		return ret;
258c5cb944dSShinas Rasheed 	}
259c5cb944dSShinas Rasheed 	if (rsp.s_set_mtu.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
260c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Received Mbox NACK from PF for MTU:%d\n", mtu);
261c5cb944dSShinas Rasheed 		return -EINVAL;
262c5cb944dSShinas Rasheed 	}
263c5cb944dSShinas Rasheed 
264cb7dd712SShinas Rasheed 	return 0;
265cb7dd712SShinas Rasheed }
266cb7dd712SShinas Rasheed 
octep_vf_mbox_set_mac_addr(struct octep_vf_device * oct,char * mac_addr)267cb7dd712SShinas Rasheed int octep_vf_mbox_set_mac_addr(struct octep_vf_device *oct, char *mac_addr)
268cb7dd712SShinas Rasheed {
269c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
270c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
271c5cb944dSShinas Rasheed 	int i, ret;
272c5cb944dSShinas Rasheed 
273c5cb944dSShinas Rasheed 	cmd.u64 = 0;
274c5cb944dSShinas Rasheed 	cmd.s_set_mac.opcode = OCTEP_PFVF_MBOX_CMD_SET_MAC_ADDR;
275c5cb944dSShinas Rasheed 	for (i = 0; i < ETH_ALEN; i++)
276c5cb944dSShinas Rasheed 		cmd.s_set_mac.mac_addr[i] = mac_addr[i];
277c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
278c5cb944dSShinas Rasheed 	if (ret) {
279c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Mbox send failed; err = %d\n", ret);
280c5cb944dSShinas Rasheed 		return ret;
281c5cb944dSShinas Rasheed 	}
282c5cb944dSShinas Rasheed 	if (rsp.s_set_mac.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
283c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "received NACK\n");
284c5cb944dSShinas Rasheed 		return -EINVAL;
285c5cb944dSShinas Rasheed 	}
286cb7dd712SShinas Rasheed 	return 0;
287cb7dd712SShinas Rasheed }
288cb7dd712SShinas Rasheed 
octep_vf_mbox_get_mac_addr(struct octep_vf_device * oct,char * mac_addr)289cb7dd712SShinas Rasheed int octep_vf_mbox_get_mac_addr(struct octep_vf_device *oct, char *mac_addr)
290cb7dd712SShinas Rasheed {
291c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
292c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
293c5cb944dSShinas Rasheed 	int i, ret;
294c5cb944dSShinas Rasheed 
295c5cb944dSShinas Rasheed 	cmd.u64 = 0;
296c5cb944dSShinas Rasheed 	cmd.s_set_mac.opcode = OCTEP_PFVF_MBOX_CMD_GET_MAC_ADDR;
297c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
298c5cb944dSShinas Rasheed 	if (ret) {
299c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "get_mac: mbox send failed; err = %d\n", ret);
300c5cb944dSShinas Rasheed 		return ret;
301c5cb944dSShinas Rasheed 	}
302c5cb944dSShinas Rasheed 	if (rsp.s_set_mac.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
303c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "get_mac: received NACK\n");
304c5cb944dSShinas Rasheed 		return -EINVAL;
305c5cb944dSShinas Rasheed 	}
306c5cb944dSShinas Rasheed 	for (i = 0; i < ETH_ALEN; i++)
307c5cb944dSShinas Rasheed 		mac_addr[i] = rsp.s_set_mac.mac_addr[i];
308cb7dd712SShinas Rasheed 	return 0;
309cb7dd712SShinas Rasheed }
310cb7dd712SShinas Rasheed 
octep_vf_mbox_set_rx_state(struct octep_vf_device * oct,bool state)311cb7dd712SShinas Rasheed int octep_vf_mbox_set_rx_state(struct octep_vf_device *oct, bool state)
312cb7dd712SShinas Rasheed {
313c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
314c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
315c5cb944dSShinas Rasheed 	int ret;
316c5cb944dSShinas Rasheed 
317c5cb944dSShinas Rasheed 	cmd.u64 = 0;
318c5cb944dSShinas Rasheed 	cmd.s_link_state.opcode = OCTEP_PFVF_MBOX_CMD_SET_RX_STATE;
319c5cb944dSShinas Rasheed 	cmd.s_link_state.state = state;
320c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
321c5cb944dSShinas Rasheed 	if (ret) {
322c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set Rx state via VF Mbox send failed\n");
323c5cb944dSShinas Rasheed 		return ret;
324c5cb944dSShinas Rasheed 	}
325c5cb944dSShinas Rasheed 	if (rsp.s_link_state.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
326c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set Rx state received NACK\n");
327c5cb944dSShinas Rasheed 		return -EINVAL;
328c5cb944dSShinas Rasheed 	}
329cb7dd712SShinas Rasheed 	return 0;
330cb7dd712SShinas Rasheed }
331cb7dd712SShinas Rasheed 
octep_vf_mbox_set_link_status(struct octep_vf_device * oct,bool status)332cb7dd712SShinas Rasheed int octep_vf_mbox_set_link_status(struct octep_vf_device *oct, bool status)
333cb7dd712SShinas Rasheed {
334c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
335c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
336c5cb944dSShinas Rasheed 	int ret;
337c5cb944dSShinas Rasheed 
338c5cb944dSShinas Rasheed 	cmd.u64 = 0;
339c5cb944dSShinas Rasheed 	cmd.s_link_status.opcode = OCTEP_PFVF_MBOX_CMD_SET_LINK_STATUS;
340c5cb944dSShinas Rasheed 	cmd.s_link_status.status = status;
341c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
342c5cb944dSShinas Rasheed 	if (ret) {
343c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set link status via VF Mbox send failed\n");
344c5cb944dSShinas Rasheed 		return ret;
345c5cb944dSShinas Rasheed 	}
346c5cb944dSShinas Rasheed 	if (rsp.s_link_status.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
347c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set link status received NACK\n");
348c5cb944dSShinas Rasheed 		return -EINVAL;
349c5cb944dSShinas Rasheed 	}
350cb7dd712SShinas Rasheed 	return 0;
351cb7dd712SShinas Rasheed }
352cb7dd712SShinas Rasheed 
octep_vf_mbox_get_link_status(struct octep_vf_device * oct,u8 * oper_up)353cb7dd712SShinas Rasheed int octep_vf_mbox_get_link_status(struct octep_vf_device *oct, u8 *oper_up)
354cb7dd712SShinas Rasheed {
355c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
356c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
357c5cb944dSShinas Rasheed 	int ret;
358c5cb944dSShinas Rasheed 
359c5cb944dSShinas Rasheed 	cmd.u64 = 0;
360c5cb944dSShinas Rasheed 	cmd.s_link_status.opcode = OCTEP_PFVF_MBOX_CMD_GET_LINK_STATUS;
361c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
362c5cb944dSShinas Rasheed 	if (ret) {
363c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Get link status via VF Mbox send failed\n");
364c5cb944dSShinas Rasheed 		return ret;
365c5cb944dSShinas Rasheed 	}
366c5cb944dSShinas Rasheed 	if (rsp.s_link_status.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
367c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Get link status received NACK\n");
368c5cb944dSShinas Rasheed 		return -EINVAL;
369c5cb944dSShinas Rasheed 	}
370c5cb944dSShinas Rasheed 	*oper_up = rsp.s_link_status.status;
371cb7dd712SShinas Rasheed 	return 0;
372cb7dd712SShinas Rasheed }
373cb7dd712SShinas Rasheed 
octep_vf_mbox_dev_remove(struct octep_vf_device * oct)374cb7dd712SShinas Rasheed int octep_vf_mbox_dev_remove(struct octep_vf_device *oct)
375cb7dd712SShinas Rasheed {
376c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
377c5cb944dSShinas Rasheed 	int ret;
378c5cb944dSShinas Rasheed 
379c5cb944dSShinas Rasheed 	cmd.u64 = 0;
380c5cb944dSShinas Rasheed 	cmd.s.opcode = OCTEP_PFVF_MBOX_CMD_DEV_REMOVE;
381c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, NULL);
382c5cb944dSShinas Rasheed 	return ret;
383cb7dd712SShinas Rasheed }
384cb7dd712SShinas Rasheed 
octep_vf_mbox_get_fw_info(struct octep_vf_device * oct)385cb7dd712SShinas Rasheed int octep_vf_mbox_get_fw_info(struct octep_vf_device *oct)
386cb7dd712SShinas Rasheed {
387c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
388c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
389c5cb944dSShinas Rasheed 	int ret;
390c5cb944dSShinas Rasheed 
391c5cb944dSShinas Rasheed 	cmd.u64 = 0;
392c5cb944dSShinas Rasheed 	cmd.s_fw_info.opcode = OCTEP_PFVF_MBOX_CMD_GET_FW_INFO;
393c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
394c5cb944dSShinas Rasheed 	if (ret) {
395c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Get link status via VF Mbox send failed\n");
396c5cb944dSShinas Rasheed 		return ret;
397c5cb944dSShinas Rasheed 	}
398c5cb944dSShinas Rasheed 	if (rsp.s_fw_info.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
399c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Get link status received NACK\n");
400c5cb944dSShinas Rasheed 		return -EINVAL;
401c5cb944dSShinas Rasheed 	}
402c5cb944dSShinas Rasheed 	oct->fw_info.pkind = rsp.s_fw_info.pkind;
403c5cb944dSShinas Rasheed 	oct->fw_info.fsz = rsp.s_fw_info.fsz;
404c5cb944dSShinas Rasheed 	oct->fw_info.rx_ol_flags = rsp.s_fw_info.rx_ol_flags;
405c5cb944dSShinas Rasheed 	oct->fw_info.tx_ol_flags = rsp.s_fw_info.tx_ol_flags;
406c5cb944dSShinas Rasheed 
407cb7dd712SShinas Rasheed 	return 0;
408cb7dd712SShinas Rasheed }
409cb7dd712SShinas Rasheed 
octep_vf_mbox_set_offloads(struct octep_vf_device * oct,u16 tx_offloads,u16 rx_offloads)410cb7dd712SShinas Rasheed int octep_vf_mbox_set_offloads(struct octep_vf_device *oct, u16 tx_offloads,
411cb7dd712SShinas Rasheed 			       u16 rx_offloads)
412cb7dd712SShinas Rasheed {
413c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word cmd;
414c5cb944dSShinas Rasheed 	union octep_pfvf_mbox_word rsp;
415c5cb944dSShinas Rasheed 	int ret;
416c5cb944dSShinas Rasheed 
417c5cb944dSShinas Rasheed 	cmd.u64 = 0;
418c5cb944dSShinas Rasheed 	cmd.s_offloads.opcode = OCTEP_PFVF_MBOX_CMD_SET_OFFLOADS;
419c5cb944dSShinas Rasheed 	cmd.s_offloads.rx_ol_flags = rx_offloads;
420c5cb944dSShinas Rasheed 	cmd.s_offloads.tx_ol_flags = tx_offloads;
421c5cb944dSShinas Rasheed 	ret = octep_vf_mbox_send_cmd(oct, cmd, &rsp);
422c5cb944dSShinas Rasheed 	if (ret) {
423c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set offloads via VF Mbox send failed\n");
424c5cb944dSShinas Rasheed 		return ret;
425c5cb944dSShinas Rasheed 	}
426c5cb944dSShinas Rasheed 	if (rsp.s_link_state.type != OCTEP_PFVF_MBOX_TYPE_RSP_ACK) {
427c5cb944dSShinas Rasheed 		dev_err(&oct->pdev->dev, "Set offloads received NACK\n");
428c5cb944dSShinas Rasheed 		return -EINVAL;
429c5cb944dSShinas Rasheed 	}
430cb7dd712SShinas Rasheed 	return 0;
431cb7dd712SShinas Rasheed }
432