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