forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Huawei HiNIC PCI Express Linux driver
34 * Copyright(c) 2017 Huawei Technologies Co., Ltd
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
- * for more details.
13
- *
145 */
156
167 #include <linux/kernel.h>
....@@ -24,7 +15,12 @@
2415 #include <linux/jiffies.h>
2516 #include <linux/log2.h>
2617 #include <linux/err.h>
18
+#include <linux/netdevice.h>
19
+#include <net/devlink.h>
2720
21
+#include "hinic_devlink.h"
22
+#include "hinic_sriov.h"
23
+#include "hinic_dev.h"
2824 #include "hinic_hw_if.h"
2925 #include "hinic_hw_eqs.h"
3026 #include "hinic_hw_mgmt.h"
....@@ -51,24 +47,6 @@
5147 IO_RUNNING = 1,
5248 };
5349
54
-enum hw_ioctxt_set_cmdq_depth {
55
- HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT,
56
-};
57
-
58
-/* HW struct */
59
-struct hinic_dev_cap {
60
- u8 status;
61
- u8 version;
62
- u8 rsvd0[6];
63
-
64
- u8 rsvd1[5];
65
- u8 intr_type;
66
- u8 rsvd2[66];
67
- u16 max_sqs;
68
- u16 max_rqs;
69
- u8 rsvd3[208];
70
-};
71
-
7250 /**
7351 * get_capability - convert device capabilities to NIC capabilities
7452 * @hwdev: the HW device to set and convert device capabilities for
....@@ -76,16 +54,13 @@
7654 *
7755 * Return 0 - Success, negative - Failure
7856 **/
79
-static int get_capability(struct hinic_hwdev *hwdev,
80
- struct hinic_dev_cap *dev_cap)
57
+static int parse_capability(struct hinic_hwdev *hwdev,
58
+ struct hinic_dev_cap *dev_cap)
8159 {
8260 struct hinic_cap *nic_cap = &hwdev->nic_cap;
8361 int num_aeqs, num_ceqs, num_irqs;
8462
85
- if (!HINIC_IS_PF(hwdev->hwif) && !HINIC_IS_PPF(hwdev->hwif))
86
- return -EINVAL;
87
-
88
- if (dev_cap->intr_type != INTR_MSIX_TYPE)
63
+ if (!HINIC_IS_VF(hwdev->hwif) && dev_cap->intr_type != INTR_MSIX_TYPE)
8964 return -EFAULT;
9065
9166 num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif);
....@@ -98,15 +73,20 @@
9873 if (nic_cap->num_qps > HINIC_Q_CTXT_MAX)
9974 nic_cap->num_qps = HINIC_Q_CTXT_MAX;
10075
101
- /* num_qps must be power of 2 */
102
- nic_cap->num_qps = BIT(fls(nic_cap->num_qps) - 1);
103
-
104
- nic_cap->max_qps = dev_cap->max_sqs + 1;
105
- if (nic_cap->max_qps != (dev_cap->max_rqs + 1))
106
- return -EFAULT;
76
+ if (!HINIC_IS_VF(hwdev->hwif))
77
+ nic_cap->max_qps = dev_cap->max_sqs + 1;
78
+ else
79
+ nic_cap->max_qps = dev_cap->max_sqs;
10780
10881 if (nic_cap->num_qps > nic_cap->max_qps)
10982 nic_cap->num_qps = nic_cap->max_qps;
83
+
84
+ if (!HINIC_IS_VF(hwdev->hwif)) {
85
+ nic_cap->max_vf = dev_cap->max_vf;
86
+ nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1;
87
+ }
88
+
89
+ hwdev->port_id = dev_cap->port_id;
11090
11191 return 0;
11292 }
....@@ -117,27 +97,26 @@
11797 *
11898 * Return 0 - Success, negative - Failure
11999 **/
120
-static int get_cap_from_fw(struct hinic_pfhwdev *pfhwdev)
100
+static int get_capability(struct hinic_pfhwdev *pfhwdev)
121101 {
122102 struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
123103 struct hinic_hwif *hwif = hwdev->hwif;
124104 struct pci_dev *pdev = hwif->pdev;
125105 struct hinic_dev_cap dev_cap;
126
- u16 in_len, out_len;
106
+ u16 out_len;
127107 int err;
128108
129
- in_len = 0;
130109 out_len = sizeof(dev_cap);
131110
132111 err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_CFGM,
133
- HINIC_CFG_NIC_CAP, &dev_cap, in_len, &dev_cap,
134
- &out_len, HINIC_MGMT_MSG_SYNC);
112
+ HINIC_CFG_NIC_CAP, &dev_cap, sizeof(dev_cap),
113
+ &dev_cap, &out_len, HINIC_MGMT_MSG_SYNC);
135114 if (err) {
136115 dev_err(&pdev->dev, "Failed to get capability from FW\n");
137116 return err;
138117 }
139118
140
- return get_capability(hwdev, &dev_cap);
119
+ return parse_capability(hwdev, &dev_cap);
141120 }
142121
143122 /**
....@@ -156,15 +135,14 @@
156135 switch (HINIC_FUNC_TYPE(hwif)) {
157136 case HINIC_PPF:
158137 case HINIC_PF:
138
+ case HINIC_VF:
159139 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
160
-
161
- err = get_cap_from_fw(pfhwdev);
140
+ err = get_capability(pfhwdev);
162141 if (err) {
163
- dev_err(&pdev->dev, "Failed to get capability from FW\n");
142
+ dev_err(&pdev->dev, "Failed to get capability\n");
164143 return err;
165144 }
166145 break;
167
-
168146 default:
169147 dev_err(&pdev->dev, "Unsupported PCI Function type\n");
170148 return -EINVAL;
....@@ -184,7 +162,6 @@
184162 struct hinic_hwif *hwif = hwdev->hwif;
185163 struct pci_dev *pdev = hwif->pdev;
186164 int nr_irqs, num_aeqs, num_ceqs;
187
- size_t msix_entries_size;
188165 int i, err;
189166
190167 num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
....@@ -193,8 +170,8 @@
193170 if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif))
194171 nr_irqs = HINIC_HWIF_NUM_IRQS(hwif);
195172
196
- msix_entries_size = nr_irqs * sizeof(*hwdev->msix_entries);
197
- hwdev->msix_entries = devm_kzalloc(&pdev->dev, msix_entries_size,
173
+ hwdev->msix_entries = devm_kcalloc(&pdev->dev, nr_irqs,
174
+ sizeof(*hwdev->msix_entries),
198175 GFP_KERNEL);
199176 if (!hwdev->msix_entries)
200177 return -ENOMEM;
....@@ -237,18 +214,24 @@
237214 int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd,
238215 void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
239216 {
240
- struct hinic_hwif *hwif = hwdev->hwif;
241
- struct pci_dev *pdev = hwif->pdev;
242217 struct hinic_pfhwdev *pfhwdev;
243
-
244
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
245
- dev_err(&pdev->dev, "unsupported PCI Function type\n");
246
- return -EINVAL;
247
- }
248218
249219 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
250220
251221 return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd,
222
+ buf_in, in_size, buf_out, out_size,
223
+ HINIC_MGMT_MSG_SYNC);
224
+}
225
+
226
+int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd,
227
+ void *buf_in, u16 in_size, void *buf_out,
228
+ u16 *out_size)
229
+{
230
+ struct hinic_pfhwdev *pfhwdev;
231
+
232
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
233
+
234
+ return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_HILINK, cmd,
252235 buf_in, in_size, buf_out, out_size,
253236 HINIC_MGMT_MSG_SYNC);
254237 }
....@@ -264,13 +247,8 @@
264247 struct hinic_hwif *hwif = hwdev->hwif;
265248 struct pci_dev *pdev = hwif->pdev;
266249 struct hinic_cmd_fw_ctxt fw_ctxt;
267
- u16 out_size;
250
+ u16 out_size = sizeof(fw_ctxt);
268251 int err;
269
-
270
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
271
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
272
- return -EINVAL;
273
- }
274252
275253 fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
276254 fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ;
....@@ -279,9 +257,9 @@
279257 &fw_ctxt, sizeof(fw_ctxt),
280258 &fw_ctxt, &out_size);
281259 if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) {
282
- dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n",
283
- fw_ctxt.status);
284
- return -EFAULT;
260
+ dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n",
261
+ err, fw_ctxt.status, out_size);
262
+ return -EIO;
285263 }
286264
287265 return 0;
....@@ -295,24 +273,20 @@
295273 *
296274 * Return 0 - Success, negative - Failure
297275 **/
298
-static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
299
- unsigned int sq_depth)
276
+static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth,
277
+ unsigned int rq_depth)
300278 {
301279 struct hinic_hwif *hwif = hwdev->hwif;
302280 struct hinic_cmd_hw_ioctxt hw_ioctxt;
303
- struct pci_dev *pdev = hwif->pdev;
304281 struct hinic_pfhwdev *pfhwdev;
305
-
306
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
307
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
308
- return -EINVAL;
309
- }
310282
311283 hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
312284 hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);
313285
314286 hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
315287 hw_ioctxt.cmdq_depth = 0;
288
+
289
+ hw_ioctxt.lro_en = 1;
316290
317291 hw_ioctxt.rq_depth = ilog2(rq_depth);
318292
....@@ -384,11 +358,6 @@
384358 struct hinic_pfhwdev *pfhwdev;
385359 int err;
386360
387
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
388
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
389
- return -EINVAL;
390
- }
391
-
392361 /* sleep 100ms to wait for firmware stopping I/O */
393362 msleep(100);
394363
....@@ -420,13 +389,7 @@
420389 {
421390 struct hinic_cmd_set_res_state res_state;
422391 struct hinic_hwif *hwif = hwdev->hwif;
423
- struct pci_dev *pdev = hwif->pdev;
424392 struct hinic_pfhwdev *pfhwdev;
425
-
426
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
427
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
428
- return -EINVAL;
429
- }
430393
431394 res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
432395 res_state.state = state;
....@@ -451,8 +414,8 @@
451414 {
452415 struct hinic_cmd_base_qpn cmd_base_qpn;
453416 struct hinic_hwif *hwif = hwdev->hwif;
417
+ u16 out_size = sizeof(cmd_base_qpn);
454418 struct pci_dev *pdev = hwif->pdev;
455
- u16 out_size;
456419 int err;
457420
458421 cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
....@@ -461,9 +424,9 @@
461424 &cmd_base_qpn, sizeof(cmd_base_qpn),
462425 &cmd_base_qpn, &out_size);
463426 if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) {
464
- dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n",
465
- cmd_base_qpn.status);
466
- return -EFAULT;
427
+ dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n",
428
+ err, cmd_base_qpn.status, out_size);
429
+ return -EIO;
467430 }
468431
469432 *base_qpn = cmd_base_qpn.qpn;
....@@ -473,10 +436,12 @@
473436 /**
474437 * hinic_hwdev_ifup - Preparing the HW for passing IO
475438 * @hwdev: the NIC HW device
439
+ * @sq_depth: the send queue depth
440
+ * @rq_depth: the receive queue depth
476441 *
477442 * Return 0 - Success, negative - Failure
478443 **/
479
-int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
444
+int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth)
480445 {
481446 struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
482447 struct hinic_cap *nic_cap = &hwdev->nic_cap;
....@@ -498,6 +463,10 @@
498463 num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);
499464
500465 ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
466
+ func_to_io->hwdev = hwdev;
467
+ func_to_io->sq_depth = sq_depth;
468
+ func_to_io->rq_depth = rq_depth;
469
+ func_to_io->global_qpn = base_qpn;
501470
502471 err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
503472 ceq_msix_entries);
....@@ -523,7 +492,7 @@
523492 hinic_db_state_set(hwif, HINIC_DB_ENABLE);
524493 }
525494
526
- err = set_hw_ioctxt(hwdev, HINIC_SQ_DEPTH, HINIC_RQ_DEPTH);
495
+ err = set_hw_ioctxt(hwdev, sq_depth, rq_depth);
527496 if (err) {
528497 dev_err(&pdev->dev, "Failed to set HW IO ctxt\n");
529498 goto err_hw_ioctxt;
....@@ -568,16 +537,9 @@
568537 u16 in_size, void *buf_out,
569538 u16 *out_size))
570539 {
571
- struct hinic_hwif *hwif = hwdev->hwif;
572
- struct pci_dev *pdev = hwif->pdev;
573540 struct hinic_pfhwdev *pfhwdev;
574541 struct hinic_nic_cb *nic_cb;
575542 u8 cmd_cb;
576
-
577
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
578
- dev_err(&pdev->dev, "unsupported PCI Function type\n");
579
- return;
580
- }
581543
582544 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
583545
....@@ -598,15 +560,12 @@
598560 enum hinic_mgmt_msg_cmd cmd)
599561 {
600562 struct hinic_hwif *hwif = hwdev->hwif;
601
- struct pci_dev *pdev = hwif->pdev;
602563 struct hinic_pfhwdev *pfhwdev;
603564 struct hinic_nic_cb *nic_cb;
604565 u8 cmd_cb;
605566
606
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
607
- dev_err(&pdev->dev, "unsupported PCI Function type\n");
567
+ if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif))
608568 return;
609
- }
610569
611570 pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
612571
....@@ -624,6 +583,7 @@
624583 /**
625584 * nic_mgmt_msg_handler - nic mgmt event handler
626585 * @handle: private data for the handler
586
+ * @cmd: message command
627587 * @buf_in: input buffer
628588 * @in_size: input size
629589 * @buf_out: output buffer
....@@ -667,6 +627,113 @@
667627 nic_cb->cb_state &= ~HINIC_CB_RUNNING;
668628 }
669629
630
+static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev,
631
+ u8 cmd,
632
+ comm_mgmt_self_msg_proc proc)
633
+{
634
+ u8 cmd_idx;
635
+
636
+ cmd_idx = pfhwdev->proc.cmd_num;
637
+ if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
638
+ dev_err(&pfhwdev->hwdev.hwif->pdev->dev,
639
+ "Register recv mgmt process failed, cmd: 0x%x\n", cmd);
640
+ return;
641
+ }
642
+
643
+ pfhwdev->proc.info[cmd_idx].cmd = cmd;
644
+ pfhwdev->proc.info[cmd_idx].proc = proc;
645
+ pfhwdev->proc.cmd_num++;
646
+}
647
+
648
+static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev,
649
+ u8 cmd)
650
+{
651
+ u8 cmd_idx;
652
+
653
+ cmd_idx = pfhwdev->proc.cmd_num;
654
+ if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
655
+ dev_err(&pfhwdev->hwdev.hwif->pdev->dev, "Unregister recv mgmt process failed, cmd: 0x%x\n",
656
+ cmd);
657
+ return;
658
+ }
659
+
660
+ for (cmd_idx = 0; cmd_idx < HINIC_COMM_SELF_CMD_MAX; cmd_idx++) {
661
+ if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
662
+ pfhwdev->proc.info[cmd_idx].cmd = 0;
663
+ pfhwdev->proc.info[cmd_idx].proc = NULL;
664
+ pfhwdev->proc.cmd_num--;
665
+ }
666
+ }
667
+}
668
+
669
+static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
670
+ u16 in_size, void *buf_out, u16 *out_size)
671
+{
672
+ struct hinic_pfhwdev *pfhwdev = handle;
673
+ u8 cmd_idx;
674
+
675
+ for (cmd_idx = 0; cmd_idx < pfhwdev->proc.cmd_num; cmd_idx++) {
676
+ if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
677
+ if (!pfhwdev->proc.info[cmd_idx].proc) {
678
+ dev_warn(&pfhwdev->hwdev.hwif->pdev->dev,
679
+ "PF recv mgmt comm msg handle null, cmd: 0x%x\n",
680
+ cmd);
681
+ } else {
682
+ pfhwdev->proc.info[cmd_idx].proc
683
+ (&pfhwdev->hwdev, buf_in, in_size,
684
+ buf_out, out_size);
685
+ }
686
+
687
+ return;
688
+ }
689
+ }
690
+
691
+ dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, "Received unknown mgmt cpu event: 0x%x\n",
692
+ cmd);
693
+
694
+ *out_size = 0;
695
+}
696
+
697
+/* pf fault report event */
698
+static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size,
699
+ void *buf_out, u16 *out_size)
700
+{
701
+ struct hinic_cmd_fault_event *fault_event = buf_in;
702
+ struct hinic_hwdev *hwdev = dev;
703
+
704
+ if (in_size != sizeof(*fault_event)) {
705
+ dev_err(&hwdev->hwif->pdev->dev, "Invalid fault event report, length: %d, should be %zu\n",
706
+ in_size, sizeof(*fault_event));
707
+ return;
708
+ }
709
+
710
+ if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->hw_fault_reporter))
711
+ return;
712
+
713
+ devlink_health_report(hwdev->devlink_dev->hw_fault_reporter,
714
+ "HW fatal error reported", &fault_event->event);
715
+}
716
+
717
+static void mgmt_watchdog_timeout_event_handler(void *dev,
718
+ void *buf_in, u16 in_size,
719
+ void *buf_out, u16 *out_size)
720
+{
721
+ struct hinic_mgmt_watchdog_info *watchdog_info = buf_in;
722
+ struct hinic_hwdev *hwdev = dev;
723
+
724
+ if (in_size != sizeof(*watchdog_info)) {
725
+ dev_err(&hwdev->hwif->pdev->dev, "Invalid mgmt watchdog report, length: %d, should be %zu\n",
726
+ in_size, sizeof(*watchdog_info));
727
+ return;
728
+ }
729
+
730
+ if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->fw_fault_reporter))
731
+ return;
732
+
733
+ devlink_health_report(hwdev->devlink_dev->fw_fault_reporter,
734
+ "FW fatal error reported", watchdog_info);
735
+}
736
+
670737 /**
671738 * init_pfhwdev - Initialize the extended components of PF
672739 * @pfhwdev: the HW device for PF
....@@ -686,10 +753,40 @@
686753 return err;
687754 }
688755
689
- hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC,
690
- pfhwdev, nic_mgmt_msg_handler);
756
+ err = hinic_devlink_register(hwdev->devlink_dev, &pdev->dev);
757
+ if (err) {
758
+ dev_err(&hwif->pdev->dev, "Failed to register devlink\n");
759
+ hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
760
+ return err;
761
+ }
762
+
763
+ err = hinic_func_to_func_init(hwdev);
764
+ if (err) {
765
+ dev_err(&hwif->pdev->dev, "Failed to init mailbox\n");
766
+ hinic_devlink_unregister(hwdev->devlink_dev);
767
+ hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
768
+ return err;
769
+ }
770
+
771
+ if (!HINIC_IS_VF(hwif)) {
772
+ hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
773
+ HINIC_MOD_L2NIC, pfhwdev,
774
+ nic_mgmt_msg_handler);
775
+ hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
776
+ pfhwdev, comm_mgmt_msg_handler);
777
+ hinic_comm_recv_mgmt_self_cmd_reg(pfhwdev,
778
+ HINIC_COMM_CMD_FAULT_REPORT,
779
+ pf_fault_event_handler);
780
+ hinic_comm_recv_mgmt_self_cmd_reg
781
+ (pfhwdev, HINIC_COMM_CMD_WATCHDOG_INFO,
782
+ mgmt_watchdog_timeout_event_handler);
783
+ } else {
784
+ hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC,
785
+ nic_mgmt_msg_handler);
786
+ }
691787
692788 hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE);
789
+
693790 return 0;
694791 }
695792
....@@ -703,20 +800,124 @@
703800
704801 hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT);
705802
706
- hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC);
803
+ if (!HINIC_IS_VF(hwdev->hwif)) {
804
+ hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
805
+ HINIC_COMM_CMD_WATCHDOG_INFO);
806
+ hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
807
+ HINIC_COMM_CMD_FAULT_REPORT);
808
+ hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
809
+ HINIC_MOD_COMM);
810
+ hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
811
+ HINIC_MOD_L2NIC);
812
+ } else {
813
+ hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
814
+ }
815
+
816
+ hinic_func_to_func_free(hwdev);
817
+
818
+ hinic_devlink_unregister(hwdev->devlink_dev);
707819
708820 hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
821
+}
822
+
823
+static int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
824
+{
825
+ struct hinic_cmd_l2nic_reset l2nic_reset = {0};
826
+ u16 out_size = sizeof(l2nic_reset);
827
+ struct hinic_pfhwdev *pfhwdev;
828
+ int err;
829
+
830
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
831
+
832
+ l2nic_reset.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
833
+ /* 0 represents standard l2nic reset flow */
834
+ l2nic_reset.reset_flag = 0;
835
+
836
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
837
+ HINIC_COMM_CMD_L2NIC_RESET, &l2nic_reset,
838
+ sizeof(l2nic_reset), &l2nic_reset,
839
+ &out_size, HINIC_MGMT_MSG_SYNC);
840
+ if (err || !out_size || l2nic_reset.status) {
841
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to reset L2NIC resources, err: %d, status: 0x%x, out_size: 0x%x\n",
842
+ err, l2nic_reset.status, out_size);
843
+ return -EIO;
844
+ }
845
+
846
+ return 0;
847
+}
848
+
849
+int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,
850
+ struct hinic_msix_config *interrupt_info)
851
+{
852
+ u16 out_size = sizeof(*interrupt_info);
853
+ struct hinic_pfhwdev *pfhwdev;
854
+ int err;
855
+
856
+ if (!hwdev || !interrupt_info)
857
+ return -EINVAL;
858
+
859
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
860
+
861
+ interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
862
+
863
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
864
+ HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
865
+ interrupt_info, sizeof(*interrupt_info),
866
+ interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
867
+ if (err || !out_size || interrupt_info->status) {
868
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
869
+ err, interrupt_info->status, out_size);
870
+ return -EIO;
871
+ }
872
+
873
+ return 0;
874
+}
875
+
876
+int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
877
+ struct hinic_msix_config *interrupt_info)
878
+{
879
+ u16 out_size = sizeof(*interrupt_info);
880
+ struct hinic_msix_config temp_info;
881
+ struct hinic_pfhwdev *pfhwdev;
882
+ int err;
883
+
884
+ if (!hwdev)
885
+ return -EINVAL;
886
+
887
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
888
+
889
+ interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
890
+
891
+ err = hinic_get_interrupt_cfg(hwdev, &temp_info);
892
+ if (err)
893
+ return -EINVAL;
894
+
895
+ interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt;
896
+ interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;
897
+
898
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
899
+ HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
900
+ interrupt_info, sizeof(*interrupt_info),
901
+ interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
902
+ if (err || !out_size || interrupt_info->status) {
903
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
904
+ err, interrupt_info->status, out_size);
905
+ return -EIO;
906
+ }
907
+
908
+ return 0;
709909 }
710910
711911 /**
712912 * hinic_init_hwdev - Initialize the NIC HW
713913 * @pdev: the NIC pci device
914
+ * @devlink: the poniter of hinic devlink
714915 *
715916 * Return initialized NIC HW device
716917 *
717918 * Initialize the NIC HW device and return a pointer to it
718919 **/
719
-struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev)
920
+struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink)
720921 {
721922 struct hinic_pfhwdev *pfhwdev;
722923 struct hinic_hwdev *hwdev;
....@@ -733,12 +934,6 @@
733934 return ERR_PTR(err);
734935 }
735936
736
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
737
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
738
- err = -EFAULT;
739
- goto err_func_type;
740
- }
741
-
742937 pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL);
743938 if (!pfhwdev) {
744939 err = -ENOMEM;
....@@ -747,6 +942,8 @@
747942
748943 hwdev = &pfhwdev->hwdev;
749944 hwdev->hwif = hwif;
945
+ hwdev->devlink_dev = devlink_priv(devlink);
946
+ hwdev->devlink_dev->hwdev = hwdev;
750947
751948 err = init_msix(hwdev);
752949 if (err) {
....@@ -776,10 +973,22 @@
776973 goto err_init_pfhwdev;
777974 }
778975
976
+ err = hinic_l2nic_reset(hwdev);
977
+ if (err)
978
+ goto err_l2nic_reset;
979
+
779980 err = get_dev_cap(hwdev);
780981 if (err) {
781982 dev_err(&pdev->dev, "Failed to get device capabilities\n");
782983 goto err_dev_cap;
984
+ }
985
+
986
+ mutex_init(&hwdev->func_to_io.nic_cfg.cfg_mutex);
987
+
988
+ err = hinic_vf_func_init(hwdev);
989
+ if (err) {
990
+ dev_err(&pdev->dev, "Failed to init nic mbox\n");
991
+ goto err_vf_func_init;
783992 }
784993
785994 err = init_fw_ctxt(hwdev);
....@@ -798,6 +1007,9 @@
7981007
7991008 err_resources_state:
8001009 err_init_fw_ctxt:
1010
+ hinic_vf_func_free(hwdev);
1011
+err_vf_func_init:
1012
+err_l2nic_reset:
8011013 err_dev_cap:
8021014 free_pfhwdev(pfhwdev);
8031015
....@@ -809,8 +1021,9 @@
8091021
8101022 err_init_msix:
8111023 err_pfhwdev_alloc:
812
-err_func_type:
8131024 hinic_free_hwif(hwif);
1025
+ if (err > 0)
1026
+ err = -EIO;
8141027 return ERR_PTR(err);
8151028 }
8161029
....@@ -826,6 +1039,8 @@
8261039
8271040 set_resources_state(hwdev, HINIC_RES_CLEAN);
8281041
1042
+ hinic_vf_func_free(hwdev);
1043
+
8291044 free_pfhwdev(pfhwdev);
8301045
8311046 hinic_aeqs_free(&hwdev->aeqs);
....@@ -833,6 +1048,13 @@
8331048 disable_msix(hwdev);
8341049
8351050 hinic_free_hwif(hwdev->hwif);
1051
+}
1052
+
1053
+int hinic_hwdev_max_num_qps(struct hinic_hwdev *hwdev)
1054
+{
1055
+ struct hinic_cap *nic_cap = &hwdev->nic_cap;
1056
+
1057
+ return nic_cap->max_qps;
8361058 }
8371059
8381060 /**
....@@ -902,7 +1124,7 @@
9021124 * @msix_index: msix_index
9031125 * @pending_limit: the maximum pending interrupt events (unit 8)
9041126 * @coalesc_timer: coalesc period for interrupt (unit 8 us)
905
- * @lli_timer: replenishing period for low latency credit (unit 8 us)
1127
+ * @lli_timer_cfg: replenishing period for low latency credit (unit 8 us)
9061128 * @lli_credit_limit: maximum credits for low latency msix messages (unit 8)
9071129 * @resend_timer: maximum wait for resending msix (unit coalesc period)
9081130 *
....@@ -933,14 +1155,8 @@
9331155 {
9341156 struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq);
9351157 struct hinic_hwif *hwif = hwdev->hwif;
936
- struct pci_dev *pdev = hwif->pdev;
9371158 struct hinic_pfhwdev *pfhwdev;
9381159 struct hinic_cmd_hw_ci hw_ci;
939
-
940
- if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
941
- dev_err(&pdev->dev, "Unsupported PCI Function type\n");
942
- return -EINVAL;
943
- }
9441160
9451161 hw_ci.dma_attr_off = 0;
9461162 hw_ci.pending_limit = pending_limit;
....@@ -962,3 +1178,42 @@
9621178 &hw_ci, sizeof(hw_ci), NULL,
9631179 NULL, HINIC_MGMT_MSG_SYNC);
9641180 }
1181
+
1182
+/**
1183
+ * hinic_hwdev_set_msix_state- set msix state
1184
+ * @hwdev: the NIC HW device
1185
+ * @msix_index: IRQ corresponding index number
1186
+ * @flag: msix state
1187
+ *
1188
+ **/
1189
+void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
1190
+ enum hinic_msix_state flag)
1191
+{
1192
+ hinic_set_msix_state(hwdev->hwif, msix_index, flag);
1193
+}
1194
+
1195
+int hinic_get_board_info(struct hinic_hwdev *hwdev,
1196
+ struct hinic_comm_board_info *board_info)
1197
+{
1198
+ u16 out_size = sizeof(*board_info);
1199
+ struct hinic_pfhwdev *pfhwdev;
1200
+ int err;
1201
+
1202
+ if (!hwdev || !board_info)
1203
+ return -EINVAL;
1204
+
1205
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
1206
+
1207
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
1208
+ HINIC_COMM_CMD_GET_BOARD_INFO,
1209
+ board_info, sizeof(*board_info),
1210
+ board_info, &out_size, HINIC_MGMT_MSG_SYNC);
1211
+ if (err || board_info->status || !out_size) {
1212
+ dev_err(&hwdev->hwif->pdev->dev,
1213
+ "Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\n",
1214
+ err, board_info->status, out_size);
1215
+ return -EIO;
1216
+ }
1217
+
1218
+ return 0;
1219
+}