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 net_device *netdev = nic_dev->netdev;
41 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
42 	struct hinic_port_mac_cmd port_mac_cmd;
43 	struct hinic_hwif *hwif = hwdev->hwif;
44 	struct pci_dev *pdev = hwif->pdev;
45 	enum hinic_port_cmd cmd;
46 	u16 out_size;
47 	int err;
48 
49 	if (vlan_id >= VLAN_N_VID) {
50 		netif_err(nic_dev, drv, netdev, "Invalid VLAN number\n");
51 		return -EINVAL;
52 	}
53 
54 	if (op == MAC_SET)
55 		cmd = HINIC_PORT_CMD_SET_MAC;
56 	else
57 		cmd = HINIC_PORT_CMD_DEL_MAC;
58 
59 	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
60 	port_mac_cmd.vlan_id = vlan_id;
61 	memcpy(port_mac_cmd.mac, addr, ETH_ALEN);
62 
63 	err = hinic_port_msg_cmd(hwdev, cmd, &port_mac_cmd,
64 				 sizeof(port_mac_cmd),
65 				 &port_mac_cmd, &out_size);
66 	if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
67 		dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n",
68 			port_mac_cmd.status);
69 		return -EFAULT;
70 	}
71 
72 	return 0;
73 }
74 
75 /**
76  * hinic_port_add_mac - add mac address
77  * @nic_dev: nic device
78  * @addr: mac address
79  * @vlan_id: vlan number to set with the mac
80  *
81  * Return 0 - Success, negative - Failure
82  **/
83 int hinic_port_add_mac(struct hinic_dev *nic_dev,
84 		       const u8 *addr, u16 vlan_id)
85 {
86 	return change_mac(nic_dev, addr, vlan_id, MAC_SET);
87 }
88 
89 /**
90  * hinic_port_del_mac - remove mac address
91  * @nic_dev: nic device
92  * @addr: mac address
93  * @vlan_id: vlan number that is connected to the mac
94  *
95  * Return 0 - Success, negative - Failure
96  **/
97 int hinic_port_del_mac(struct hinic_dev *nic_dev, const u8 *addr,
98 		       u16 vlan_id)
99 {
100 	return change_mac(nic_dev, addr, vlan_id, MAC_DEL);
101 }
102 
103 /**
104  * hinic_port_get_mac - get the mac address of the nic device
105  * @nic_dev: nic device
106  * @addr: returned mac address
107  *
108  * Return 0 - Success, negative - Failure
109  **/
110 int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
111 {
112 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
113 	struct hinic_port_mac_cmd port_mac_cmd;
114 	struct hinic_hwif *hwif = hwdev->hwif;
115 	struct pci_dev *pdev = hwif->pdev;
116 	u16 out_size;
117 	int err;
118 
119 	port_mac_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
120 
121 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MAC,
122 				 &port_mac_cmd, sizeof(port_mac_cmd),
123 				 &port_mac_cmd, &out_size);
124 	if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
125 		dev_err(&pdev->dev, "Failed to get mac, ret = %d\n",
126 			port_mac_cmd.status);
127 		return -EFAULT;
128 	}
129 
130 	memcpy(addr, port_mac_cmd.mac, ETH_ALEN);
131 	return 0;
132 }
133 
134 /**
135  * hinic_port_set_mtu - set mtu
136  * @nic_dev: nic device
137  * @new_mtu: new mtu
138  *
139  * Return 0 - Success, negative - Failure
140  **/
141 int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
142 {
143 	struct net_device *netdev = nic_dev->netdev;
144 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
145 	struct hinic_port_mtu_cmd port_mtu_cmd;
146 	struct hinic_hwif *hwif = hwdev->hwif;
147 	struct pci_dev *pdev = hwif->pdev;
148 	int err, max_frame;
149 	u16 out_size;
150 
151 	if (new_mtu < HINIC_MIN_MTU_SIZE) {
152 		netif_err(nic_dev, drv, netdev, "mtu < MIN MTU size");
153 		return -EINVAL;
154 	}
155 
156 	max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
157 	if (max_frame > HINIC_MAX_JUMBO_FRAME_SIZE) {
158 		netif_err(nic_dev, drv, netdev, "mtu > MAX MTU size");
159 		return -EINVAL;
160 	}
161 
162 	port_mtu_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
163 	port_mtu_cmd.mtu = new_mtu;
164 
165 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
166 				 &port_mtu_cmd, sizeof(port_mtu_cmd),
167 				 &port_mtu_cmd, &out_size);
168 	if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) {
169 		dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n",
170 			port_mtu_cmd.status);
171 		return -EFAULT;
172 	}
173 
174 	return 0;
175 }
176 
177 /**
178  * hinic_port_add_vlan - add vlan to the nic device
179  * @nic_dev: nic device
180  * @vlan_id: the vlan number to add
181  *
182  * Return 0 - Success, negative - Failure
183  **/
184 int hinic_port_add_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
185 {
186 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
187 	struct hinic_port_vlan_cmd port_vlan_cmd;
188 
189 	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
190 	port_vlan_cmd.vlan_id = vlan_id;
191 
192 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_ADD_VLAN,
193 				  &port_vlan_cmd, sizeof(port_vlan_cmd),
194 				  NULL, NULL);
195 }
196 
197 /**
198  * hinic_port_del_vlan - delete vlan from the nic device
199  * @nic_dev: nic device
200  * @vlan_id: the vlan number to delete
201  *
202  * Return 0 - Success, negative - Failure
203  **/
204 int hinic_port_del_vlan(struct hinic_dev *nic_dev, u16 vlan_id)
205 {
206 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
207 	struct hinic_port_vlan_cmd port_vlan_cmd;
208 
209 	port_vlan_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
210 	port_vlan_cmd.vlan_id = vlan_id;
211 
212 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_DEL_VLAN,
213 				 &port_vlan_cmd, sizeof(port_vlan_cmd),
214 				 NULL, NULL);
215 }
216 
217 /**
218  * hinic_port_set_rx_mode - set rx mode in the nic device
219  * @nic_dev: nic device
220  * @rx_mode: the rx mode to set
221  *
222  * Return 0 - Success, negative - Failure
223  **/
224 int hinic_port_set_rx_mode(struct hinic_dev *nic_dev, u32 rx_mode)
225 {
226 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
227 	struct hinic_port_rx_mode_cmd rx_mode_cmd;
228 
229 	rx_mode_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
230 	rx_mode_cmd.rx_mode = rx_mode;
231 
232 	return hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
233 				  &rx_mode_cmd, sizeof(rx_mode_cmd),
234 				  NULL, NULL);
235 }
236 
237 /**
238  * hinic_port_link_state - get the link state
239  * @nic_dev: nic device
240  * @link_state: the returned link state
241  *
242  * Return 0 - Success, negative - Failure
243  **/
244 int hinic_port_link_state(struct hinic_dev *nic_dev,
245 			  enum hinic_port_link_state *link_state)
246 {
247 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
248 	struct hinic_hwif *hwif = hwdev->hwif;
249 	struct hinic_port_link_cmd link_cmd;
250 	struct pci_dev *pdev = hwif->pdev;
251 	u16 out_size;
252 	int err;
253 
254 	if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
255 		dev_err(&pdev->dev, "unsupported PCI Function type\n");
256 		return -EINVAL;
257 	}
258 
259 	link_cmd.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
260 
261 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
262 				 &link_cmd, sizeof(link_cmd),
263 				 &link_cmd, &out_size);
264 	if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
265 		dev_err(&pdev->dev, "Failed to get link state, ret = %d\n",
266 			link_cmd.status);
267 		return -EINVAL;
268 	}
269 
270 	*link_state = link_cmd.state;
271 	return 0;
272 }
273 
274 /**
275  * hinic_port_set_state - set port state
276  * @nic_dev: nic device
277  * @state: the state to set
278  *
279  * Return 0 - Success, negative - Failure
280  **/
281 int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
282 {
283 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
284 	struct hinic_port_state_cmd port_state;
285 	struct hinic_hwif *hwif = hwdev->hwif;
286 	struct pci_dev *pdev = hwif->pdev;
287 	u16 out_size;
288 	int err;
289 
290 	if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
291 		dev_err(&pdev->dev, "unsupported PCI Function type\n");
292 		return -EINVAL;
293 	}
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, ret = %d\n",
302 			port_state.status);
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;
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, ret = %d\n",
334 			func_state.status);
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;
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, ret = %d\n",
365 			port_cap->status);
366 		return -EINVAL;
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;
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, ret = %d\n",
397 			tso_cfg.status);
398 		return -EINVAL;
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 	struct hinic_hwif *hwif;
409 	struct pci_dev *pdev;
410 	u16 out_size;
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, ret = %d\n",
427 			rx_csum_cfg.status);
428 		return -EINVAL;
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 	hwif = hwdev->hwif;
447 	pdev = hwif->pdev;
448 	vlan_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
449 	vlan_cfg.vlan_rx_offload = en;
450 
451 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
452 				 &vlan_cfg, sizeof(vlan_cfg),
453 				 &vlan_cfg, &out_size);
454 	if (err || !out_size || vlan_cfg.status) {
455 		dev_err(&pdev->dev,
456 			"Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x\n",
457 			err, vlan_cfg.status, out_size);
458 		return -EINVAL;
459 	}
460 
461 	return 0;
462 }
463 
464 int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
465 {
466 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
467 	struct hinic_hwif *hwif = hwdev->hwif;
468 	struct pci_dev *pdev = hwif->pdev;
469 	struct hinic_rq_num rq_num = { 0 };
470 	u16 out_size = sizeof(rq_num);
471 	int err;
472 
473 	rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
474 	rq_num.num_rqs = num_rqs;
475 	rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH);
476 
477 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
478 				 &rq_num, sizeof(rq_num),
479 				 &rq_num, &out_size);
480 	if (err || !out_size || rq_num.status) {
481 		dev_err(&pdev->dev,
482 			"Failed to rxq number, ret = %d\n",
483 			rq_num.status);
484 		return -EINVAL;
485 	}
486 
487 	return 0;
488 }
489 
490 static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
491 			    u8 max_wqe_num)
492 {
493 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
494 	struct hinic_hwif *hwif = hwdev->hwif;
495 	struct hinic_lro_config lro_cfg = { 0 };
496 	struct pci_dev *pdev = hwif->pdev;
497 	u16 out_size = sizeof(lro_cfg);
498 	int err;
499 
500 	lro_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
501 	lro_cfg.lro_ipv4_en = ipv4_en;
502 	lro_cfg.lro_ipv6_en = ipv6_en;
503 	lro_cfg.lro_max_wqe_num = max_wqe_num;
504 
505 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO,
506 				 &lro_cfg, sizeof(lro_cfg),
507 				 &lro_cfg, &out_size);
508 	if (err || !out_size || lro_cfg.status) {
509 		dev_err(&pdev->dev,
510 			"Failed to set lro offload, ret = %d\n",
511 			lro_cfg.status);
512 		return -EINVAL;
513 	}
514 
515 	return 0;
516 }
517 
518 static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
519 {
520 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
521 	struct hinic_lro_timer lro_timer = { 0 };
522 	struct hinic_hwif *hwif = hwdev->hwif;
523 	struct pci_dev *pdev = hwif->pdev;
524 	u16 out_size = sizeof(lro_timer);
525 	int err;
526 
527 	lro_timer.status = 0;
528 	lro_timer.type = 0;
529 	lro_timer.enable = 1;
530 	lro_timer.timer = timer_value;
531 
532 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_LRO_TIMER,
533 				 &lro_timer, sizeof(lro_timer),
534 				 &lro_timer, &out_size);
535 	if (lro_timer.status == 0xFF) {
536 		/* For this case, we think status (0xFF) is OK */
537 		lro_timer.status = 0;
538 		dev_dbg(&pdev->dev,
539 			"Set lro timer not supported by the current FW version, it will be 1ms default\n");
540 	}
541 
542 	if (err || !out_size || lro_timer.status) {
543 		dev_err(&pdev->dev,
544 			"Failed to set lro timer, ret = %d\n",
545 			lro_timer.status);
546 
547 		return -EINVAL;
548 	}
549 
550 	return 0;
551 }
552 
553 int hinic_set_rx_lro_state(struct hinic_dev *nic_dev, u8 lro_en,
554 			   u32 lro_timer, u32 wqe_num)
555 {
556 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
557 	u8 ipv4_en;
558 	u8 ipv6_en;
559 	int err;
560 
561 	if (!hwdev)
562 		return -EINVAL;
563 
564 	ipv4_en = lro_en ? 1 : 0;
565 	ipv6_en = lro_en ? 1 : 0;
566 
567 	err = hinic_set_rx_lro(nic_dev, ipv4_en, ipv6_en, (u8)wqe_num);
568 	if (err)
569 		return err;
570 
571 	err = hinic_set_rx_lro_timer(nic_dev, lro_timer);
572 	if (err)
573 		return err;
574 
575 	return 0;
576 }
577 
578 int hinic_rss_set_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
579 			    const u32 *indir_table)
580 {
581 	struct hinic_rss_indirect_tbl *indir_tbl;
582 	struct hinic_func_to_io *func_to_io;
583 	struct hinic_cmdq_buf cmd_buf;
584 	struct hinic_hwdev *hwdev;
585 	struct hinic_hwif *hwif;
586 	struct pci_dev *pdev;
587 	u32 indir_size;
588 	u64 out_param;
589 	int err, i;
590 	u32 *temp;
591 
592 	hwdev = nic_dev->hwdev;
593 	func_to_io = &hwdev->func_to_io;
594 	hwif = hwdev->hwif;
595 	pdev = hwif->pdev;
596 
597 	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
598 	if (err) {
599 		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
600 		return err;
601 	}
602 
603 	cmd_buf.size = sizeof(*indir_tbl);
604 
605 	indir_tbl = cmd_buf.buf;
606 	indir_tbl->group_index = cpu_to_be32(tmpl_idx);
607 
608 	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
609 		indir_tbl->entry[i] = indir_table[i];
610 
611 		if (0x3 == (i & 0x3)) {
612 			temp = (u32 *)&indir_tbl->entry[i - 3];
613 			*temp = cpu_to_be32(*temp);
614 		}
615 	}
616 
617 	/* cfg the rss indirect table by command queue */
618 	indir_size = HINIC_RSS_INDIR_SIZE / 2;
619 	indir_tbl->offset = 0;
620 	indir_tbl->size = cpu_to_be32(indir_size);
621 
622 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
623 				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
624 				     &cmd_buf, &out_param);
625 	if (err || out_param != 0) {
626 		dev_err(&pdev->dev, "Failed to set rss indir table\n");
627 		err = -EFAULT;
628 		goto free_buf;
629 	}
630 
631 	indir_tbl->offset = cpu_to_be32(indir_size);
632 	indir_tbl->size = cpu_to_be32(indir_size);
633 	memcpy(&indir_tbl->entry[0], &indir_tbl->entry[indir_size], indir_size);
634 
635 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
636 				     HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
637 				     &cmd_buf, &out_param);
638 	if (err || out_param != 0) {
639 		dev_err(&pdev->dev, "Failed to set rss indir table\n");
640 		err = -EFAULT;
641 	}
642 
643 free_buf:
644 	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
645 
646 	return err;
647 }
648 
649 int hinic_rss_get_indir_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
650 			    u32 *indir_table)
651 {
652 	struct hinic_rss_indir_table rss_cfg = { 0 };
653 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
654 	struct hinic_hwif *hwif = hwdev->hwif;
655 	struct pci_dev *pdev = hwif->pdev;
656 	u16 out_size = sizeof(rss_cfg);
657 	int err = 0, i;
658 
659 	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
660 	rss_cfg.template_id = tmpl_idx;
661 
662 	err = hinic_port_msg_cmd(hwdev,
663 				 HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
664 				 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
665 				 &out_size);
666 	if (err || !out_size || rss_cfg.status) {
667 		dev_err(&pdev->dev, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x\n",
668 			err, rss_cfg.status, out_size);
669 		return -EINVAL;
670 	}
671 
672 	hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
673 	for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
674 		indir_table[i] = rss_cfg.indir[i];
675 
676 	return 0;
677 }
678 
679 int hinic_set_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
680 		       struct hinic_rss_type rss_type)
681 {
682 	struct hinic_rss_context_tbl *ctx_tbl;
683 	struct hinic_func_to_io *func_to_io;
684 	struct hinic_cmdq_buf cmd_buf;
685 	struct hinic_hwdev *hwdev;
686 	struct hinic_hwif *hwif;
687 	struct pci_dev *pdev;
688 	u64 out_param;
689 	u32 ctx = 0;
690 	int err;
691 
692 	hwdev = nic_dev->hwdev;
693 	func_to_io = &hwdev->func_to_io;
694 	hwif = hwdev->hwif;
695 	pdev = hwif->pdev;
696 
697 	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
698 	if (err) {
699 		dev_err(&pdev->dev, "Failed to allocate cmd buf\n");
700 		return -ENOMEM;
701 	}
702 
703 	ctx |=  HINIC_RSS_TYPE_SET(1, VALID) |
704 		HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
705 		HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
706 		HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
707 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
708 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
709 		HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
710 		HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
711 		HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
712 
713 	cmd_buf.size = sizeof(struct hinic_rss_context_tbl);
714 
715 	ctx_tbl = (struct hinic_rss_context_tbl *)cmd_buf.buf;
716 	ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
717 	ctx_tbl->offset = 0;
718 	ctx_tbl->size = sizeof(u32);
719 	ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
720 	ctx_tbl->rsvd = 0;
721 	ctx_tbl->ctx = cpu_to_be32(ctx);
722 
723 	/* cfg the rss context table by command queue */
724 	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
725 				     HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
726 				     &cmd_buf, &out_param);
727 
728 	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmd_buf);
729 
730 	if (err || out_param != 0) {
731 		dev_err(&pdev->dev, "Failed to set rss context table, err: %d\n",
732 			err);
733 		return -EFAULT;
734 	}
735 
736 	return 0;
737 }
738 
739 int hinic_get_rss_type(struct hinic_dev *nic_dev, u32 tmpl_idx,
740 		       struct hinic_rss_type *rss_type)
741 {
742 	struct hinic_rss_context_table ctx_tbl = { 0 };
743 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
744 	struct hinic_hwif *hwif;
745 	struct pci_dev *pdev;
746 	u16 out_size = sizeof(ctx_tbl);
747 	int err;
748 
749 	if (!hwdev || !rss_type)
750 		return -EINVAL;
751 
752 	hwif = hwdev->hwif;
753 	pdev = hwif->pdev;
754 
755 	ctx_tbl.func_id = HINIC_HWIF_FUNC_IDX(hwif);
756 	ctx_tbl.template_id = tmpl_idx;
757 
758 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
759 				 &ctx_tbl, sizeof(ctx_tbl),
760 				 &ctx_tbl, &out_size);
761 	if (err || !out_size || ctx_tbl.status) {
762 		dev_err(&pdev->dev, "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x\n",
763 			err, ctx_tbl.status, out_size);
764 		return -EINVAL;
765 	}
766 
767 	rss_type->ipv4          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
768 	rss_type->ipv6          = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
769 	rss_type->ipv6_ext      = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
770 	rss_type->tcp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
771 	rss_type->tcp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
772 	rss_type->tcp_ipv6_ext  = HINIC_RSS_TYPE_GET(ctx_tbl.context,
773 						     TCP_IPV6_EXT);
774 	rss_type->udp_ipv4      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
775 	rss_type->udp_ipv6      = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
776 
777 	return 0;
778 }
779 
780 int hinic_rss_set_template_tbl(struct hinic_dev *nic_dev, u32 template_id,
781 			       const u8 *temp)
782 {
783 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
784 	struct hinic_hwif *hwif = hwdev->hwif;
785 	struct hinic_rss_key rss_key = { 0 };
786 	struct pci_dev *pdev = hwif->pdev;
787 	u16 out_size;
788 	int err;
789 
790 	rss_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
791 	rss_key.template_id = template_id;
792 	memcpy(rss_key.key, temp, HINIC_RSS_KEY_SIZE);
793 
794 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
795 				 &rss_key, sizeof(rss_key),
796 				 &rss_key, &out_size);
797 	if (err || !out_size || rss_key.status) {
798 		dev_err(&pdev->dev,
799 			"Failed to set rss hash key, err: %d, status: 0x%x, out size: 0x%x\n",
800 			err, rss_key.status, out_size);
801 		return -EINVAL;
802 	}
803 
804 	return 0;
805 }
806 
807 int hinic_rss_get_template_tbl(struct hinic_dev *nic_dev, u32 tmpl_idx,
808 			       u8 *temp)
809 {
810 	struct hinic_rss_template_key temp_key = { 0 };
811 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
812 	struct hinic_hwif *hwif;
813 	struct pci_dev *pdev;
814 	u16 out_size = sizeof(temp_key);
815 	int err;
816 
817 	if (!hwdev || !temp)
818 		return -EINVAL;
819 
820 	hwif = hwdev->hwif;
821 	pdev = hwif->pdev;
822 
823 	temp_key.func_id = HINIC_HWIF_FUNC_IDX(hwif);
824 	temp_key.template_id = tmpl_idx;
825 
826 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
827 				 &temp_key, sizeof(temp_key),
828 				 &temp_key, &out_size);
829 	if (err || !out_size || temp_key.status) {
830 		dev_err(&pdev->dev, "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x\n",
831 			err, temp_key.status, out_size);
832 		return -EINVAL;
833 	}
834 
835 	memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
836 
837 	return 0;
838 }
839 
840 int hinic_rss_set_hash_engine(struct hinic_dev *nic_dev, u8 template_id,
841 			      u8 type)
842 {
843 	struct hinic_rss_engine_type rss_engine = { 0 };
844 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
845 	struct hinic_hwif *hwif = hwdev->hwif;
846 	struct pci_dev *pdev = hwif->pdev;
847 	u16 out_size;
848 	int err;
849 
850 	rss_engine.func_id = HINIC_HWIF_FUNC_IDX(hwif);
851 	rss_engine.hash_engine = type;
852 	rss_engine.template_id = template_id;
853 
854 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
855 				 &rss_engine, sizeof(rss_engine),
856 				 &rss_engine, &out_size);
857 	if (err || !out_size || rss_engine.status) {
858 		dev_err(&pdev->dev,
859 			"Failed to set hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
860 			err, rss_engine.status, out_size);
861 		return -EINVAL;
862 	}
863 
864 	return 0;
865 }
866 
867 int hinic_rss_get_hash_engine(struct hinic_dev *nic_dev, u8 tmpl_idx, u8 *type)
868 {
869 	struct hinic_rss_engine_type hash_type = { 0 };
870 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
871 	struct hinic_hwif *hwif;
872 	struct pci_dev *pdev;
873 	u16 out_size = sizeof(hash_type);
874 	int err;
875 
876 	if (!hwdev || !type)
877 		return -EINVAL;
878 
879 	hwif = hwdev->hwif;
880 	pdev = hwif->pdev;
881 
882 	hash_type.func_id = HINIC_HWIF_FUNC_IDX(hwif);
883 	hash_type.template_id = tmpl_idx;
884 
885 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_RSS_HASH_ENGINE,
886 				 &hash_type, sizeof(hash_type),
887 				 &hash_type, &out_size);
888 	if (err || !out_size || hash_type.status) {
889 		dev_err(&pdev->dev, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x\n",
890 			err, hash_type.status, out_size);
891 		return -EINVAL;
892 	}
893 
894 	*type = hash_type.hash_engine;
895 	return 0;
896 }
897 
898 int hinic_rss_cfg(struct hinic_dev *nic_dev, u8 rss_en, u8 template_id)
899 {
900 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
901 	struct hinic_rss_config rss_cfg = { 0 };
902 	struct hinic_hwif *hwif = hwdev->hwif;
903 	struct pci_dev *pdev = hwif->pdev;
904 	u16 out_size;
905 	int err;
906 
907 	rss_cfg.func_id = HINIC_HWIF_FUNC_IDX(hwif);
908 	rss_cfg.rss_en = rss_en;
909 	rss_cfg.template_id = template_id;
910 	rss_cfg.rq_priority_number = 0;
911 
912 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_CFG,
913 				 &rss_cfg, sizeof(rss_cfg),
914 				 &rss_cfg, &out_size);
915 	if (err || !out_size || rss_cfg.status) {
916 		dev_err(&pdev->dev,
917 			"Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x\n",
918 			err, rss_cfg.status, out_size);
919 		return -EINVAL;
920 	}
921 
922 	return 0;
923 }
924 
925 int hinic_rss_template_alloc(struct hinic_dev *nic_dev, u8 *tmpl_idx)
926 {
927 	struct hinic_rss_template_mgmt template_mgmt = { 0 };
928 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
929 	struct hinic_hwif *hwif = hwdev->hwif;
930 	struct pci_dev *pdev = hwif->pdev;
931 	u16 out_size;
932 	int err;
933 
934 	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
935 	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
936 
937 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
938 				 &template_mgmt, sizeof(template_mgmt),
939 				 &template_mgmt, &out_size);
940 	if (err || !out_size || template_mgmt.status) {
941 		dev_err(&pdev->dev, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x\n",
942 			err, template_mgmt.status, out_size);
943 		return -EINVAL;
944 	}
945 
946 	*tmpl_idx = template_mgmt.template_id;
947 
948 	return 0;
949 }
950 
951 int hinic_rss_template_free(struct hinic_dev *nic_dev, u8 tmpl_idx)
952 {
953 	struct hinic_rss_template_mgmt template_mgmt = { 0 };
954 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
955 	struct hinic_hwif *hwif = hwdev->hwif;
956 	struct pci_dev *pdev = hwif->pdev;
957 	u16 out_size;
958 	int err;
959 
960 	template_mgmt.func_id = HINIC_HWIF_FUNC_IDX(hwif);
961 	template_mgmt.template_id = tmpl_idx;
962 	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
963 
964 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
965 				 &template_mgmt, sizeof(template_mgmt),
966 				 &template_mgmt, &out_size);
967 	if (err || !out_size || template_mgmt.status) {
968 		dev_err(&pdev->dev, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x\n",
969 			err, template_mgmt.status, out_size);
970 		return -EINVAL;
971 	}
972 
973 	return 0;
974 }
975 
976 int hinic_get_vport_stats(struct hinic_dev *nic_dev,
977 			  struct hinic_vport_stats *stats)
978 {
979 	struct hinic_cmd_vport_stats vport_stats = { 0 };
980 	struct hinic_port_stats_info stats_info = { 0 };
981 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
982 	struct hinic_hwif *hwif = hwdev->hwif;
983 	u16 out_size = sizeof(vport_stats);
984 	struct pci_dev *pdev = hwif->pdev;
985 	int err;
986 
987 	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
988 	stats_info.func_id = HINIC_HWIF_FUNC_IDX(hwif);
989 	stats_info.stats_size = sizeof(vport_stats);
990 
991 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
992 				 &stats_info, sizeof(stats_info),
993 				 &vport_stats, &out_size);
994 	if (err || !out_size || vport_stats.status) {
995 		dev_err(&pdev->dev,
996 			"Failed to get function statistics, err: %d, status: 0x%x, out size: 0x%x\n",
997 			err, vport_stats.status, out_size);
998 		return -EFAULT;
999 	}
1000 
1001 	memcpy(stats, &vport_stats.stats, sizeof(*stats));
1002 	return 0;
1003 }
1004 
1005 int hinic_get_phy_port_stats(struct hinic_dev *nic_dev,
1006 			     struct hinic_phy_port_stats *stats)
1007 {
1008 	struct hinic_port_stats_info stats_info = { 0 };
1009 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
1010 	struct hinic_hwif *hwif = hwdev->hwif;
1011 	struct hinic_port_stats *port_stats;
1012 	u16 out_size = sizeof(*port_stats);
1013 	struct pci_dev *pdev = hwif->pdev;
1014 	int err;
1015 
1016 	port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1017 	if (!port_stats)
1018 		return -ENOMEM;
1019 
1020 	stats_info.stats_version = HINIC_PORT_STATS_VERSION;
1021 	stats_info.stats_size = sizeof(*port_stats);
1022 
1023 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
1024 				 &stats_info, sizeof(stats_info),
1025 				 port_stats, &out_size);
1026 	if (err || !out_size || port_stats->status) {
1027 		dev_err(&pdev->dev,
1028 			"Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
1029 			err, port_stats->status, out_size);
1030 		err = -EINVAL;
1031 		goto out;
1032 	}
1033 
1034 	memcpy(stats, &port_stats->stats, sizeof(*stats));
1035 
1036 out:
1037 	kfree(port_stats);
1038 
1039 	return err;
1040 }
1041 
1042 int hinic_get_mgmt_version(struct hinic_dev *nic_dev, u8 *mgmt_ver)
1043 {
1044 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
1045 	struct hinic_version_info up_ver = {0};
1046 	struct hinic_hwif *hwif;
1047 	struct pci_dev *pdev;
1048 	u16 out_size;
1049 	int err;
1050 
1051 	if (!hwdev)
1052 		return -EINVAL;
1053 
1054 	hwif = hwdev->hwif;
1055 	pdev = hwif->pdev;
1056 
1057 	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1058 				 &up_ver, sizeof(up_ver), &up_ver,
1059 				 &out_size);
1060 	if (err || !out_size || up_ver.status) {
1061 		dev_err(&pdev->dev,
1062 			"Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1063 			err, up_ver.status, out_size);
1064 		return -EINVAL;
1065 	}
1066 
1067 	snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver);
1068 
1069 	return 0;
1070 }
1071