xref: /linux/drivers/net/ethernet/huawei/hinic/hinic_port.c (revision 8ca4fc323d2e4ab9dabbdd57633af40b0c7e6af9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Huawei HiNIC PCI Express Linux driver
4  * Copyright(c) 2017 Huawei Technologies Co., Ltd
5  */
6 
7 #include <linux/types.h>
8 #include <linux/netdevice.h>
9 #include <linux/etherdevice.h>
10 #include <linux/if_vlan.h>
11 #include <linux/pci.h>
12 #include <linux/device.h>
13 #include <linux/errno.h>
14 
15 #include "hinic_hw_if.h"
16 #include "hinic_hw_dev.h"
17 #include "hinic_port.h"
18 #include "hinic_dev.h"
19 
20 enum mac_op {
21 	MAC_DEL,
22 	MAC_SET,
23 };
24 
25 /**
26  * change_mac - change(add or delete) mac address
27  * @nic_dev: nic device
28  * @addr: mac address
29  * @vlan_id: vlan number to set with the mac
30  * @op: add or delete the mac
31  *
32  * Return 0 - Success, negative - Failure
33  **/
34 static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
35 		      u16 vlan_id, enum mac_op op)
36 {
37 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
38 	struct hinic_port_mac_cmd port_mac_cmd;
39 	struct hinic_hwif *hwif = hwdev->hwif;
40 	u16 out_size = sizeof(port_mac_cmd);
41 	struct pci_dev *pdev = hwif->pdev;
42 	enum hinic_port_cmd cmd;
43 	int err;
44 
45 	if (op == MAC_SET)
46 		cmd = HINIC_PORT_CMD_SET_MAC;
47 	else
48 		cmd = HINIC_PORT_CMD_DEL_MAC;
49 
50 	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
51 	port_mac_cmd.vlan_id = vlan_id;
52 	memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
53 
54 	err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
55 				 sizeof(port_mac_cmd),
56 				 &port_mac_cmd, &out_size);
57 	if (err || out_size != sizeof(port_mac_cmd) ||
58 	    (port_mac_cmd.status &&
59 	     (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
60 	     port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
61 		dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
62 			err, port_mac_cmd.status, out_size);
63 		return -EFAULT;
64 	}
65 
66 	if (port_mac_cmd.status == HINIC_PF_SET_VF_ALREADY) {
67 		dev_warn(&pdev->dev, "PF has already set VF mac, ignore %s operation\n",
68 			 (op == MAC_SET) ? "set" : "del");
69 		return HINIC_PF_SET_VF_ALREADY;
70 	}
71 
72 	if (cmd == HINIC_PORT_CMD_SET_MAC && port_mac_cmd.status ==
73 	    HINIC_MGMT_STATUS_EXIST)
74 		dev_warn(&pdev->dev, "MAC is repeated, ignore set operation\n");
75 
76 	return 0;
77 }
78 
79 /**
80  * hinic_port_add_mac - add mac address
81  * @nic_dev: nic device
82  * @addr: mac address
83  * @vlan_id: vlan number to set with the mac
84  *
85  * Return 0 - Success, negative - Failure
86  **/
87 int hinic_port_add_mac(struct hinic_dev *nic_dev,
88 		       const u8 *addr, u16 vlan_id)
89 {
90 	return change_mac(nic_dev, addr, vlan_id, MAC_SET);
91 }
92 
93 /**
94  * hinic_port_del_mac - remove mac address
95  * @nic_dev: nic device
96  * @addr: mac address
97  * @vlan_id: vlan number that is connected to the mac
98  *
99  * Return 0 - Success, negative - Failure
100  **/
101 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
102 		       u16 vlan_id)
103 {
104 	return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
105 }
106 
107 /**
108  * hinic_port_get_mac - get the mac address of the nic device
109  * @nic_dev: nic device
110  * @addr: returned mac address
111  *
112  * Return 0 - Success, negative - Failure
113  **/
114 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
115 {
116 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
117 	struct hinic_port_mac_cmd port_mac_cmd;
118 	struct hinic_hwif *hwif = hwdev->hwif;
119 	u16 out_size = sizeof(port_mac_cmd);
120 	struct pci_dev *pdev = hwif->pdev;
121 	int err;
122 
123 	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
124 
125 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
126 				 &port_mac_cmd, sizeof(port_mac_cmd),
127 				 &port_mac_cmd, &out_size);
128 	if (err || out_size != sizeof(port_mac_cmd) || port_mac_cmd.status) {
129 		dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
130 			err, port_mac_cmd.status, out_size);
131 		return -EFAULT;
132 	}
133 
134 	memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
135 	return 0;
136 }
137 
138 /**
139  * hinic_port_set_mtu - set mtu
140  * @nic_dev: nic device
141  * @new_mtu: new mtu
142  *
143  * Return 0 - Success, negative - Failure
144  **/
145 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
146 {
147 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
148 	struct hinic_port_mtu_cmd port_mtu_cmd;
149 	struct hinic_hwif *hwif = hwdev->hwif;
150 	u16 out_size = sizeof(port_mtu_cmd);
151 	struct pci_dev *pdev = hwif->pdev;
152 	int err;
153 
154 	port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
155 	port_mtu_cmd.mtu = new_mtu;
156 
157 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
158 				 &port_mtu_cmd, sizeof(port_mtu_cmd),
159 				 &port_mtu_cmd, &out_size);
160 	if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
161 		dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
162 			err, port_mtu_cmd.status, out_size);
163 		return -EFAULT;
164 	}
165 
166 	return 0;
167 }
168 
169 /**
170  * hinic_port_add_vlan - add vlan to the nic device
171  * @nic_dev: nic device
172  * @vlan_id: the vlan number to add
173  *
174  * Return 0 - Success, negative - Failure
175  **/
176 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
177 {
178 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
179 	struct hinic_port_vlan_cmd port_vlan_cmd;
180 
181 	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
182 	port_vlan_cmd.vlan_id = vlan_id;
183 
184 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
185 				  &port_vlan_cmd, sizeof(port_vlan_cmd),
186 				  NULL, NULL);
187 }
188 
189 /**
190  * hinic_port_del_vlan - delete vlan from the nic device
191  * @nic_dev: nic device
192  * @vlan_id: the vlan number to delete
193  *
194  * Return 0 - Success, negative - Failure
195  **/
196 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
197 {
198 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
199 	struct hinic_port_vlan_cmd port_vlan_cmd;
200 
201 	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
202 	port_vlan_cmd.vlan_id = vlan_id;
203 
204 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
205 				 &port_vlan_cmd, sizeof(port_vlan_cmd),
206 				 NULL, NULL);
207 }
208 
209 /**
210  * hinic_port_set_rx_mode - set rx mode in the nic device
211  * @nic_dev: nic device
212  * @rx_mode: the rx mode to set
213  *
214  * Return 0 - Success, negative - Failure
215  **/
216 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
217 {
218 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
219 	struct hinic_port_rx_mode_cmd rx_mode_cmd;
220 
221 	rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
222 	rx_mode_cmd.rx_mode = rx_mode;
223 
224 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
225 				  &rx_mode_cmd, sizeof(rx_mode_cmd),
226 				  NULL, NULL);
227 }
228 
229 /**
230  * hinic_port_link_state - get the link state
231  * @nic_dev: nic device
232  * @link_state: the returned link state
233  *
234  * Return 0 - Success, negative - Failure
235  **/
236 int hinic_port_link_state(struct hinic_dev *nic_dev,
237 			  enum hinic_port_link_state *link_state)
238 {
239 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
240 	struct hinic_hwif *hwif = hwdev->hwif;
241 	struct hinic_port_link_cmd link_cmd;
242 	struct pci_dev *pdev = hwif->pdev;
243 	u16 out_size = sizeof(link_cmd);
244 	int err;
245 
246 	link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
247 
248 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
249 				 &link_cmd, sizeof(link_cmd),
250 				 &link_cmd, &out_size);
251 	if (err || out_size != sizeof(link_cmd) || link_cmd.status) {
252 		dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
253 			err, link_cmd.status, out_size);
254 		return -EINVAL;
255 	}
256 
257 	*link_state = link_cmd.state;
258 	return 0;
259 }
260 
261 /**
262  * hinic_port_set_state - set port state
263  * @nic_dev: nic device
264  * @state: the state to set
265  *
266  * Return 0 - Success, negative - Failure
267  **/
268 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
269 {
270 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
271 	struct hinic_port_state_cmd port_state;
272 	struct hinic_hwif *hwif = hwdev->hwif;
273 	struct pci_dev *pdev = hwif->pdev;
274 	u16 out_size = sizeof(port_state);
275 	int err;
276 
277 	if (HINIC_IS_VF(hwdev->hwif))
278 		return 0;
279 
280 	port_state.state = state;
281 
282 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PORT_STATE,
283 				 &port_state, sizeof(port_state),
284 				 &port_state, &out_size);
285 	if (err || out_size != sizeof(port_state) || port_state.status) {
286 		dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
287 			err, port_state.status, out_size);
288 		return -EFAULT;
289 	}
290 
291 	return 0;
292 }
293 
294 /**
295  * hinic_port_set_func_state- set func device state
296  * @nic_dev: nic device
297  * @state: the state to set
298  *
299  * Return 0 - Success, negative - Failure
300  **/
301 int hinic_port_set_func_state(struct hinic_dev *nic_dev,
302 			      enum hinic_func_port_state state)
303 {
304 	struct hinic_port_func_state_cmd func_state;
305 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
306 	struct hinic_hwif *hwif = hwdev->hwif;
307 	struct pci_dev *pdev = hwif->pdev;
308 	u16 out_size = sizeof(func_state);
309 	int err;
310 
311 	func_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
312 	func_state.state = state;
313 
314 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_FUNC_STATE,
315 				 &func_state, sizeof(func_state),
316 				 &func_state, &out_size);
317 	if (err || out_size != sizeof(func_state) || func_state.status) {
318 		dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
319 			err, func_state.status, out_size);
320 		return -EFAULT;
321 	}
322 
323 	return 0;
324 }
325 
326 /**
327  * hinic_port_get_cap - get port capabilities
328  * @nic_dev: nic device
329  * @port_cap: returned port capabilities
330  *
331  * Return 0 - Success, negative - Failure
332  **/
333 int hinic_port_get_cap(struct hinic_dev *nic_dev,
334 		       struct hinic_port_cap *port_cap)
335 {
336 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
337 	struct hinic_hwif *hwif = hwdev->hwif;
338 	struct pci_dev *pdev = hwif->pdev;
339 	u16 out_size = sizeof(*port_cap);
340 	int err;
341 
342 	port_cap->func_idx = HINIC_HWIF_FUNC_IDX(hwif);
343 
344 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_CAP,
345 				 port_cap, sizeof(*port_cap),
346 				 port_cap, &out_size);
347 	if (err || out_size != sizeof(*port_cap) || port_cap->status) {
348 		dev_err(&pdev->dev,
349 			"Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
350 			err, port_cap->status, out_size);
351 		return -EIO;
352 	}
353 
354 	return 0;
355 }
356 
357 /**
358  * hinic_port_set_tso - set port tso configuration
359  * @nic_dev: nic device
360  * @state: the tso state to set
361  *
362  * Return 0 - Success, negative - Failure
363  **/
364 int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
365 {
366 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
367 	struct hinic_hwif *hwif = hwdev->hwif;
368 	struct hinic_tso_config tso_cfg = {0};
369 	struct pci_dev *pdev = hwif->pdev;
370 	u16 out_size = sizeof(tso_cfg);
371 	int err;
372 
373 	tso_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
374 	tso_cfg.tso_en = state;
375 
376 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_TSO,
377 				 &tso_cfg, sizeof(tso_cfg),
378 				 &tso_cfg, &out_size);
379 	if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
380 		dev_err(&pdev->dev,
381 			"Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
382 			err, tso_cfg.status, out_size);
383 		return -EIO;
384 	}
385 
386 	return 0;
387 }
388 
389 int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
390 {
391 	struct hinic_checksum_offload rx_csum_cfg = {0};
392 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
393 	u16 out_size = sizeof(rx_csum_cfg);
394 	struct hinic_hwif *hwif;
395 	struct pci_dev *pdev;
396 	int err;
397 
398 	if (!hwdev)
399 		return -EINVAL;
400 
401 	hwif = hwdev->hwif;
402 	pdev = hwif->pdev;
403 	rx_csum_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
404 	rx_csum_cfg.rx_csum_offload = en;
405 
406 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
407 				 &rx_csum_cfg, sizeof(rx_csum_cfg),
408 				 &rx_csum_cfg, &out_size);
409 	if (err || !out_size || rx_csum_cfg.status) {
410 		dev_err(&pdev->dev,
411 			"Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
412 			err, rx_csum_cfg.status, out_size);
413 		return -EIO;
414 	}
415 
416 	return 0;
417 }
418 
419 int hinic_set_rx_vlan_offload(struct hinic_dev *nic_dev, u8 en)
420 {
421 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
422 	struct hinic_vlan_cfg vlan_cfg;
423 	struct hinic_hwif *hwif;
424 	struct pci_dev *pdev;
425 	u16 out_size;
426 	int err;
427 
428 	if (!hwdev)
429 		return -EINVAL;
430 
431 	out_size = sizeof(vlan_cfg);
432 	hwif = hwdev->hwif;
433 	pdev = hwif->pdev;
434 	vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
435 	vlan_cfg.vlan_rx_offload = en;
436 
437 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
438 				 &vlan_cfg, sizeof(vlan_cfg),
439 				 &vlan_cfg, &out_size);
440 	if (err || !out_size || vlan_cfg.status) {
441 		dev_err(&pdev->dev,
442 			"Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
443 			err, vlan_cfg.status, out_size);
444 		return -EINVAL;
445 	}
446 
447 	return 0;
448 }
449 
450 int hinic_set_vlan_fliter(struct hinic_dev *nic_dev, u32 en)
451 {
452 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
453 	struct hinic_hwif *hwif = hwdev->hwif;
454 	struct pci_dev *pdev = hwif->pdev;
455 	struct hinic_vlan_filter vlan_filter;
456 	u16 out_size = sizeof(vlan_filter);
457 	int err;
458 
459 	if (!hwdev)
460 		return -EINVAL;
461 
462 	vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
463 	vlan_filter.enable = en;
464 
465 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER,
466 				 &vlan_filter, sizeof(vlan_filter),
467 				 &vlan_filter, &out_size);
468 	if (vlan_filter.status == HINIC_MGMT_CMD_UNSUPPORTED) {
469 		err = HINIC_MGMT_CMD_UNSUPPORTED;
470 	} else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
471 			   HINIC_IS_VF(hwif)) {
472 		err = HINIC_MGMT_CMD_UNSUPPORTED;
473 	} else if (err || !out_size || vlan_filter.status) {
474 		dev_err(&pdev->dev,
475 			"Failed to set vlan fliter, err: %d, status: 0x%x, out size: 0x%x\n",
476 			err, vlan_filter.status, out_size);
477 		err = -EINVAL;
478 	}
479 
480 	return err;
481 }
482 
483 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
484 {
485 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
486 	struct hinic_hwif *hwif = hwdev->hwif;
487 	struct hinic_rq_num rq_num = { 0 };
488 	struct pci_dev *pdev = hwif->pdev;
489 	u16 out_size = sizeof(rq_num);
490 	int err;
491 
492 	rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
493 	rq_num.num_rqs = num_rqs;
494 	rq_num.rq_depth = ilog2(nic_dev->rq_depth);
495 
496 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
497 				 &rq_num, sizeof(rq_num),
498 				 &rq_num, &out_size);
499 	if (err || !out_size || rq_num.status) {
500 		dev_err(&pdev->dev,
501 			"Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
502 			err, rq_num.status, out_size);
503 		return -EIO;
504 	}
505 
506 	return 0;
507 }
508 
509 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
510 			    u8 max_wqe_num)
511 {
512 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
513 	struct hinic_lro_config lro_cfg = { 0 };
514 	struct hinic_hwif *hwif = hwdev->hwif;
515 	struct pci_dev *pdev = hwif->pdev;
516 	u16 out_size = sizeof(lro_cfg);
517 	int err;
518 
519 	lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
520 	lro_cfg.lro_ipv4_en = ipv4_en;
521 	lro_cfg.lro_ipv6_en = ipv6_en;
522 	lro_cfg.lro_max_wqe_num = max_wqe_num;
523 
524 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
525 				 &lro_cfg, sizeof(lro_cfg),
526 				 &lro_cfg, &out_size);
527 	if (err || !out_size || lro_cfg.status) {
528 		dev_err(&pdev->dev,
529 			"Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
530 			err, lro_cfg.status, out_size);
531 		return -EIO;
532 	}
533 
534 	return 0;
535 }
536 
537 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
538 {
539 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
540 	struct hinic_lro_timer lro_timer = { 0 };
541 	struct hinic_hwif *hwif = hwdev->hwif;
542 	struct pci_dev *pdev = hwif->pdev;
543 	u16 out_size = sizeof(lro_timer);
544 	int err;
545 
546 	lro_timer.status = 0;
547 	lro_timer.type = 0;
548 	lro_timer.enable = 1;
549 	lro_timer.timer = timer_value;
550 
551 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
552 				 &lro_timer, sizeof(lro_timer),
553 				 &lro_timer, &out_size);
554 	if (lro_timer.status == 0xFF) {
555 		/* For this case, we think status (0xFF) is OK */
556 		lro_timer.status = 0;
557 		dev_dbg(&pdev->dev,
558 			"Set lro timer not supported by the current FW version, it will be 1ms default\n");
559 	}
560 
561 	if (err || !out_size || lro_timer.status) {
562 		dev_err(&pdev->dev,
563 			"Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
564 			err, lro_timer.status, out_size);
565 
566 		return -EIO;
567 	}
568 
569 	return 0;
570 }
571 
572 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
573 			   u32 lro_timer, u32 wqe_num)
574 {
575 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
576 	u8 ipv4_en;
577 	u8 ipv6_en;
578 	int err;
579 
580 	if (!hwdev)
581 		return -EINVAL;
582 
583 	ipv4_en = lro_en ? 1 : 0;
584 	ipv6_en = lro_en ? 1 : 0;
585 
586 	err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
587 	if (err)
588 		return err;
589 
590 	if (HINIC_IS_VF(nic_dev->hwdev->hwif))
591 		return 0;
592 
593 	err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
594 	if (err)
595 		return err;
596 
597 	return 0;
598 }
599 
600 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
601 			    const u32 *indir_table)
602 {
603 	struct hinic_rss_indirect_tbl *indir_tbl;
604 	struct hinic_func_to_io *func_to_io;
605 	struct hinic_cmdq_buf cmd_buf;
606 	struct hinic_hwdev *hwdev;
607 	struct hinic_hwif *hwif;
608 	struct pci_dev *pdev;
609 	u32 indir_size;
610 	u64 out_param;
611 	int err, i;
612 	u32 *temp;
613 
614 	hwdev = nic_dev->hwdev;
615 	func_to_io = &hwdev->func_to_io;
616 	hwif = hwdev->hwif;
617 	pdev = hwif->pdev;
618 
619 	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
620 	if (err) {
621 		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
622 		return err;
623 	}
624 
625 	cmd_buf.size = sizeof(*indir_tbl);
626 
627 	indir_tbl = cmd_buf.buf;
628 	indir_tbl->group_index = cpu_to_be32(tmpl_idx);
629 
630 	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
631 		indir_tbl->entry[i] = indir_table[i];
632 
633 		if (0x3 == (i & 0x3)) {
634 			temp = (u32 *)&indir_tbl->entry[i - 3];
635 			*temp = cpu_to_be32(*temp);
636 		}
637 	}
638 
639 	/* cfg the rss indirect table by command queue */
640 	indir_size = HINIC_RSS_INDIR_SIZE / 2;
641 	indir_tbl->offset = 0;
642 	indir_tbl->size = cpu_to_be32(indir_size);
643 
644 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
645 				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
646 				     &cmd_buf, &out_param);
647 	if (err || out_param != 0) {
648 		dev_err(&pdev->dev, "Failed to set rss indir table\n");
649 		err = -EFAULT;
650 		goto free_buf;
651 	}
652 
653 	indir_tbl->offset = cpu_to_be32(indir_size);
654 	indir_tbl->size = cpu_to_be32(indir_size);
655 	memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
656 
657 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
658 				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
659 				     &cmd_buf, &out_param);
660 	if (err || out_param != 0) {
661 		dev_err(&pdev->dev, "Failed to set rss indir table\n");
662 		err = -EFAULT;
663 	}
664 
665 free_buf:
666 	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
667 
668 	return err;
669 }
670 
671 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
672 			    u32 *indir_table)
673 {
674 	struct hinic_rss_indir_table rss_cfg = { 0 };
675 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
676 	struct hinic_hwif *hwif = hwdev->hwif;
677 	struct pci_dev *pdev = hwif->pdev;
678 	u16 out_size = sizeof(rss_cfg);
679 	int err = 0, i;
680 
681 	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
682 	rss_cfg.template_id = tmpl_idx;
683 
684 	err = hinic_port_msg_cmd(hwdev,
685 				 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
686 				 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
687 				 &out_size);
688 	if (err || !out_size || rss_cfg.status) {
689 		dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
690 			err, rss_cfg.status, out_size);
691 		return -EINVAL;
692 	}
693 
694 	hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
695 	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
696 		indir_table[i] = rss_cfg.indir[i];
697 
698 	return 0;
699 }
700 
701 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
702 		       struct hinic_rss_type rss_type)
703 {
704 	struct hinic_rss_context_tbl *ctx_tbl;
705 	struct hinic_func_to_io *func_to_io;
706 	struct hinic_cmdq_buf cmd_buf;
707 	struct hinic_hwdev *hwdev;
708 	struct hinic_hwif *hwif;
709 	struct pci_dev *pdev;
710 	u64 out_param;
711 	u32 ctx = 0;
712 	int err;
713 
714 	hwdev = nic_dev->hwdev;
715 	func_to_io = &hwdev->func_to_io;
716 	hwif = hwdev->hwif;
717 	pdev = hwif->pdev;
718 
719 	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
720 	if (err) {
721 		dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
722 		return -ENOMEM;
723 	}
724 
725 	ctx |=  HINIC_RSS_TYPE_SET(1, VALID) |
726 		HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
727 		HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
728 		HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
729 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
730 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
731 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
732 		HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
733 		HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
734 
735 	cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
736 
737 	ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
738 	ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
739 	ctx_tbl->offset = 0;
740 	ctx_tbl->size = sizeof(u32);
741 	ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
742 	ctx_tbl->rsvd = 0;
743 	ctx_tbl->ctx = cpu_to_be32(ctx);
744 
745 	/* cfg the rss context table by command queue */
746 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
747 				     HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
748 				     &cmd_buf, &out_param);
749 
750 	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
751 
752 	if (err || out_param != 0) {
753 		dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
754 			err);
755 		return -EFAULT;
756 	}
757 
758 	return 0;
759 }
760 
761 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
762 		       struct hinic_rss_type *rss_type)
763 {
764 	struct hinic_rss_context_table ctx_tbl = { 0 };
765 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
766 	u16 out_size = sizeof(ctx_tbl);
767 	struct hinic_hwif *hwif;
768 	struct pci_dev *pdev;
769 	int err;
770 
771 	if (!hwdev || !rss_type)
772 		return -EINVAL;
773 
774 	hwif = hwdev->hwif;
775 	pdev = hwif->pdev;
776 
777 	ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
778 	ctx_tbl.template_id = tmpl_idx;
779 
780 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
781 				 &ctx_tbl, sizeof(ctx_tbl),
782 				 &ctx_tbl, &out_size);
783 	if (err || !out_size || ctx_tbl.status) {
784 		dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
785 			err, ctx_tbl.status, out_size);
786 		return -EINVAL;
787 	}
788 
789 	rss_type->ipv4          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
790 	rss_type->ipv6          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
791 	rss_type->ipv6_ext      = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
792 	rss_type->tcp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
793 	rss_type->tcp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
794 	rss_type->tcp_ipv6_ext  = HINIC_RSS_TYPE_GET(ctx_tbl.context,
795 						     TCP_IPV6_EXT);
796 	rss_type->udp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
797 	rss_type->udp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
798 
799 	return 0;
800 }
801 
802 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
803 			       const u8 *temp)
804 {
805 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
806 	struct hinic_hwif *hwif = hwdev->hwif;
807 	struct hinic_rss_key rss_key = { 0 };
808 	struct pci_dev *pdev = hwif->pdev;
809 	u16 out_size = sizeof(rss_key);
810 	int err;
811 
812 	rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
813 	rss_key.template_id = template_id;
814 	memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
815 
816 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
817 				 &rss_key, sizeof(rss_key),
818 				 &rss_key, &out_size);
819 	if (err || !out_size || rss_key.status) {
820 		dev_err(&pdev->dev,
821 			"Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
822 			err, rss_key.status, out_size);
823 		return -EINVAL;
824 	}
825 
826 	return 0;
827 }
828 
829 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
830 			       u8 *temp)
831 {
832 	struct hinic_rss_template_key temp_key = { 0 };
833 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
834 	u16 out_size = sizeof(temp_key);
835 	struct hinic_hwif *hwif;
836 	struct pci_dev *pdev;
837 	int err;
838 
839 	if (!hwdev || !temp)
840 		return -EINVAL;
841 
842 	hwif = hwdev->hwif;
843 	pdev = hwif->pdev;
844 
845 	temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
846 	temp_key.template_id = tmpl_idx;
847 
848 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
849 				 &temp_key, sizeof(temp_key),
850 				 &temp_key, &out_size);
851 	if (err || !out_size || temp_key.status) {
852 		dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
853 			err, temp_key.status, out_size);
854 		return -EINVAL;
855 	}
856 
857 	memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
858 
859 	return 0;
860 }
861 
862 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
863 			      u8 type)
864 {
865 	struct hinic_rss_engine_type rss_engine = { 0 };
866 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
867 	struct hinic_hwif *hwif = hwdev->hwif;
868 	struct pci_dev *pdev = hwif->pdev;
869 	u16 out_size = sizeof(rss_engine);
870 	int err;
871 
872 	rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
873 	rss_engine.hash_engine = type;
874 	rss_engine.template_id = template_id;
875 
876 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
877 				 &rss_engine, sizeof(rss_engine),
878 				 &rss_engine, &out_size);
879 	if (err || !out_size || rss_engine.status) {
880 		dev_err(&pdev->dev,
881 			"Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
882 			err, rss_engine.status, out_size);
883 		return -EINVAL;
884 	}
885 
886 	return 0;
887 }
888 
889 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
890 {
891 	struct hinic_rss_engine_type hash_type = { 0 };
892 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
893 	u16 out_size = sizeof(hash_type);
894 	struct hinic_hwif *hwif;
895 	struct pci_dev *pdev;
896 	int err;
897 
898 	if (!hwdev || !type)
899 		return -EINVAL;
900 
901 	hwif = hwdev->hwif;
902 	pdev = hwif->pdev;
903 
904 	hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
905 	hash_type.template_id = tmpl_idx;
906 
907 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
908 				 &hash_type, sizeof(hash_type),
909 				 &hash_type, &out_size);
910 	if (err || !out_size || hash_type.status) {
911 		dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
912 			err, hash_type.status, out_size);
913 		return -EINVAL;
914 	}
915 
916 	*type = hash_type.hash_engine;
917 	return 0;
918 }
919 
920 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
921 {
922 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
923 	struct hinic_rss_config rss_cfg = { 0 };
924 	struct hinic_hwif *hwif = hwdev->hwif;
925 	struct pci_dev *pdev = hwif->pdev;
926 	u16 out_size = sizeof(rss_cfg);
927 	int err;
928 
929 	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
930 	rss_cfg.rss_en = rss_en;
931 	rss_cfg.template_id = template_id;
932 	rss_cfg.rq_priority_number = 0;
933 
934 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
935 				 &rss_cfg, sizeof(rss_cfg),
936 				 &rss_cfg, &out_size);
937 	if (err || !out_size || rss_cfg.status) {
938 		dev_err(&pdev->dev,
939 			"Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
940 			err, rss_cfg.status, out_size);
941 		return -EINVAL;
942 	}
943 
944 	return 0;
945 }
946 
947 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
948 {
949 	struct hinic_rss_template_mgmt template_mgmt = { 0 };
950 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
951 	struct hinic_hwif *hwif = hwdev->hwif;
952 	u16 out_size = sizeof(template_mgmt);
953 	struct pci_dev *pdev = hwif->pdev;
954 	int err;
955 
956 	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
957 	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
958 
959 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
960 				 &template_mgmt, sizeof(template_mgmt),
961 				 &template_mgmt, &out_size);
962 	if (err || !out_size || template_mgmt.status) {
963 		dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
964 			err, template_mgmt.status, out_size);
965 		return -EINVAL;
966 	}
967 
968 	*tmpl_idx = template_mgmt.template_id;
969 
970 	return 0;
971 }
972 
973 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
974 {
975 	struct hinic_rss_template_mgmt template_mgmt = { 0 };
976 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
977 	struct hinic_hwif *hwif = hwdev->hwif;
978 	u16 out_size = sizeof(template_mgmt);
979 	struct pci_dev *pdev = hwif->pdev;
980 	int err;
981 
982 	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
983 	template_mgmt.template_id = tmpl_idx;
984 	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
985 
986 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
987 				 &template_mgmt, sizeof(template_mgmt),
988 				 &template_mgmt, &out_size);
989 	if (err || !out_size || template_mgmt.status) {
990 		dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
991 			err, template_mgmt.status, out_size);
992 		return -EINVAL;
993 	}
994 
995 	return 0;
996 }
997 
998 int hinic_get_vport_stats(struct hinic_dev *nic_dev,
999 			  struct hinic_vport_stats *stats)
1000 {
1001 	struct hinic_cmd_vport_stats vport_stats = { 0 };
1002 	struct hinic_port_stats_info stats_info = { 0 };
1003 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
1004 	struct hinic_hwif *hwif = hwdev->hwif;
1005 	u16 out_size = sizeof(vport_stats);
1006 	struct pci_dev *pdev = hwif->pdev;
1007 	int err;
1008 
1009 	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1010 	stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
1011 	stats_info.stats_size = sizeof(vport_stats);
1012 
1013 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
1014 				 &stats_info, sizeof(stats_info),
1015 				 &vport_stats, &out_size);
1016 	if (err || !out_size || vport_stats.status) {
1017 		dev_err(&pdev->dev,
1018 			"Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1019 			err, vport_stats.status, out_size);
1020 		return -EFAULT;
1021 	}
1022 
1023 	memcpy(stats, &vport_stats.stats, sizeof(*stats));
1024 	return 0;
1025 }
1026 
1027 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1028 			     struct hinic_phy_port_stats *stats)
1029 {
1030 	struct hinic_port_stats_info stats_info = { 0 };
1031 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
1032 	struct hinic_hwif *hwif = hwdev->hwif;
1033 	struct hinic_port_stats *port_stats;
1034 	u16 out_size = sizeof(*port_stats);
1035 	struct pci_dev *pdev = hwif->pdev;
1036 	int err;
1037 
1038 	port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1039 	if (!port_stats)
1040 		return -ENOMEM;
1041 
1042 	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1043 	stats_info.stats_size = sizeof(*port_stats);
1044 
1045 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
1046 				 &stats_info, sizeof(stats_info),
1047 				 port_stats, &out_size);
1048 	if (err || !out_size || port_stats->status) {
1049 		dev_err(&pdev->dev,
1050 			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1051 			err, port_stats->status, out_size);
1052 		err = -EINVAL;
1053 		goto out;
1054 	}
1055 
1056 	memcpy(stats, &port_stats->stats, sizeof(*stats));
1057 
1058 out:
1059 	kfree(port_stats);
1060 
1061 	return err;
1062 }
1063 
1064 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1065 {
1066 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
1067 	struct hinic_version_info up_ver = {0};
1068 	u16 out_size = sizeof(up_ver);
1069 	struct hinic_hwif *hwif;
1070 	struct pci_dev *pdev;
1071 	int err;
1072 
1073 	if (!hwdev)
1074 		return -EINVAL;
1075 
1076 	hwif = hwdev->hwif;
1077 	pdev = hwif->pdev;
1078 
1079 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1080 				 &up_ver, sizeof(up_ver), &up_ver,
1081 				 &out_size);
1082 	if (err || !out_size || up_ver.status) {
1083 		dev_err(&pdev->dev,
1084 			"Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1085 			err, up_ver.status, out_size);
1086 		return -EINVAL;
1087 	}
1088 
1089 	snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1090 
1091 	return 0;
1092 }
1093 
1094 int hinic_get_link_mode(struct hinic_hwdev *hwdev,
1095 			struct hinic_link_mode_cmd *link_mode)
1096 {
1097 	u16 out_size;
1098 	int err;
1099 
1100 	if (!hwdev || !link_mode)
1101 		return -EINVAL;
1102 
1103 	link_mode->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1104 	out_size = sizeof(*link_mode);
1105 
1106 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
1107 				 link_mode, sizeof(*link_mode),
1108 				 link_mode, &out_size);
1109 	if (err || !out_size || link_mode->status) {
1110 		dev_err(&hwdev->hwif->pdev->dev,
1111 			"Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x\n",
1112 			err, link_mode->status, out_size);
1113 		return -EIO;
1114 	}
1115 
1116 	return 0;
1117 }
1118 
1119 int hinic_set_autoneg(struct hinic_hwdev *hwdev, bool enable)
1120 {
1121 	struct hinic_set_autoneg_cmd autoneg = {0};
1122 	u16 out_size = sizeof(autoneg);
1123 	int err;
1124 
1125 	if (!hwdev)
1126 		return -EINVAL;
1127 
1128 	autoneg.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1129 	autoneg.enable = enable;
1130 
1131 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_AUTONEG,
1132 				 &autoneg, sizeof(autoneg),
1133 				 &autoneg, &out_size);
1134 	if (err || !out_size || autoneg.status) {
1135 		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s autoneg, err: %d, status: 0x%x, out size: 0x%x\n",
1136 			enable ? "enable" : "disable", err, autoneg.status,
1137 			out_size);
1138 		return -EIO;
1139 	}
1140 
1141 	return 0;
1142 }
1143 
1144 int hinic_set_speed(struct hinic_hwdev *hwdev, enum nic_speed_level speed)
1145 {
1146 	struct hinic_speed_cmd speed_info = {0};
1147 	u16 out_size = sizeof(speed_info);
1148 	int err;
1149 
1150 	if (!hwdev)
1151 		return -EINVAL;
1152 
1153 	speed_info.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1154 	speed_info.speed = speed;
1155 
1156 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_SPEED,
1157 				 &speed_info, sizeof(speed_info),
1158 				 &speed_info, &out_size);
1159 	if (err || !out_size || speed_info.status) {
1160 		dev_err(&hwdev->hwif->pdev->dev,
1161 			"Failed to set speed, err: %d, status: 0x%x, out size: 0x%x\n",
1162 			err, speed_info.status, out_size);
1163 		return -EIO;
1164 	}
1165 
1166 	return 0;
1167 }
1168 
1169 int hinic_set_link_settings(struct hinic_hwdev *hwdev,
1170 			    struct hinic_link_ksettings_info *info)
1171 {
1172 	u16 out_size = sizeof(*info);
1173 	int err;
1174 
1175 	err = hinic_hilink_msg_cmd(hwdev, HINIC_HILINK_CMD_SET_LINK_SETTINGS,
1176 				   info, sizeof(*info), info, &out_size);
1177 	if ((info->status != HINIC_MGMT_CMD_UNSUPPORTED &&
1178 	     info->status) || err || !out_size) {
1179 		dev_err(&hwdev->hwif->pdev->dev,
1180 			"Failed to set link settings, err: %d, status: 0x%x, out size: 0x%x\n",
1181 			err, info->status, out_size);
1182 		return -EFAULT;
1183 	}
1184 
1185 	return info->status;
1186 }
1187 
1188 int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
1189 			    struct hinic_pause_config *pause_info)
1190 {
1191 	u16 out_size = sizeof(*pause_info);
1192 	int err;
1193 
1194 	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1195 
1196 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
1197 				 pause_info, sizeof(*pause_info),
1198 				 pause_info, &out_size);
1199 	if (err || !out_size || pause_info->status) {
1200 		dev_err(&hwdev->hwif->pdev->dev, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
1201 			err, pause_info->status, out_size);
1202 		return -EIO;
1203 	}
1204 
1205 	return 0;
1206 }
1207 
1208 int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
1209 			    struct hinic_pause_config *pause_info)
1210 {
1211 	u16 out_size = sizeof(*pause_info);
1212 	int err;
1213 
1214 	pause_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1215 
1216 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
1217 				 pause_info, sizeof(*pause_info),
1218 				 pause_info, &out_size);
1219 	if (err || !out_size || pause_info->status) {
1220 		dev_err(&hwdev->hwif->pdev->dev, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x\n",
1221 			err, pause_info->status, out_size);
1222 		return -EIO;
1223 	}
1224 
1225 	return 0;
1226 }
1227 
1228 int hinic_dcb_set_pfc(struct hinic_hwdev *hwdev, u8 pfc_en, u8 pfc_bitmap)
1229 {
1230 	struct hinic_nic_cfg *nic_cfg = &hwdev->func_to_io.nic_cfg;
1231 	struct hinic_set_pfc pfc = {0};
1232 	u16 out_size = sizeof(pfc);
1233 	int err;
1234 
1235 	if (HINIC_IS_VF(hwdev->hwif))
1236 		return 0;
1237 
1238 	mutex_lock(&nic_cfg->cfg_mutex);
1239 
1240 	pfc.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
1241 	pfc.pfc_bitmap = pfc_bitmap;
1242 	pfc.pfc_en = pfc_en;
1243 
1244 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_PFC,
1245 				 &pfc, sizeof(pfc), &pfc, &out_size);
1246 	if (err || pfc.status || !out_size) {
1247 		dev_err(&hwdev->hwif->pdev->dev, "Failed to %s pfc, err: %d, status: 0x%x, out size: 0x%x\n",
1248 			pfc_en ? "enable" : "disable", err, pfc.status,
1249 			out_size);
1250 		mutex_unlock(&nic_cfg->cfg_mutex);
1251 		return -EIO;
1252 	}
1253 
1254 	/* pause settings is opposite from pfc */
1255 	nic_cfg->rx_pause = pfc_en ? 0 : 1;
1256 	nic_cfg->tx_pause = pfc_en ? 0 : 1;
1257 
1258 	mutex_unlock(&nic_cfg->cfg_mutex);
1259 
1260 	return 0;
1261 }
1262 
1263 int hinic_set_loopback_mode(struct hinic_hwdev *hwdev, u32 mode, u32 enable)
1264 {
1265 	struct hinic_port_loopback lb = {0};
1266 	u16 out_size = sizeof(lb);
1267 	int err;
1268 
1269 	lb.mode = mode;
1270 	lb.en = enable;
1271 
1272 	if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
1273 		dev_err(&hwdev->hwif->pdev->dev,
1274 			"Invalid loopback mode %d to set\n", mode);
1275 		return -EINVAL;
1276 	}
1277 
1278 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LOOPBACK_MODE,
1279 				 &lb, sizeof(lb), &lb, &out_size);
1280 	if (err || !out_size || lb.status) {
1281 		dev_err(&hwdev->hwif->pdev->dev,
1282 			"Failed to set loopback mode %d en %d, err: %d, status: 0x%x, out size: 0x%x\n",
1283 			mode, enable, err, lb.status, out_size);
1284 		return -EIO;
1285 	}
1286 
1287 	return 0;
1288 }
1289 
1290 static int _set_led_status(struct hinic_hwdev *hwdev, u8 port,
1291 			   enum hinic_led_type type,
1292 			   enum hinic_led_mode mode, u8 reset)
1293 {
1294 	struct hinic_led_info led_info = {0};
1295 	u16 out_size = sizeof(led_info);
1296 	struct hinic_pfhwdev *pfhwdev;
1297 	int err;
1298 
1299 	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
1300 
1301 	led_info.port = port;
1302 	led_info.reset = reset;
1303 
1304 	led_info.type = type;
1305 	led_info.mode = mode;
1306 
1307 	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
1308 				HINIC_COMM_CMD_SET_LED_STATUS,
1309 				&led_info, sizeof(led_info),
1310 				&led_info, &out_size, HINIC_MGMT_MSG_SYNC);
1311 	if (err || led_info.status || !out_size) {
1312 		dev_err(&hwdev->hwif->pdev->dev, "Failed to set led status, err: %d, status: 0x%x, out size: 0x%x\n",
1313 			err, led_info.status, out_size);
1314 		return -EIO;
1315 	}
1316 
1317 	return 0;
1318 }
1319 
1320 int hinic_set_led_status(struct hinic_hwdev *hwdev, u8 port,
1321 			 enum hinic_led_type type, enum hinic_led_mode mode)
1322 {
1323 	if (!hwdev)
1324 		return -EINVAL;
1325 
1326 	return _set_led_status(hwdev, port, type, mode, 0);
1327 }
1328 
1329 int hinic_reset_led_status(struct hinic_hwdev *hwdev, u8 port)
1330 {
1331 	int err;
1332 
1333 	if (!hwdev)
1334 		return -EINVAL;
1335 
1336 	err = _set_led_status(hwdev, port, HINIC_LED_TYPE_INVALID,
1337 			      HINIC_LED_MODE_INVALID, 1);
1338 	if (err)
1339 		dev_err(&hwdev->hwif->pdev->dev,
1340 			"Failed to reset led status\n");
1341 
1342 	return err;
1343 }
1344 
1345 static bool hinic_if_sfp_absent(struct hinic_hwdev *hwdev)
1346 {
1347 	struct hinic_cmd_get_light_module_abs sfp_abs = {0};
1348 	u16 out_size = sizeof(sfp_abs);
1349 	u8 port_id = hwdev->port_id;
1350 	int err;
1351 
1352 	sfp_abs.port_id = port_id;
1353 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_SFP_ABS,
1354 				 &sfp_abs, sizeof(sfp_abs), &sfp_abs,
1355 				 &out_size);
1356 	if (sfp_abs.status || err || !out_size) {
1357 		dev_err(&hwdev->hwif->pdev->dev,
1358 			"Failed to get port%d sfp absent status, err: %d, status: 0x%x, out size: 0x%x\n",
1359 			port_id, err, sfp_abs.status, out_size);
1360 		return true;
1361 	}
1362 
1363 	return ((sfp_abs.abs_status == 0) ? false : true);
1364 }
1365 
1366 int hinic_get_sfp_eeprom(struct hinic_hwdev *hwdev, u8 *data, u16 *len)
1367 {
1368 	struct hinic_cmd_get_std_sfp_info sfp_info = {0};
1369 	u16 out_size = sizeof(sfp_info);
1370 	u8 port_id;
1371 	int err;
1372 
1373 	if (!hwdev || !data || !len)
1374 		return -EINVAL;
1375 
1376 	port_id = hwdev->port_id;
1377 
1378 	if (hinic_if_sfp_absent(hwdev))
1379 		return -ENXIO;
1380 
1381 	sfp_info.port_id = port_id;
1382 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_STD_SFP_INFO,
1383 				 &sfp_info, sizeof(sfp_info), &sfp_info,
1384 				 &out_size);
1385 	if (sfp_info.status || err || !out_size) {
1386 		dev_err(&hwdev->hwif->pdev->dev,
1387 			"Failed to get port%d sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
1388 			port_id, err, sfp_info.status, out_size);
1389 		return -EIO;
1390 	}
1391 
1392 	*len = min_t(u16, sfp_info.eeprom_len, STD_SFP_INFO_MAX_SIZE);
1393 	memcpy(data, sfp_info.sfp_info, STD_SFP_INFO_MAX_SIZE);
1394 
1395 	return 0;
1396 }
1397 
1398 int hinic_get_sfp_type(struct hinic_hwdev *hwdev, u8 *data0, u8 *data1)
1399 {
1400 	u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
1401 	u16 len;
1402 	int err;
1403 
1404 	if (hinic_if_sfp_absent(hwdev))
1405 		return -ENXIO;
1406 
1407 	err = hinic_get_sfp_eeprom(hwdev, sfp_data, &len);
1408 	if (err)
1409 		return err;
1410 
1411 	*data0 = sfp_data[0];
1412 	*data1 = sfp_data[1];
1413 
1414 	return 0;
1415 }
1416