Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / huawei / hinic / hinic_port.c
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 }