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