hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/qlogic/qed/qed_main.c
....@@ -1,33 +1,7 @@
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
12 /* QLogic qed NIC Driver
23 * Copyright (c) 2015-2017 QLogic Corporation
3
- *
4
- * This software is available to you under a choice of one of two
5
- * licenses. You may choose to be licensed under the terms of the GNU
6
- * General Public License (GPL) Version 2, available from the file
7
- * COPYING in the main directory of this source tree, or the
8
- * OpenIB.org BSD license below:
9
- *
10
- * Redistribution and use in source and binary forms, with or
11
- * without modification, are permitted provided that the following
12
- * conditions are met:
13
- *
14
- * - Redistributions of source code must retain the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer.
17
- *
18
- * - Redistributions in binary form must reproduce the above
19
- * copyright notice, this list of conditions and the following
20
- * disclaimer in the documentation and /or other materials
21
- * provided with the distribution.
22
- *
23
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- * SOFTWARE.
4
+ * Copyright (c) 2019-2020 Marvell International Ltd.
315 */
326
337 #include <linux/stddef.h>
....@@ -48,6 +22,9 @@
4822 #include <linux/crc32.h>
4923 #include <linux/qed/qed_if.h>
5024 #include <linux/qed/qed_ll2_if.h>
25
+#include <net/devlink.h>
26
+#include <linux/aer.h>
27
+#include <linux/phylink.h>
5128
5229 #include "qed.h"
5330 #include "qed_sriov.h"
....@@ -58,13 +35,18 @@
5835 #include "qed_iscsi.h"
5936
6037 #include "qed_mcp.h"
38
+#include "qed_reg_addr.h"
6139 #include "qed_hw.h"
6240 #include "qed_selftest.h"
6341 #include "qed_debug.h"
42
+#include "qed_devlink.h"
6443
6544 #define QED_ROCE_QPS (8192)
6645 #define QED_ROCE_DPIS (8)
6746 #define QED_RDMA_SRQS QED_ROCE_QPS
47
+#define QED_NVM_CFG_GET_FLAGS 0xA
48
+#define QED_NVM_CFG_GET_PF_FLAGS 0x1A
49
+#define QED_NVM_CFG_MAX_ATTRS 50
6850
6951 static char version[] =
7052 "QLogic FastLinQ 4xxxx Core Module qed " DRV_MODULE_VERSION "\n";
....@@ -84,20 +66,200 @@
8466
8567 MODULE_FIRMWARE(QED_FW_FILE_NAME);
8668
69
+/* MFW speed capabilities maps */
70
+
71
+struct qed_mfw_speed_map {
72
+ u32 mfw_val;
73
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(caps);
74
+
75
+ const u32 *cap_arr;
76
+ u32 arr_size;
77
+};
78
+
79
+#define QED_MFW_SPEED_MAP(type, arr) \
80
+{ \
81
+ .mfw_val = (type), \
82
+ .cap_arr = (arr), \
83
+ .arr_size = ARRAY_SIZE(arr), \
84
+}
85
+
86
+static const u32 qed_mfw_ext_1g[] __initconst = {
87
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
88
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
89
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
90
+};
91
+
92
+static const u32 qed_mfw_ext_10g[] __initconst = {
93
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
94
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
95
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
96
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
97
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
98
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
99
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
100
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
101
+};
102
+
103
+static const u32 qed_mfw_ext_20g[] __initconst = {
104
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
105
+};
106
+
107
+static const u32 qed_mfw_ext_25g[] __initconst = {
108
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
109
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
110
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
111
+};
112
+
113
+static const u32 qed_mfw_ext_40g[] __initconst = {
114
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
115
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
116
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
117
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
118
+};
119
+
120
+static const u32 qed_mfw_ext_50g_base_r[] __initconst = {
121
+ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
122
+ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
123
+ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
124
+ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
125
+ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
126
+};
127
+
128
+static const u32 qed_mfw_ext_50g_base_r2[] __initconst = {
129
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
130
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
131
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
132
+};
133
+
134
+static const u32 qed_mfw_ext_100g_base_r2[] __initconst = {
135
+ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
136
+ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
137
+ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
138
+ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
139
+ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
140
+};
141
+
142
+static const u32 qed_mfw_ext_100g_base_r4[] __initconst = {
143
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
144
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
145
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
146
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
147
+};
148
+
149
+static struct qed_mfw_speed_map qed_mfw_ext_maps[] __ro_after_init = {
150
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_1G, qed_mfw_ext_1g),
151
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_10G, qed_mfw_ext_10g),
152
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_20G, qed_mfw_ext_20g),
153
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_25G, qed_mfw_ext_25g),
154
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_40G, qed_mfw_ext_40g),
155
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R,
156
+ qed_mfw_ext_50g_base_r),
157
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R2,
158
+ qed_mfw_ext_50g_base_r2),
159
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R2,
160
+ qed_mfw_ext_100g_base_r2),
161
+ QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R4,
162
+ qed_mfw_ext_100g_base_r4),
163
+};
164
+
165
+static const u32 qed_mfw_legacy_1g[] __initconst = {
166
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
167
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
168
+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
169
+};
170
+
171
+static const u32 qed_mfw_legacy_10g[] __initconst = {
172
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
173
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
174
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
175
+ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
176
+ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
177
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
178
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
179
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
180
+};
181
+
182
+static const u32 qed_mfw_legacy_20g[] __initconst = {
183
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
184
+};
185
+
186
+static const u32 qed_mfw_legacy_25g[] __initconst = {
187
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
188
+ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
189
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
190
+};
191
+
192
+static const u32 qed_mfw_legacy_40g[] __initconst = {
193
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
194
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
195
+ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
196
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
197
+};
198
+
199
+static const u32 qed_mfw_legacy_50g[] __initconst = {
200
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
201
+ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
202
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
203
+};
204
+
205
+static const u32 qed_mfw_legacy_bb_100g[] __initconst = {
206
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
207
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
208
+ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
209
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
210
+};
211
+
212
+static struct qed_mfw_speed_map qed_mfw_legacy_maps[] __ro_after_init = {
213
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G,
214
+ qed_mfw_legacy_1g),
215
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G,
216
+ qed_mfw_legacy_10g),
217
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G,
218
+ qed_mfw_legacy_20g),
219
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G,
220
+ qed_mfw_legacy_25g),
221
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G,
222
+ qed_mfw_legacy_40g),
223
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G,
224
+ qed_mfw_legacy_50g),
225
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G,
226
+ qed_mfw_legacy_bb_100g),
227
+};
228
+
229
+static void __init qed_mfw_speed_map_populate(struct qed_mfw_speed_map *map)
230
+{
231
+ linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps);
232
+
233
+ map->cap_arr = NULL;
234
+ map->arr_size = 0;
235
+}
236
+
237
+static void __init qed_mfw_speed_maps_init(void)
238
+{
239
+ u32 i;
240
+
241
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++)
242
+ qed_mfw_speed_map_populate(qed_mfw_ext_maps + i);
243
+
244
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++)
245
+ qed_mfw_speed_map_populate(qed_mfw_legacy_maps + i);
246
+}
247
+
87248 static int __init qed_init(void)
88249 {
89250 pr_info("%s", version);
90251
252
+ qed_mfw_speed_maps_init();
253
+
91254 return 0;
92255 }
93
-
94
-static void __exit qed_cleanup(void)
95
-{
96
- pr_notice("qed_cleanup called\n");
97
-}
98
-
99256 module_init(qed_init);
100
-module_exit(qed_cleanup);
257
+
258
+static void __exit qed_exit(void)
259
+{
260
+ /* To prevent marking this module as "permanent" */
261
+}
262
+module_exit(qed_exit);
101263
102264 /* Check if the DMA controller on the machine can properly handle the DMA
103265 * addressing required by the device.
....@@ -123,6 +285,8 @@
123285 static void qed_free_pci(struct qed_dev *cdev)
124286 {
125287 struct pci_dev *pdev = cdev->pdev;
288
+
289
+ pci_disable_pcie_error_reporting(pdev);
126290
127291 if (cdev->doorbells && cdev->db_size)
128292 iounmap(cdev->doorbells);
....@@ -226,6 +390,12 @@
226390 return -ENOMEM;
227391 }
228392
393
+ /* AER (Advanced Error reporting) configuration */
394
+ rc = pci_enable_pcie_error_reporting(pdev);
395
+ if (rc)
396
+ DP_VERBOSE(cdev, NETIF_MSG_DRV,
397
+ "Failed to configure PCIe AER [%d]\n", rc);
398
+
229399 return 0;
230400
231401 err2:
....@@ -275,10 +445,14 @@
275445 dev_info->fw_eng = FW_ENGINEERING_VERSION;
276446 dev_info->b_inter_pf_switch = test_bit(QED_MF_INTER_PF_SWITCH,
277447 &cdev->mf_bits);
448
+ if (!test_bit(QED_MF_DISABLE_ARFS, &cdev->mf_bits))
449
+ dev_info->b_arfs_capable = true;
278450 dev_info->tx_switching = true;
279451
280452 if (hw_info->b_wol_support == QED_WOL_SUPPORT_PME)
281453 dev_info->wol_support = true;
454
+
455
+ dev_info->smart_an = qed_mcp_is_smart_an_supported(p_hwfn);
282456
283457 dev_info->abs_pf_id = QED_LEADING_HWFN(cdev)->abs_pf_id;
284458 } else {
....@@ -307,6 +481,7 @@
307481 }
308482
309483 dev_info->mtu = hw_info->mtu;
484
+ cdev->common_dev_info = *dev_info;
310485
311486 return 0;
312487 }
....@@ -357,6 +532,8 @@
357532 cdev->b_is_vf = true;
358533
359534 qed_init_dp(cdev, params->dp_module, params->dp_level);
535
+
536
+ cdev->recov_in_prog = params->recov_in_prog;
360537
361538 rc = qed_init_pci(cdev, pdev);
362539 if (rc) {
....@@ -484,7 +661,7 @@
484661 kfree(int_params->msix_table);
485662 if (force_mode)
486663 goto out;
487
- /* Fallthrough */
664
+ fallthrough;
488665
489666 case QED_INT_MODE_MSI:
490667 if (cdev->num_hwfns == 1) {
....@@ -498,7 +675,7 @@
498675 if (force_mode)
499676 goto out;
500677 }
501
- /* Fallthrough */
678
+ fallthrough;
502679
503680 case QED_INT_MODE_INTA:
504681 int_params->out.int_mode = QED_INT_MODE_INTA;
....@@ -564,7 +741,7 @@
564741
565742 /* Slowpath interrupt */
566743 if (unlikely(status & 0x1)) {
567
- tasklet_schedule(hwfn->sp_dpc);
744
+ tasklet_schedule(&hwfn->sp_dpc);
568745 status &= ~0x1;
569746 rc = IRQ_HANDLED;
570747 }
....@@ -610,7 +787,7 @@
610787 id, cdev->pdev->bus->number,
611788 PCI_SLOT(cdev->pdev->devfn), hwfn->abs_pf_id);
612789 rc = request_irq(cdev->int_params.msix_table[id].vector,
613
- qed_msix_sp_int, 0, hwfn->name, hwfn->sp_dpc);
790
+ qed_msix_sp_int, 0, hwfn->name, &hwfn->sp_dpc);
614791 } else {
615792 unsigned long flags = 0;
616793
....@@ -642,8 +819,8 @@
642819 * enable function makes this sequence a flush-like operation.
643820 */
644821 if (p_hwfn->b_sp_dpc_enabled) {
645
- tasklet_disable(p_hwfn->sp_dpc);
646
- tasklet_enable(p_hwfn->sp_dpc);
822
+ tasklet_disable(&p_hwfn->sp_dpc);
823
+ tasklet_enable(&p_hwfn->sp_dpc);
647824 }
648825 }
649826
....@@ -672,7 +849,7 @@
672849 break;
673850 synchronize_irq(cdev->int_params.msix_table[i].vector);
674851 free_irq(cdev->int_params.msix_table[i].vector,
675
- cdev->hwfns[i].sp_dpc);
852
+ &cdev->hwfns[i].sp_dpc);
676853 }
677854 } else {
678855 if (QED_LEADING_HWFN(cdev)->b_int_requested)
....@@ -691,11 +868,11 @@
691868 struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
692869
693870 if (p_hwfn->b_sp_dpc_enabled) {
694
- tasklet_disable(p_hwfn->sp_dpc);
871
+ tasklet_disable(&p_hwfn->sp_dpc);
695872 p_hwfn->b_sp_dpc_enabled = false;
696873 DP_VERBOSE(cdev, NETIF_MSG_IFDOWN,
697874 "Disabled sp tasklet [hwfn %d] at %p\n",
698
- i, p_hwfn->sp_dpc);
875
+ i, &p_hwfn->sp_dpc);
699876 }
700877 }
701878
....@@ -970,6 +1147,41 @@
9701147 }
9711148 }
9721149
1150
+#define QED_PERIODIC_DB_REC_COUNT 10
1151
+#define QED_PERIODIC_DB_REC_INTERVAL_MS 100
1152
+#define QED_PERIODIC_DB_REC_INTERVAL \
1153
+ msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS)
1154
+
1155
+static int qed_slowpath_delayed_work(struct qed_hwfn *hwfn,
1156
+ enum qed_slowpath_wq_flag wq_flag,
1157
+ unsigned long delay)
1158
+{
1159
+ if (!hwfn->slowpath_wq_active)
1160
+ return -EINVAL;
1161
+
1162
+ /* Memory barrier for setting atomic bit */
1163
+ smp_mb__before_atomic();
1164
+ set_bit(wq_flag, &hwfn->slowpath_task_flags);
1165
+ smp_mb__after_atomic();
1166
+ queue_delayed_work(hwfn->slowpath_wq, &hwfn->slowpath_task, delay);
1167
+
1168
+ return 0;
1169
+}
1170
+
1171
+void qed_periodic_db_rec_start(struct qed_hwfn *p_hwfn)
1172
+{
1173
+ /* Reset periodic Doorbell Recovery counter */
1174
+ p_hwfn->periodic_db_rec_count = QED_PERIODIC_DB_REC_COUNT;
1175
+
1176
+ /* Don't schedule periodic Doorbell Recovery if already scheduled */
1177
+ if (test_bit(QED_SLOWPATH_PERIODIC_DB_REC,
1178
+ &p_hwfn->slowpath_task_flags))
1179
+ return;
1180
+
1181
+ qed_slowpath_delayed_work(p_hwfn, QED_SLOWPATH_PERIODIC_DB_REC,
1182
+ QED_PERIODIC_DB_REC_INTERVAL);
1183
+}
1184
+
9731185 static void qed_slowpath_wq_stop(struct qed_dev *cdev)
9741186 {
9751187 int i;
....@@ -981,7 +1193,10 @@
9811193 if (!cdev->hwfns[i].slowpath_wq)
9821194 continue;
9831195
984
- flush_workqueue(cdev->hwfns[i].slowpath_wq);
1196
+ /* Stop queuing new delayed works */
1197
+ cdev->hwfns[i].slowpath_wq_active = false;
1198
+
1199
+ cancel_delayed_work(&cdev->hwfns[i].slowpath_task);
9851200 destroy_workqueue(cdev->hwfns[i].slowpath_wq);
9861201 }
9871202 }
....@@ -993,13 +1208,25 @@
9931208 struct qed_ptt *ptt = qed_ptt_acquire(hwfn);
9941209
9951210 if (!ptt) {
996
- queue_delayed_work(hwfn->slowpath_wq, &hwfn->slowpath_task, 0);
1211
+ if (hwfn->slowpath_wq_active)
1212
+ queue_delayed_work(hwfn->slowpath_wq,
1213
+ &hwfn->slowpath_task, 0);
1214
+
9971215 return;
9981216 }
9991217
10001218 if (test_and_clear_bit(QED_SLOWPATH_MFW_TLV_REQ,
10011219 &hwfn->slowpath_task_flags))
10021220 qed_mfw_process_tlv_req(hwfn, ptt);
1221
+
1222
+ if (test_and_clear_bit(QED_SLOWPATH_PERIODIC_DB_REC,
1223
+ &hwfn->slowpath_task_flags)) {
1224
+ qed_db_rec_handler(hwfn, ptt);
1225
+ if (hwfn->periodic_db_rec_count--)
1226
+ qed_slowpath_delayed_work(hwfn,
1227
+ QED_SLOWPATH_PERIODIC_DB_REC,
1228
+ QED_PERIODIC_DB_REC_INTERVAL);
1229
+ }
10031230
10041231 qed_ptt_release(hwfn, ptt);
10051232 }
....@@ -1027,6 +1254,7 @@
10271254 }
10281255
10291256 INIT_DELAYED_WORK(&hwfn->slowpath_task, qed_slowpath_task);
1257
+ hwfn->slowpath_wq_active = true;
10301258 }
10311259
10321260 return 0;
....@@ -1244,26 +1472,21 @@
12441472 {
12451473 struct qed_hwfn *p_hwfn;
12461474 struct qed_ptt *p_ptt;
1247
- int hwfn_index;
12481475 u16 rel_sb_id;
1249
- u8 n_hwfns;
12501476 u32 rc;
12511477
1252
- /* RoCE uses single engine and CMT uses two engines. When using both
1253
- * we force only a single engine. Storage uses only engine 0 too.
1254
- */
1255
- if (type == QED_SB_TYPE_L2_QUEUE)
1256
- n_hwfns = cdev->num_hwfns;
1257
- else
1258
- n_hwfns = 1;
1259
-
1260
- hwfn_index = sb_id % n_hwfns;
1261
- p_hwfn = &cdev->hwfns[hwfn_index];
1262
- rel_sb_id = sb_id / n_hwfns;
1478
+ /* RoCE/Storage use a single engine in CMT mode while L2 uses both */
1479
+ if (type == QED_SB_TYPE_L2_QUEUE) {
1480
+ p_hwfn = &cdev->hwfns[sb_id % cdev->num_hwfns];
1481
+ rel_sb_id = sb_id / cdev->num_hwfns;
1482
+ } else {
1483
+ p_hwfn = QED_AFFIN_HWFN(cdev);
1484
+ rel_sb_id = sb_id;
1485
+ }
12631486
12641487 DP_VERBOSE(cdev, NETIF_MSG_INTR,
12651488 "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
1266
- hwfn_index, rel_sb_id, sb_id);
1489
+ IS_LEAD_HWFN(p_hwfn) ? 0 : 1, rel_sb_id, sb_id);
12671490
12681491 if (IS_PF(p_hwfn->cdev)) {
12691492 p_ptt = qed_ptt_acquire(p_hwfn);
....@@ -1282,20 +1505,26 @@
12821505 }
12831506
12841507 static u32 qed_sb_release(struct qed_dev *cdev,
1285
- struct qed_sb_info *sb_info, u16 sb_id)
1508
+ struct qed_sb_info *sb_info,
1509
+ u16 sb_id,
1510
+ enum qed_sb_type type)
12861511 {
12871512 struct qed_hwfn *p_hwfn;
1288
- int hwfn_index;
12891513 u16 rel_sb_id;
12901514 u32 rc;
12911515
1292
- hwfn_index = sb_id % cdev->num_hwfns;
1293
- p_hwfn = &cdev->hwfns[hwfn_index];
1294
- rel_sb_id = sb_id / cdev->num_hwfns;
1516
+ /* RoCE/Storage use a single engine in CMT mode while L2 uses both */
1517
+ if (type == QED_SB_TYPE_L2_QUEUE) {
1518
+ p_hwfn = &cdev->hwfns[sb_id % cdev->num_hwfns];
1519
+ rel_sb_id = sb_id / cdev->num_hwfns;
1520
+ } else {
1521
+ p_hwfn = QED_AFFIN_HWFN(cdev);
1522
+ rel_sb_id = sb_id;
1523
+ }
12951524
12961525 DP_VERBOSE(cdev, NETIF_MSG_INTR,
12971526 "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
1298
- hwfn_index, rel_sb_id, sb_id);
1527
+ IS_LEAD_HWFN(p_hwfn) ? 0 : 1, rel_sb_id, sb_id);
12991528
13001529 rc = qed_int_sb_release(p_hwfn, sb_info, rel_sb_id);
13011530
....@@ -1307,12 +1536,156 @@
13071536 return true;
13081537 }
13091538
1539
+static void qed_set_ext_speed_params(struct qed_mcp_link_params *link_params,
1540
+ const struct qed_link_params *params)
1541
+{
1542
+ struct qed_mcp_link_speed_params *ext_speed = &link_params->ext_speed;
1543
+ const struct qed_mfw_speed_map *map;
1544
+ u32 i;
1545
+
1546
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
1547
+ ext_speed->autoneg = !!params->autoneg;
1548
+
1549
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
1550
+ ext_speed->advertised_speeds = 0;
1551
+
1552
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++) {
1553
+ map = qed_mfw_ext_maps + i;
1554
+
1555
+ if (linkmode_intersects(params->adv_speeds, map->caps))
1556
+ ext_speed->advertised_speeds |= map->mfw_val;
1557
+ }
1558
+ }
1559
+
1560
+ if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED) {
1561
+ switch (params->forced_speed) {
1562
+ case SPEED_1000:
1563
+ ext_speed->forced_speed = QED_EXT_SPEED_1G;
1564
+ break;
1565
+ case SPEED_10000:
1566
+ ext_speed->forced_speed = QED_EXT_SPEED_10G;
1567
+ break;
1568
+ case SPEED_20000:
1569
+ ext_speed->forced_speed = QED_EXT_SPEED_20G;
1570
+ break;
1571
+ case SPEED_25000:
1572
+ ext_speed->forced_speed = QED_EXT_SPEED_25G;
1573
+ break;
1574
+ case SPEED_40000:
1575
+ ext_speed->forced_speed = QED_EXT_SPEED_40G;
1576
+ break;
1577
+ case SPEED_50000:
1578
+ ext_speed->forced_speed = QED_EXT_SPEED_50G_R |
1579
+ QED_EXT_SPEED_50G_R2;
1580
+ break;
1581
+ case SPEED_100000:
1582
+ ext_speed->forced_speed = QED_EXT_SPEED_100G_R2 |
1583
+ QED_EXT_SPEED_100G_R4 |
1584
+ QED_EXT_SPEED_100G_P4;
1585
+ break;
1586
+ default:
1587
+ break;
1588
+ }
1589
+ }
1590
+
1591
+ if (!(params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG))
1592
+ return;
1593
+
1594
+ switch (params->forced_speed) {
1595
+ case SPEED_25000:
1596
+ switch (params->fec) {
1597
+ case FEC_FORCE_MODE_NONE:
1598
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_NONE;
1599
+ break;
1600
+ case FEC_FORCE_MODE_FIRECODE:
1601
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_BASE_R;
1602
+ break;
1603
+ case FEC_FORCE_MODE_RS:
1604
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528;
1605
+ break;
1606
+ case FEC_FORCE_MODE_AUTO:
1607
+ link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528 |
1608
+ ETH_EXT_FEC_25G_BASE_R |
1609
+ ETH_EXT_FEC_25G_NONE;
1610
+ break;
1611
+ default:
1612
+ break;
1613
+ }
1614
+
1615
+ break;
1616
+ case SPEED_40000:
1617
+ switch (params->fec) {
1618
+ case FEC_FORCE_MODE_NONE:
1619
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_NONE;
1620
+ break;
1621
+ case FEC_FORCE_MODE_FIRECODE:
1622
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R;
1623
+ break;
1624
+ case FEC_FORCE_MODE_AUTO:
1625
+ link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R |
1626
+ ETH_EXT_FEC_40G_NONE;
1627
+ break;
1628
+ default:
1629
+ break;
1630
+ }
1631
+
1632
+ break;
1633
+ case SPEED_50000:
1634
+ switch (params->fec) {
1635
+ case FEC_FORCE_MODE_NONE:
1636
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_NONE;
1637
+ break;
1638
+ case FEC_FORCE_MODE_FIRECODE:
1639
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_BASE_R;
1640
+ break;
1641
+ case FEC_FORCE_MODE_RS:
1642
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528;
1643
+ break;
1644
+ case FEC_FORCE_MODE_AUTO:
1645
+ link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528 |
1646
+ ETH_EXT_FEC_50G_BASE_R |
1647
+ ETH_EXT_FEC_50G_NONE;
1648
+ break;
1649
+ default:
1650
+ break;
1651
+ }
1652
+
1653
+ break;
1654
+ case SPEED_100000:
1655
+ switch (params->fec) {
1656
+ case FEC_FORCE_MODE_NONE:
1657
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_NONE;
1658
+ break;
1659
+ case FEC_FORCE_MODE_FIRECODE:
1660
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_BASE_R;
1661
+ break;
1662
+ case FEC_FORCE_MODE_RS:
1663
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528;
1664
+ break;
1665
+ case FEC_FORCE_MODE_AUTO:
1666
+ link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528 |
1667
+ ETH_EXT_FEC_100G_BASE_R |
1668
+ ETH_EXT_FEC_100G_NONE;
1669
+ break;
1670
+ default:
1671
+ break;
1672
+ }
1673
+
1674
+ break;
1675
+ default:
1676
+ break;
1677
+ }
1678
+}
1679
+
13101680 static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
13111681 {
1312
- struct qed_hwfn *hwfn;
13131682 struct qed_mcp_link_params *link_params;
1683
+ struct qed_mcp_link_speed_params *speed;
1684
+ const struct qed_mfw_speed_map *map;
1685
+ struct qed_hwfn *hwfn;
13141686 struct qed_ptt *ptt;
13151687 int rc;
1688
+ u32 i;
13161689
13171690 if (!cdev)
13181691 return -ENODEV;
....@@ -1334,32 +1707,31 @@
13341707 return -EBUSY;
13351708
13361709 link_params = qed_mcp_get_link_params(hwfn);
1710
+ if (!link_params)
1711
+ return -ENODATA;
1712
+
1713
+ speed = &link_params->speed;
1714
+
13371715 if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
1338
- link_params->speed.autoneg = params->autoneg;
1716
+ speed->autoneg = !!params->autoneg;
1717
+
13391718 if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
1340
- link_params->speed.advertised_speeds = 0;
1341
- if ((params->adv_speeds & QED_LM_1000baseT_Half_BIT) ||
1342
- (params->adv_speeds & QED_LM_1000baseT_Full_BIT))
1343
- link_params->speed.advertised_speeds |=
1344
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
1345
- if (params->adv_speeds & QED_LM_10000baseKR_Full_BIT)
1346
- link_params->speed.advertised_speeds |=
1347
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
1348
- if (params->adv_speeds & QED_LM_25000baseKR_Full_BIT)
1349
- link_params->speed.advertised_speeds |=
1350
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
1351
- if (params->adv_speeds & QED_LM_40000baseLR4_Full_BIT)
1352
- link_params->speed.advertised_speeds |=
1353
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
1354
- if (params->adv_speeds & QED_LM_50000baseKR2_Full_BIT)
1355
- link_params->speed.advertised_speeds |=
1356
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
1357
- if (params->adv_speeds & QED_LM_100000baseKR4_Full_BIT)
1358
- link_params->speed.advertised_speeds |=
1359
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
1719
+ speed->advertised_speeds = 0;
1720
+
1721
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++) {
1722
+ map = qed_mfw_legacy_maps + i;
1723
+
1724
+ if (linkmode_intersects(params->adv_speeds, map->caps))
1725
+ speed->advertised_speeds |= map->mfw_val;
1726
+ }
13601727 }
1728
+
13611729 if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED)
1362
- link_params->speed.forced_speed = params->forced_speed;
1730
+ speed->forced_speed = params->forced_speed;
1731
+
1732
+ if (qed_mcp_is_ext_speed_supported(hwfn))
1733
+ qed_set_ext_speed_params(link_params, params);
1734
+
13631735 if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
13641736 if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
13651737 link_params->pause.autoneg = true;
....@@ -1374,6 +1746,7 @@
13741746 else
13751747 link_params->pause.forced_tx = false;
13761748 }
1749
+
13771750 if (params->override_flags & QED_LINK_OVERRIDE_LOOPBACK_MODE) {
13781751 switch (params->loopback_mode) {
13791752 case QED_LINK_LOOPBACK_INT_PHY:
....@@ -1388,6 +1761,25 @@
13881761 case QED_LINK_LOOPBACK_MAC:
13891762 link_params->loopback_mode = ETH_LOOPBACK_MAC;
13901763 break;
1764
+ case QED_LINK_LOOPBACK_CNIG_AH_ONLY_0123:
1765
+ link_params->loopback_mode =
1766
+ ETH_LOOPBACK_CNIG_AH_ONLY_0123;
1767
+ break;
1768
+ case QED_LINK_LOOPBACK_CNIG_AH_ONLY_2301:
1769
+ link_params->loopback_mode =
1770
+ ETH_LOOPBACK_CNIG_AH_ONLY_2301;
1771
+ break;
1772
+ case QED_LINK_LOOPBACK_PCS_AH_ONLY:
1773
+ link_params->loopback_mode = ETH_LOOPBACK_PCS_AH_ONLY;
1774
+ break;
1775
+ case QED_LINK_LOOPBACK_REVERSE_MAC_AH_ONLY:
1776
+ link_params->loopback_mode =
1777
+ ETH_LOOPBACK_REVERSE_MAC_AH_ONLY;
1778
+ break;
1779
+ case QED_LINK_LOOPBACK_INT_PHY_FEA_AH_ONLY:
1780
+ link_params->loopback_mode =
1781
+ ETH_LOOPBACK_INT_PHY_FEA_AH_ONLY;
1782
+ break;
13911783 default:
13921784 link_params->loopback_mode = ETH_LOOPBACK_NONE;
13931785 break;
....@@ -1397,6 +1789,9 @@
13971789 if (params->override_flags & QED_LINK_OVERRIDE_EEE_CONFIG)
13981790 memcpy(&link_params->eee, &params->eee,
13991791 sizeof(link_params->eee));
1792
+
1793
+ if (params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG)
1794
+ link_params->fec = params->fec;
14001795
14011796 rc = qed_mcp_set_link(hwfn, ptt, params->link_up);
14021797
....@@ -1414,7 +1809,6 @@
14141809 case MEDIA_SFP_1G_FIBER:
14151810 case MEDIA_XFP_FIBER:
14161811 case MEDIA_MODULE_FIBER:
1417
- case MEDIA_KR:
14181812 port_type = PORT_FIBRE;
14191813 break;
14201814 case MEDIA_DA_TWINAX:
....@@ -1423,6 +1817,7 @@
14231817 case MEDIA_BASE_T:
14241818 port_type = PORT_TP;
14251819 break;
1820
+ case MEDIA_KR:
14261821 case MEDIA_NOT_PRESENT:
14271822 port_type = PORT_NONE;
14281823 break;
....@@ -1467,14 +1862,248 @@
14671862 return 0;
14681863 }
14691864
1865
+static void qed_fill_link_capability(struct qed_hwfn *hwfn,
1866
+ struct qed_ptt *ptt, u32 capability,
1867
+ unsigned long *if_caps)
1868
+{
1869
+ u32 media_type, tcvr_state, tcvr_type;
1870
+ u32 speed_mask, board_cfg;
1871
+
1872
+ if (qed_mcp_get_media_type(hwfn, ptt, &media_type))
1873
+ media_type = MEDIA_UNSPECIFIED;
1874
+
1875
+ if (qed_mcp_get_transceiver_data(hwfn, ptt, &tcvr_state, &tcvr_type))
1876
+ tcvr_type = ETH_TRANSCEIVER_STATE_UNPLUGGED;
1877
+
1878
+ if (qed_mcp_trans_speed_mask(hwfn, ptt, &speed_mask))
1879
+ speed_mask = 0xFFFFFFFF;
1880
+
1881
+ if (qed_mcp_get_board_config(hwfn, ptt, &board_cfg))
1882
+ board_cfg = NVM_CFG1_PORT_PORT_TYPE_UNDEFINED;
1883
+
1884
+ DP_VERBOSE(hwfn->cdev, NETIF_MSG_DRV,
1885
+ "Media_type = 0x%x tcvr_state = 0x%x tcvr_type = 0x%x speed_mask = 0x%x board_cfg = 0x%x\n",
1886
+ media_type, tcvr_state, tcvr_type, speed_mask, board_cfg);
1887
+
1888
+ switch (media_type) {
1889
+ case MEDIA_DA_TWINAX:
1890
+ phylink_set(if_caps, FIBRE);
1891
+
1892
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
1893
+ phylink_set(if_caps, 20000baseKR2_Full);
1894
+
1895
+ /* For DAC media multiple speed capabilities are supported */
1896
+ capability |= speed_mask;
1897
+
1898
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
1899
+ phylink_set(if_caps, 1000baseKX_Full);
1900
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
1901
+ phylink_set(if_caps, 10000baseCR_Full);
1902
+
1903
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
1904
+ switch (tcvr_type) {
1905
+ case ETH_TRANSCEIVER_TYPE_40G_CR4:
1906
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
1907
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
1908
+ phylink_set(if_caps, 40000baseCR4_Full);
1909
+ break;
1910
+ default:
1911
+ break;
1912
+ }
1913
+
1914
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
1915
+ phylink_set(if_caps, 25000baseCR_Full);
1916
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
1917
+ phylink_set(if_caps, 50000baseCR2_Full);
1918
+
1919
+ if (capability &
1920
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
1921
+ switch (tcvr_type) {
1922
+ case ETH_TRANSCEIVER_TYPE_100G_CR4:
1923
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
1924
+ phylink_set(if_caps, 100000baseCR4_Full);
1925
+ break;
1926
+ default:
1927
+ break;
1928
+ }
1929
+
1930
+ break;
1931
+ case MEDIA_BASE_T:
1932
+ phylink_set(if_caps, TP);
1933
+
1934
+ if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_EXT_PHY) {
1935
+ if (capability &
1936
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
1937
+ phylink_set(if_caps, 1000baseT_Full);
1938
+ if (capability &
1939
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
1940
+ phylink_set(if_caps, 10000baseT_Full);
1941
+ }
1942
+
1943
+ if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
1944
+ phylink_set(if_caps, FIBRE);
1945
+
1946
+ switch (tcvr_type) {
1947
+ case ETH_TRANSCEIVER_TYPE_1000BASET:
1948
+ phylink_set(if_caps, 1000baseT_Full);
1949
+ break;
1950
+ case ETH_TRANSCEIVER_TYPE_10G_BASET:
1951
+ phylink_set(if_caps, 10000baseT_Full);
1952
+ break;
1953
+ default:
1954
+ break;
1955
+ }
1956
+ }
1957
+
1958
+ break;
1959
+ case MEDIA_SFP_1G_FIBER:
1960
+ case MEDIA_SFPP_10G_FIBER:
1961
+ case MEDIA_XFP_FIBER:
1962
+ case MEDIA_MODULE_FIBER:
1963
+ phylink_set(if_caps, FIBRE);
1964
+ capability |= speed_mask;
1965
+
1966
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
1967
+ switch (tcvr_type) {
1968
+ case ETH_TRANSCEIVER_TYPE_1G_LX:
1969
+ case ETH_TRANSCEIVER_TYPE_1G_SX:
1970
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
1971
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
1972
+ phylink_set(if_caps, 1000baseKX_Full);
1973
+ break;
1974
+ default:
1975
+ break;
1976
+ }
1977
+
1978
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
1979
+ switch (tcvr_type) {
1980
+ case ETH_TRANSCEIVER_TYPE_10G_SR:
1981
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
1982
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
1983
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
1984
+ phylink_set(if_caps, 10000baseSR_Full);
1985
+ break;
1986
+ case ETH_TRANSCEIVER_TYPE_10G_LR:
1987
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
1988
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
1989
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
1990
+ phylink_set(if_caps, 10000baseLR_Full);
1991
+ break;
1992
+ case ETH_TRANSCEIVER_TYPE_10G_LRM:
1993
+ phylink_set(if_caps, 10000baseLRM_Full);
1994
+ break;
1995
+ case ETH_TRANSCEIVER_TYPE_10G_ER:
1996
+ phylink_set(if_caps, 10000baseR_FEC);
1997
+ break;
1998
+ default:
1999
+ break;
2000
+ }
2001
+
2002
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
2003
+ phylink_set(if_caps, 20000baseKR2_Full);
2004
+
2005
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
2006
+ switch (tcvr_type) {
2007
+ case ETH_TRANSCEIVER_TYPE_25G_SR:
2008
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
2009
+ phylink_set(if_caps, 25000baseSR_Full);
2010
+ break;
2011
+ default:
2012
+ break;
2013
+ }
2014
+
2015
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
2016
+ switch (tcvr_type) {
2017
+ case ETH_TRANSCEIVER_TYPE_40G_LR4:
2018
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
2019
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
2020
+ phylink_set(if_caps, 40000baseLR4_Full);
2021
+ break;
2022
+ case ETH_TRANSCEIVER_TYPE_40G_SR4:
2023
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
2024
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
2025
+ phylink_set(if_caps, 40000baseSR4_Full);
2026
+ break;
2027
+ default:
2028
+ break;
2029
+ }
2030
+
2031
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
2032
+ phylink_set(if_caps, 50000baseKR2_Full);
2033
+
2034
+ if (capability &
2035
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
2036
+ switch (tcvr_type) {
2037
+ case ETH_TRANSCEIVER_TYPE_100G_SR4:
2038
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
2039
+ phylink_set(if_caps, 100000baseSR4_Full);
2040
+ break;
2041
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
2042
+ phylink_set(if_caps, 100000baseLR4_ER4_Full);
2043
+ break;
2044
+ default:
2045
+ break;
2046
+ }
2047
+
2048
+ break;
2049
+ case MEDIA_KR:
2050
+ phylink_set(if_caps, Backplane);
2051
+
2052
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
2053
+ phylink_set(if_caps, 20000baseKR2_Full);
2054
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
2055
+ phylink_set(if_caps, 1000baseKX_Full);
2056
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
2057
+ phylink_set(if_caps, 10000baseKR_Full);
2058
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
2059
+ phylink_set(if_caps, 25000baseKR_Full);
2060
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
2061
+ phylink_set(if_caps, 40000baseKR4_Full);
2062
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
2063
+ phylink_set(if_caps, 50000baseKR2_Full);
2064
+ if (capability &
2065
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
2066
+ phylink_set(if_caps, 100000baseKR4_Full);
2067
+
2068
+ break;
2069
+ case MEDIA_UNSPECIFIED:
2070
+ case MEDIA_NOT_PRESENT:
2071
+ default:
2072
+ DP_VERBOSE(hwfn->cdev, QED_MSG_DEBUG,
2073
+ "Unknown media and transceiver type;\n");
2074
+ break;
2075
+ }
2076
+}
2077
+
2078
+static void qed_lp_caps_to_speed_mask(u32 caps, u32 *speed_mask)
2079
+{
2080
+ *speed_mask = 0;
2081
+
2082
+ if (caps &
2083
+ (QED_LINK_PARTNER_SPEED_1G_FD | QED_LINK_PARTNER_SPEED_1G_HD))
2084
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
2085
+ if (caps & QED_LINK_PARTNER_SPEED_10G)
2086
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
2087
+ if (caps & QED_LINK_PARTNER_SPEED_20G)
2088
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
2089
+ if (caps & QED_LINK_PARTNER_SPEED_25G)
2090
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
2091
+ if (caps & QED_LINK_PARTNER_SPEED_40G)
2092
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
2093
+ if (caps & QED_LINK_PARTNER_SPEED_50G)
2094
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
2095
+ if (caps & QED_LINK_PARTNER_SPEED_100G)
2096
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
2097
+}
2098
+
14702099 static void qed_fill_link(struct qed_hwfn *hwfn,
14712100 struct qed_ptt *ptt,
14722101 struct qed_link_output *if_link)
14732102 {
2103
+ struct qed_mcp_link_capabilities link_caps;
14742104 struct qed_mcp_link_params params;
14752105 struct qed_mcp_link_state link;
1476
- struct qed_mcp_link_capabilities link_caps;
1477
- u32 media_type;
2106
+ u32 media_type, speed_mask;
14782107
14792108 memset(if_link, 0, sizeof(*if_link));
14802109
....@@ -1488,61 +2117,53 @@
14882117 if (link.link_up)
14892118 if_link->link_up = true;
14902119
1491
- /* TODO - at the moment assume supported and advertised speed equal */
1492
- if_link->supported_caps = QED_LM_FIBRE_BIT;
1493
- if (link_caps.default_speed_autoneg)
1494
- if_link->supported_caps |= QED_LM_Autoneg_BIT;
2120
+ if (IS_PF(hwfn->cdev) && qed_mcp_is_ext_speed_supported(hwfn)) {
2121
+ if (link_caps.default_ext_autoneg)
2122
+ phylink_set(if_link->supported_caps, Autoneg);
2123
+
2124
+ linkmode_copy(if_link->advertised_caps, if_link->supported_caps);
2125
+
2126
+ if (params.ext_speed.autoneg)
2127
+ phylink_set(if_link->advertised_caps, Autoneg);
2128
+ else
2129
+ phylink_clear(if_link->advertised_caps, Autoneg);
2130
+
2131
+ qed_fill_link_capability(hwfn, ptt,
2132
+ params.ext_speed.advertised_speeds,
2133
+ if_link->advertised_caps);
2134
+ } else {
2135
+ if (link_caps.default_speed_autoneg)
2136
+ phylink_set(if_link->supported_caps, Autoneg);
2137
+
2138
+ linkmode_copy(if_link->advertised_caps, if_link->supported_caps);
2139
+
2140
+ if (params.speed.autoneg)
2141
+ phylink_set(if_link->advertised_caps, Autoneg);
2142
+ else
2143
+ phylink_clear(if_link->advertised_caps, Autoneg);
2144
+ }
2145
+
14952146 if (params.pause.autoneg ||
14962147 (params.pause.forced_rx && params.pause.forced_tx))
1497
- if_link->supported_caps |= QED_LM_Asym_Pause_BIT;
2148
+ phylink_set(if_link->supported_caps, Asym_Pause);
14982149 if (params.pause.autoneg || params.pause.forced_rx ||
14992150 params.pause.forced_tx)
1500
- if_link->supported_caps |= QED_LM_Pause_BIT;
2151
+ phylink_set(if_link->supported_caps, Pause);
15012152
1502
- if_link->advertised_caps = if_link->supported_caps;
1503
- if (params.speed.autoneg)
1504
- if_link->advertised_caps |= QED_LM_Autoneg_BIT;
1505
- else
1506
- if_link->advertised_caps &= ~QED_LM_Autoneg_BIT;
1507
- if (params.speed.advertised_speeds &
1508
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
1509
- if_link->advertised_caps |= QED_LM_1000baseT_Half_BIT |
1510
- QED_LM_1000baseT_Full_BIT;
1511
- if (params.speed.advertised_speeds &
1512
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
1513
- if_link->advertised_caps |= QED_LM_10000baseKR_Full_BIT;
1514
- if (params.speed.advertised_speeds &
1515
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
1516
- if_link->advertised_caps |= QED_LM_25000baseKR_Full_BIT;
1517
- if (params.speed.advertised_speeds &
1518
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
1519
- if_link->advertised_caps |= QED_LM_40000baseLR4_Full_BIT;
1520
- if (params.speed.advertised_speeds &
1521
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
1522
- if_link->advertised_caps |= QED_LM_50000baseKR2_Full_BIT;
1523
- if (params.speed.advertised_speeds &
1524
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
1525
- if_link->advertised_caps |= QED_LM_100000baseKR4_Full_BIT;
2153
+ if_link->sup_fec = link_caps.fec_default;
2154
+ if_link->active_fec = params.fec;
15262155
1527
- if (link_caps.speed_capabilities &
1528
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
1529
- if_link->supported_caps |= QED_LM_1000baseT_Half_BIT |
1530
- QED_LM_1000baseT_Full_BIT;
1531
- if (link_caps.speed_capabilities &
1532
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
1533
- if_link->supported_caps |= QED_LM_10000baseKR_Full_BIT;
1534
- if (link_caps.speed_capabilities &
1535
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
1536
- if_link->supported_caps |= QED_LM_25000baseKR_Full_BIT;
1537
- if (link_caps.speed_capabilities &
1538
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
1539
- if_link->supported_caps |= QED_LM_40000baseLR4_Full_BIT;
1540
- if (link_caps.speed_capabilities &
1541
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
1542
- if_link->supported_caps |= QED_LM_50000baseKR2_Full_BIT;
1543
- if (link_caps.speed_capabilities &
1544
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
1545
- if_link->supported_caps |= QED_LM_100000baseKR4_Full_BIT;
2156
+ /* Fill link advertised capability */
2157
+ qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds,
2158
+ if_link->advertised_caps);
2159
+
2160
+ /* Fill link supported capability */
2161
+ qed_fill_link_capability(hwfn, ptt, link_caps.speed_capabilities,
2162
+ if_link->supported_caps);
2163
+
2164
+ /* Fill partner advertised capability */
2165
+ qed_lp_caps_to_speed_mask(link.partner_adv_speed, &speed_mask);
2166
+ qed_fill_link_capability(hwfn, ptt, speed_mask, if_link->lp_caps);
15462167
15472168 if (link.link_up)
15482169 if_link->speed = link.speed;
....@@ -1561,30 +2182,13 @@
15612182 if (params.pause.forced_tx)
15622183 if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;
15632184
1564
- /* Link partner capabilities */
1565
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_HD)
1566
- if_link->lp_caps |= QED_LM_1000baseT_Half_BIT;
1567
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_FD)
1568
- if_link->lp_caps |= QED_LM_1000baseT_Full_BIT;
1569
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G)
1570
- if_link->lp_caps |= QED_LM_10000baseKR_Full_BIT;
1571
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_25G)
1572
- if_link->lp_caps |= QED_LM_25000baseKR_Full_BIT;
1573
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_40G)
1574
- if_link->lp_caps |= QED_LM_40000baseLR4_Full_BIT;
1575
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_50G)
1576
- if_link->lp_caps |= QED_LM_50000baseKR2_Full_BIT;
1577
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_100G)
1578
- if_link->lp_caps |= QED_LM_100000baseKR4_Full_BIT;
1579
-
15802185 if (link.an_complete)
1581
- if_link->lp_caps |= QED_LM_Autoneg_BIT;
1582
-
2186
+ phylink_set(if_link->lp_caps, Autoneg);
15832187 if (link.partner_adv_pause)
1584
- if_link->lp_caps |= QED_LM_Pause_BIT;
2188
+ phylink_set(if_link->lp_caps, Pause);
15852189 if (link.partner_adv_pause == QED_LINK_PARTNER_ASYMMETRIC_PAUSE ||
15862190 link.partner_adv_pause == QED_LINK_PARTNER_BOTH_PAUSE)
1587
- if_link->lp_caps |= QED_LM_Asym_Pause_BIT;
2191
+ phylink_set(if_link->lp_caps, Asym_Pause);
15882192
15892193 if (link_caps.default_eee == QED_MCP_EEE_UNSUPPORTED) {
15902194 if_link->eee_supported = false;
....@@ -1639,6 +2243,15 @@
16392243 op->link_update(cookie, &if_link);
16402244 }
16412245
2246
+void qed_bw_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt)
2247
+{
2248
+ void *cookie = hwfn->cdev->ops_cookie;
2249
+ struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common;
2250
+
2251
+ if (IS_LEAD_HWFN(hwfn) && cookie && op && op->bw_update)
2252
+ op->bw_update(cookie);
2253
+}
2254
+
16422255 static int qed_drain(struct qed_dev *cdev)
16432256 {
16442257 struct qed_hwfn *hwfn;
....@@ -1669,8 +2282,7 @@
16692282 u32 *crc)
16702283 {
16712284 u8 *buf = NULL;
1672
- int rc, j;
1673
- u32 val;
2285
+ int rc;
16742286
16752287 /* Allocate a buffer for holding the nvram image */
16762288 buf = kzalloc(nvm_image->length, GFP_KERNEL);
....@@ -1688,15 +2300,14 @@
16882300 /* Convert the buffer into big-endian format (excluding the
16892301 * closing 4 bytes of CRC).
16902302 */
1691
- for (j = 0; j < nvm_image->length - 4; j += 4) {
1692
- val = cpu_to_be32(*(u32 *)&buf[j]);
1693
- *(u32 *)&buf[j] = val;
1694
- }
2303
+ cpu_to_be32_array((__force __be32 *)buf, (const u32 *)buf,
2304
+ DIV_ROUND_UP(nvm_image->length - 4, 4));
16952305
16962306 /* Calc CRC for the "actual" image buffer, i.e. not including
16972307 * the last 4 CRC bytes.
16982308 */
1699
- *crc = (~cpu_to_be32(crc32(0xffffffff, buf, nvm_image->length - 4)));
2309
+ *crc = ~crc32(~0U, buf, nvm_image->length - 4);
2310
+ *crc = (__force u32)cpu_to_be32p(crc);
17002311
17012312 out:
17022313 kfree(buf);
....@@ -1813,21 +2424,30 @@
18132424 * 0B | 0x3 [command index] |
18142425 * 4B | b'0: check_response? | b'1-31 reserved |
18152426 * 8B | File-type | reserved |
2427
+ * 12B | Image length in bytes |
18162428 * \----------------------------------------------------------------------/
18172429 * Start a new file of the provided type
18182430 */
18192431 static int qed_nvm_flash_image_file_start(struct qed_dev *cdev,
18202432 const u8 **data, bool *check_resp)
18212433 {
2434
+ u32 file_type, file_size = 0;
18222435 int rc;
18232436
18242437 *data += 4;
18252438 *check_resp = !!(**data & BIT(0));
18262439 *data += 4;
2440
+ file_type = **data;
18272441
18282442 DP_VERBOSE(cdev, NETIF_MSG_DRV,
1829
- "About to start a new file of type %02x\n", **data);
1830
- rc = qed_mcp_nvm_put_file_begin(cdev, **data);
2443
+ "About to start a new file of type %02x\n", file_type);
2444
+ if (file_type == DRV_MB_PARAM_NVM_PUT_FILE_BEGIN_MBI) {
2445
+ *data += 4;
2446
+ file_size = *((u32 *)(*data));
2447
+ }
2448
+
2449
+ rc = qed_mcp_nvm_write(cdev, QED_PUT_FILE_BEGIN, file_type,
2450
+ (u8 *)(&file_size), 4);
18312451 *data += 4;
18322452
18332453 return rc;
....@@ -1917,6 +2537,135 @@
19172537 return 0;
19182538 }
19192539
2540
+/* Binary file format -
2541
+ * /----------------------------------------------------------------------\
2542
+ * 0B | 0x5 [command index] |
2543
+ * 4B | Number of config attributes | Reserved |
2544
+ * 4B | Config ID | Entity ID | Length |
2545
+ * 4B | Value |
2546
+ * | |
2547
+ * \----------------------------------------------------------------------/
2548
+ * There can be several cfg_id-entity_id-Length-Value sets as specified by
2549
+ * 'Number of config attributes'.
2550
+ *
2551
+ * The API parses config attributes from the user provided buffer and flashes
2552
+ * them to the respective NVM path using Management FW inerface.
2553
+ */
2554
+static int qed_nvm_flash_cfg_write(struct qed_dev *cdev, const u8 **data)
2555
+{
2556
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2557
+ u8 entity_id, len, buf[32];
2558
+ bool need_nvm_init = true;
2559
+ struct qed_ptt *ptt;
2560
+ u16 cfg_id, count;
2561
+ int rc = 0, i;
2562
+ u32 flags;
2563
+
2564
+ ptt = qed_ptt_acquire(hwfn);
2565
+ if (!ptt)
2566
+ return -EAGAIN;
2567
+
2568
+ /* NVM CFG ID attribute header */
2569
+ *data += 4;
2570
+ count = *((u16 *)*data);
2571
+ *data += 4;
2572
+
2573
+ DP_VERBOSE(cdev, NETIF_MSG_DRV,
2574
+ "Read config ids: num_attrs = %0d\n", count);
2575
+ /* NVM CFG ID attributes. Start loop index from 1 to avoid additional
2576
+ * arithmetic operations in the implementation.
2577
+ */
2578
+ for (i = 1; i <= count; i++) {
2579
+ cfg_id = *((u16 *)*data);
2580
+ *data += 2;
2581
+ entity_id = **data;
2582
+ (*data)++;
2583
+ len = **data;
2584
+ (*data)++;
2585
+ memcpy(buf, *data, len);
2586
+ *data += len;
2587
+
2588
+ flags = 0;
2589
+ if (need_nvm_init) {
2590
+ flags |= QED_NVM_CFG_OPTION_INIT;
2591
+ need_nvm_init = false;
2592
+ }
2593
+
2594
+ /* Commit to flash and free the resources */
2595
+ if (!(i % QED_NVM_CFG_MAX_ATTRS) || i == count) {
2596
+ flags |= QED_NVM_CFG_OPTION_COMMIT |
2597
+ QED_NVM_CFG_OPTION_FREE;
2598
+ need_nvm_init = true;
2599
+ }
2600
+
2601
+ if (entity_id)
2602
+ flags |= QED_NVM_CFG_OPTION_ENTITY_SEL;
2603
+
2604
+ DP_VERBOSE(cdev, NETIF_MSG_DRV,
2605
+ "cfg_id = %d entity = %d len = %d\n", cfg_id,
2606
+ entity_id, len);
2607
+ rc = qed_mcp_nvm_set_cfg(hwfn, ptt, cfg_id, entity_id, flags,
2608
+ buf, len);
2609
+ if (rc) {
2610
+ DP_ERR(cdev, "Error %d configuring %d\n", rc, cfg_id);
2611
+ break;
2612
+ }
2613
+ }
2614
+
2615
+ qed_ptt_release(hwfn, ptt);
2616
+
2617
+ return rc;
2618
+}
2619
+
2620
+#define QED_MAX_NVM_BUF_LEN 32
2621
+static int qed_nvm_flash_cfg_len(struct qed_dev *cdev, u32 cmd)
2622
+{
2623
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2624
+ u8 buf[QED_MAX_NVM_BUF_LEN];
2625
+ struct qed_ptt *ptt;
2626
+ u32 len;
2627
+ int rc;
2628
+
2629
+ ptt = qed_ptt_acquire(hwfn);
2630
+ if (!ptt)
2631
+ return QED_MAX_NVM_BUF_LEN;
2632
+
2633
+ rc = qed_mcp_nvm_get_cfg(hwfn, ptt, cmd, 0, QED_NVM_CFG_GET_FLAGS, buf,
2634
+ &len);
2635
+ if (rc || !len) {
2636
+ DP_ERR(cdev, "Error %d reading %d\n", rc, cmd);
2637
+ len = QED_MAX_NVM_BUF_LEN;
2638
+ }
2639
+
2640
+ qed_ptt_release(hwfn, ptt);
2641
+
2642
+ return len;
2643
+}
2644
+
2645
+static int qed_nvm_flash_cfg_read(struct qed_dev *cdev, u8 **data,
2646
+ u32 cmd, u32 entity_id)
2647
+{
2648
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2649
+ struct qed_ptt *ptt;
2650
+ u32 flags, len;
2651
+ int rc = 0;
2652
+
2653
+ ptt = qed_ptt_acquire(hwfn);
2654
+ if (!ptt)
2655
+ return -EAGAIN;
2656
+
2657
+ DP_VERBOSE(cdev, NETIF_MSG_DRV,
2658
+ "Read config cmd = %d entity id %d\n", cmd, entity_id);
2659
+ flags = entity_id ? QED_NVM_CFG_GET_PF_FLAGS : QED_NVM_CFG_GET_FLAGS;
2660
+ rc = qed_mcp_nvm_get_cfg(hwfn, ptt, cmd, entity_id, flags, *data, &len);
2661
+ if (rc)
2662
+ DP_ERR(cdev, "Error %d reading %d\n", rc, cmd);
2663
+
2664
+ qed_ptt_release(hwfn, ptt);
2665
+
2666
+ return rc;
2667
+}
2668
+
19202669 static int qed_nvm_flash(struct qed_dev *cdev, const char *name)
19212670 {
19222671 const struct firmware *image;
....@@ -1957,6 +2706,9 @@
19572706 case QED_NVM_FLASH_CMD_NVM_CHANGE:
19582707 rc = qed_nvm_flash_image_access(cdev, &data,
19592708 &check_resp);
2709
+ break;
2710
+ case QED_NVM_FLASH_CMD_NVM_CFG_ID:
2711
+ rc = qed_nvm_flash_cfg_write(cdev, &data);
19602712 break;
19612713 default:
19622714 DP_ERR(cdev, "Unknown command %08x\n", cmd_type);
....@@ -2008,6 +2760,48 @@
20082760 return qed_mcp_get_nvm_image(hwfn, type, buf, len);
20092761 }
20102762
2763
+void qed_schedule_recovery_handler(struct qed_hwfn *p_hwfn)
2764
+{
2765
+ struct qed_common_cb_ops *ops = p_hwfn->cdev->protocol_ops.common;
2766
+ void *cookie = p_hwfn->cdev->ops_cookie;
2767
+
2768
+ if (ops && ops->schedule_recovery_handler)
2769
+ ops->schedule_recovery_handler(cookie);
2770
+}
2771
+
2772
+static const char * const qed_hw_err_type_descr[] = {
2773
+ [QED_HW_ERR_FAN_FAIL] = "Fan Failure",
2774
+ [QED_HW_ERR_MFW_RESP_FAIL] = "MFW Response Failure",
2775
+ [QED_HW_ERR_HW_ATTN] = "HW Attention",
2776
+ [QED_HW_ERR_DMAE_FAIL] = "DMAE Failure",
2777
+ [QED_HW_ERR_RAMROD_FAIL] = "Ramrod Failure",
2778
+ [QED_HW_ERR_FW_ASSERT] = "FW Assertion",
2779
+ [QED_HW_ERR_LAST] = "Unknown",
2780
+};
2781
+
2782
+void qed_hw_error_occurred(struct qed_hwfn *p_hwfn,
2783
+ enum qed_hw_err_type err_type)
2784
+{
2785
+ struct qed_common_cb_ops *ops = p_hwfn->cdev->protocol_ops.common;
2786
+ void *cookie = p_hwfn->cdev->ops_cookie;
2787
+ const char *err_str;
2788
+
2789
+ if (err_type > QED_HW_ERR_LAST)
2790
+ err_type = QED_HW_ERR_LAST;
2791
+ err_str = qed_hw_err_type_descr[err_type];
2792
+
2793
+ DP_NOTICE(p_hwfn, "HW error occurred [%s]\n", err_str);
2794
+
2795
+ /* Call the HW error handler of the protocol driver.
2796
+ * If it is not available - perform a minimal handling of preventing
2797
+ * HW attentions from being reasserted.
2798
+ */
2799
+ if (ops && ops->schedule_hw_err_handler)
2800
+ ops->schedule_hw_err_handler(cookie, err_type);
2801
+ else
2802
+ qed_int_attn_clr_enable(p_hwfn->cdev, true);
2803
+}
2804
+
20112805 static int qed_set_coalesce(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal,
20122806 void *handle)
20132807 {
....@@ -2029,6 +2823,23 @@
20292823 qed_ptt_release(hwfn, ptt);
20302824
20312825 return status;
2826
+}
2827
+
2828
+int qed_recovery_process(struct qed_dev *cdev)
2829
+{
2830
+ struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
2831
+ struct qed_ptt *p_ptt;
2832
+ int rc = 0;
2833
+
2834
+ p_ptt = qed_ptt_acquire(p_hwfn);
2835
+ if (!p_ptt)
2836
+ return -EAGAIN;
2837
+
2838
+ rc = qed_start_recovery_process(p_hwfn, p_ptt);
2839
+
2840
+ qed_ptt_release(p_hwfn, p_ptt);
2841
+
2842
+ return rc;
20322843 }
20332844
20342845 static int qed_update_wol(struct qed_dev *cdev, bool enabled)
....@@ -2147,6 +2958,31 @@
21472958 return rc;
21482959 }
21492960
2961
+static int qed_set_grc_config(struct qed_dev *cdev, u32 cfg_id, u32 val)
2962
+{
2963
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2964
+ struct qed_ptt *ptt;
2965
+ int rc = 0;
2966
+
2967
+ if (IS_VF(cdev))
2968
+ return 0;
2969
+
2970
+ ptt = qed_ptt_acquire(hwfn);
2971
+ if (!ptt)
2972
+ return -EAGAIN;
2973
+
2974
+ rc = qed_dbg_grc_config(hwfn, cfg_id, val);
2975
+
2976
+ qed_ptt_release(hwfn, ptt);
2977
+
2978
+ return rc;
2979
+}
2980
+
2981
+static u8 qed_get_affin_hwfn_idx(struct qed_dev *cdev)
2982
+{
2983
+ return QED_AFFIN_HWFN_IDX(cdev);
2984
+}
2985
+
21502986 static struct qed_selftest_ops qed_selftest_ops_pass = {
21512987 .selftest_memory = &qed_selftest_memory,
21522988 .selftest_interrupt = &qed_selftest_interrupt,
....@@ -2177,6 +3013,9 @@
21773013 .get_link = &qed_get_current_link,
21783014 .drain = &qed_drain,
21793015 .update_msglvl = &qed_init_dp,
3016
+ .devlink_register = qed_devlink_register,
3017
+ .devlink_unregister = qed_devlink_unregister,
3018
+ .report_fatal_error = qed_report_fatal_error,
21803019 .dbg_all_data = &qed_dbg_all_data,
21813020 .dbg_all_data_size = &qed_dbg_all_data_size,
21823021 .chain_alloc = &qed_chain_alloc,
....@@ -2185,11 +3024,20 @@
21853024 .nvm_get_image = &qed_nvm_get_image,
21863025 .set_coalesce = &qed_set_coalesce,
21873026 .set_led = &qed_set_led,
3027
+ .recovery_process = &qed_recovery_process,
3028
+ .recovery_prolog = &qed_recovery_prolog,
3029
+ .attn_clr_enable = &qed_int_attn_clr_enable,
21883030 .update_drv_state = &qed_update_drv_state,
21893031 .update_mac = &qed_update_mac,
21903032 .update_mtu = &qed_update_mtu,
21913033 .update_wol = &qed_update_wol,
3034
+ .db_recovery_add = &qed_db_recovery_add,
3035
+ .db_recovery_del = &qed_db_recovery_del,
21923036 .read_module_eeprom = &qed_read_module_eeprom,
3037
+ .get_affin_hwfn_idx = &qed_get_affin_hwfn_idx,
3038
+ .read_nvm_cfg = &qed_nvm_flash_cfg_read,
3039
+ .read_nvm_cfg_len = &qed_nvm_flash_cfg_len,
3040
+ .set_grc_config = &qed_set_grc_config,
21933041 };
21943042
21953043 void qed_get_protocol_stats(struct qed_dev *cdev,