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