hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/ethernet/intel/ice/ice_ethtool.c
....@@ -4,6 +4,11 @@
44 /* ethtool support for ice */
55
66 #include "ice.h"
7
+#include "ice_flow.h"
8
+#include "ice_fltr.h"
9
+#include "ice_lib.h"
10
+#include "ice_dcb_lib.h"
11
+#include <net/dcbnl.h>
712
813 struct ice_stats {
914 char stat_string[ETH_GSTRING_LEN];
....@@ -13,7 +18,7 @@
1318
1419 #define ICE_STAT(_type, _name, _stat) { \
1520 .stat_string = _name, \
16
- .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
21
+ .sizeof_stat = sizeof_field(_type, _stat), \
1722 .stat_offset = offsetof(_type, _stat) \
1823 }
1924
....@@ -33,25 +38,52 @@
3338 #define ICE_PF_STATS_LEN ARRAY_SIZE(ice_gstrings_pf_stats)
3439 #define ICE_VSI_STATS_LEN ARRAY_SIZE(ice_gstrings_vsi_stats)
3540
36
-#define ICE_ALL_STATS_LEN(n) (ICE_PF_STATS_LEN + ICE_VSI_STATS_LEN + \
37
- ice_q_stats_len(n))
41
+#define ICE_PFC_STATS_LEN ( \
42
+ (sizeof_field(struct ice_pf, stats.priority_xoff_rx) + \
43
+ sizeof_field(struct ice_pf, stats.priority_xon_rx) + \
44
+ sizeof_field(struct ice_pf, stats.priority_xoff_tx) + \
45
+ sizeof_field(struct ice_pf, stats.priority_xon_tx)) \
46
+ / sizeof(u64))
47
+#define ICE_ALL_STATS_LEN(n) (ICE_PF_STATS_LEN + ICE_PFC_STATS_LEN + \
48
+ ICE_VSI_STATS_LEN + ice_q_stats_len(n))
3849
3950 static const struct ice_stats ice_gstrings_vsi_stats[] = {
40
- ICE_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
4151 ICE_VSI_STAT("rx_unicast", eth_stats.rx_unicast),
42
- ICE_VSI_STAT("tx_multicast", eth_stats.tx_multicast),
52
+ ICE_VSI_STAT("tx_unicast", eth_stats.tx_unicast),
4353 ICE_VSI_STAT("rx_multicast", eth_stats.rx_multicast),
44
- ICE_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
54
+ ICE_VSI_STAT("tx_multicast", eth_stats.tx_multicast),
4555 ICE_VSI_STAT("rx_broadcast", eth_stats.rx_broadcast),
46
- ICE_VSI_STAT("tx_bytes", eth_stats.tx_bytes),
56
+ ICE_VSI_STAT("tx_broadcast", eth_stats.tx_broadcast),
4757 ICE_VSI_STAT("rx_bytes", eth_stats.rx_bytes),
48
- ICE_VSI_STAT("rx_discards", eth_stats.rx_discards),
49
- ICE_VSI_STAT("tx_errors", eth_stats.tx_errors),
50
- ICE_VSI_STAT("tx_linearize", tx_linearize),
58
+ ICE_VSI_STAT("tx_bytes", eth_stats.tx_bytes),
59
+ ICE_VSI_STAT("rx_dropped", eth_stats.rx_discards),
5160 ICE_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol),
5261 ICE_VSI_STAT("rx_alloc_fail", rx_buf_failed),
5362 ICE_VSI_STAT("rx_pg_alloc_fail", rx_page_failed),
63
+ ICE_VSI_STAT("rx_gro_dropped", rx_gro_dropped),
64
+ ICE_VSI_STAT("tx_errors", eth_stats.tx_errors),
65
+ ICE_VSI_STAT("tx_linearize", tx_linearize),
66
+ ICE_VSI_STAT("tx_busy", tx_busy),
67
+ ICE_VSI_STAT("tx_restart", tx_restart),
5468 };
69
+
70
+enum ice_ethtool_test_id {
71
+ ICE_ETH_TEST_REG = 0,
72
+ ICE_ETH_TEST_EEPROM,
73
+ ICE_ETH_TEST_INTR,
74
+ ICE_ETH_TEST_LOOP,
75
+ ICE_ETH_TEST_LINK,
76
+};
77
+
78
+static const char ice_gstrings_test[][ETH_GSTRING_LEN] = {
79
+ "Register test (offline)",
80
+ "EEPROM test (offline)",
81
+ "Interrupt test (offline)",
82
+ "Loopback test (offline)",
83
+ "Link test (on/offline)",
84
+};
85
+
86
+#define ICE_TEST_LEN (sizeof(ice_gstrings_test) / ETH_GSTRING_LEN)
5587
5688 /* These PF_STATs might look like duplicates of some NETDEV_STATs,
5789 * but they aren't. This device is capable of supporting multiple
....@@ -62,49 +94,52 @@
6294 * The PF_STATs are appended to the netdev stats only when ethtool -S
6395 * is queried on the base PF netdev.
6496 */
65
-static struct ice_stats ice_gstrings_pf_stats[] = {
66
- ICE_PF_STAT("tx_bytes", stats.eth.tx_bytes),
67
- ICE_PF_STAT("rx_bytes", stats.eth.rx_bytes),
68
- ICE_PF_STAT("tx_unicast", stats.eth.tx_unicast),
69
- ICE_PF_STAT("rx_unicast", stats.eth.rx_unicast),
70
- ICE_PF_STAT("tx_multicast", stats.eth.tx_multicast),
71
- ICE_PF_STAT("rx_multicast", stats.eth.rx_multicast),
72
- ICE_PF_STAT("tx_broadcast", stats.eth.tx_broadcast),
73
- ICE_PF_STAT("rx_broadcast", stats.eth.rx_broadcast),
74
- ICE_PF_STAT("tx_errors", stats.eth.tx_errors),
75
- ICE_PF_STAT("tx_size_64", stats.tx_size_64),
76
- ICE_PF_STAT("rx_size_64", stats.rx_size_64),
77
- ICE_PF_STAT("tx_size_127", stats.tx_size_127),
78
- ICE_PF_STAT("rx_size_127", stats.rx_size_127),
79
- ICE_PF_STAT("tx_size_255", stats.tx_size_255),
80
- ICE_PF_STAT("rx_size_255", stats.rx_size_255),
81
- ICE_PF_STAT("tx_size_511", stats.tx_size_511),
82
- ICE_PF_STAT("rx_size_511", stats.rx_size_511),
83
- ICE_PF_STAT("tx_size_1023", stats.tx_size_1023),
84
- ICE_PF_STAT("rx_size_1023", stats.rx_size_1023),
85
- ICE_PF_STAT("tx_size_1522", stats.tx_size_1522),
86
- ICE_PF_STAT("rx_size_1522", stats.rx_size_1522),
87
- ICE_PF_STAT("tx_size_big", stats.tx_size_big),
88
- ICE_PF_STAT("rx_size_big", stats.rx_size_big),
89
- ICE_PF_STAT("link_xon_tx", stats.link_xon_tx),
90
- ICE_PF_STAT("link_xon_rx", stats.link_xon_rx),
91
- ICE_PF_STAT("link_xoff_tx", stats.link_xoff_tx),
92
- ICE_PF_STAT("link_xoff_rx", stats.link_xoff_rx),
93
- ICE_PF_STAT("tx_dropped_link_down", stats.tx_dropped_link_down),
94
- ICE_PF_STAT("rx_undersize", stats.rx_undersize),
95
- ICE_PF_STAT("rx_fragments", stats.rx_fragments),
96
- ICE_PF_STAT("rx_oversize", stats.rx_oversize),
97
- ICE_PF_STAT("rx_jabber", stats.rx_jabber),
98
- ICE_PF_STAT("rx_csum_bad", hw_csum_rx_error),
99
- ICE_PF_STAT("rx_length_errors", stats.rx_len_errors),
100
- ICE_PF_STAT("rx_dropped", stats.eth.rx_discards),
101
- ICE_PF_STAT("rx_crc_errors", stats.crc_errors),
102
- ICE_PF_STAT("illegal_bytes", stats.illegal_bytes),
103
- ICE_PF_STAT("mac_local_faults", stats.mac_local_faults),
104
- ICE_PF_STAT("mac_remote_faults", stats.mac_remote_faults),
97
+static const struct ice_stats ice_gstrings_pf_stats[] = {
98
+ ICE_PF_STAT("rx_bytes.nic", stats.eth.rx_bytes),
99
+ ICE_PF_STAT("tx_bytes.nic", stats.eth.tx_bytes),
100
+ ICE_PF_STAT("rx_unicast.nic", stats.eth.rx_unicast),
101
+ ICE_PF_STAT("tx_unicast.nic", stats.eth.tx_unicast),
102
+ ICE_PF_STAT("rx_multicast.nic", stats.eth.rx_multicast),
103
+ ICE_PF_STAT("tx_multicast.nic", stats.eth.tx_multicast),
104
+ ICE_PF_STAT("rx_broadcast.nic", stats.eth.rx_broadcast),
105
+ ICE_PF_STAT("tx_broadcast.nic", stats.eth.tx_broadcast),
106
+ ICE_PF_STAT("tx_errors.nic", stats.eth.tx_errors),
107
+ ICE_PF_STAT("tx_timeout.nic", tx_timeout_count),
108
+ ICE_PF_STAT("rx_size_64.nic", stats.rx_size_64),
109
+ ICE_PF_STAT("tx_size_64.nic", stats.tx_size_64),
110
+ ICE_PF_STAT("rx_size_127.nic", stats.rx_size_127),
111
+ ICE_PF_STAT("tx_size_127.nic", stats.tx_size_127),
112
+ ICE_PF_STAT("rx_size_255.nic", stats.rx_size_255),
113
+ ICE_PF_STAT("tx_size_255.nic", stats.tx_size_255),
114
+ ICE_PF_STAT("rx_size_511.nic", stats.rx_size_511),
115
+ ICE_PF_STAT("tx_size_511.nic", stats.tx_size_511),
116
+ ICE_PF_STAT("rx_size_1023.nic", stats.rx_size_1023),
117
+ ICE_PF_STAT("tx_size_1023.nic", stats.tx_size_1023),
118
+ ICE_PF_STAT("rx_size_1522.nic", stats.rx_size_1522),
119
+ ICE_PF_STAT("tx_size_1522.nic", stats.tx_size_1522),
120
+ ICE_PF_STAT("rx_size_big.nic", stats.rx_size_big),
121
+ ICE_PF_STAT("tx_size_big.nic", stats.tx_size_big),
122
+ ICE_PF_STAT("link_xon_rx.nic", stats.link_xon_rx),
123
+ ICE_PF_STAT("link_xon_tx.nic", stats.link_xon_tx),
124
+ ICE_PF_STAT("link_xoff_rx.nic", stats.link_xoff_rx),
125
+ ICE_PF_STAT("link_xoff_tx.nic", stats.link_xoff_tx),
126
+ ICE_PF_STAT("tx_dropped_link_down.nic", stats.tx_dropped_link_down),
127
+ ICE_PF_STAT("rx_undersize.nic", stats.rx_undersize),
128
+ ICE_PF_STAT("rx_fragments.nic", stats.rx_fragments),
129
+ ICE_PF_STAT("rx_oversize.nic", stats.rx_oversize),
130
+ ICE_PF_STAT("rx_jabber.nic", stats.rx_jabber),
131
+ ICE_PF_STAT("rx_csum_bad.nic", hw_csum_rx_error),
132
+ ICE_PF_STAT("rx_length_errors.nic", stats.rx_len_errors),
133
+ ICE_PF_STAT("rx_dropped.nic", stats.eth.rx_discards),
134
+ ICE_PF_STAT("rx_crc_errors.nic", stats.crc_errors),
135
+ ICE_PF_STAT("illegal_bytes.nic", stats.illegal_bytes),
136
+ ICE_PF_STAT("mac_local_faults.nic", stats.mac_local_faults),
137
+ ICE_PF_STAT("mac_remote_faults.nic", stats.mac_remote_faults),
138
+ ICE_PF_STAT("fdir_sb_match.nic", stats.fd_sb_match),
139
+ ICE_PF_STAT("fdir_sb_status.nic", stats.fd_sb_status),
105140 };
106141
107
-static u32 ice_regs_dump_list[] = {
142
+static const u32 ice_regs_dump_list[] = {
108143 PFGEN_STATE,
109144 PRTGEN_STATUS,
110145 QRX_CTRL(0),
....@@ -114,30 +149,26 @@
114149 QRX_ITR(0),
115150 };
116151
117
-/**
118
- * ice_nvm_version_str - format the NVM version strings
119
- * @hw: ptr to the hardware info
120
- */
121
-static char *ice_nvm_version_str(struct ice_hw *hw)
122
-{
123
- static char buf[ICE_ETHTOOL_FWVER_LEN];
124
- u8 ver, patch;
125
- u32 full_ver;
126
- u16 build;
152
+struct ice_priv_flag {
153
+ char name[ETH_GSTRING_LEN];
154
+ u32 bitno; /* bit position in pf->flags */
155
+};
127156
128
- full_ver = hw->nvm.oem_ver;
129
- ver = (u8)((full_ver & ICE_OEM_VER_MASK) >> ICE_OEM_VER_SHIFT);
130
- build = (u16)((full_ver & ICE_OEM_VER_BUILD_MASK) >>
131
- ICE_OEM_VER_BUILD_SHIFT);
132
- patch = (u8)(full_ver & ICE_OEM_VER_PATCH_MASK);
133
-
134
- snprintf(buf, sizeof(buf), "%x.%02x 0x%x %d.%d.%d",
135
- (hw->nvm.ver & ICE_NVM_VER_HI_MASK) >> ICE_NVM_VER_HI_SHIFT,
136
- (hw->nvm.ver & ICE_NVM_VER_LO_MASK) >> ICE_NVM_VER_LO_SHIFT,
137
- hw->nvm.eetrack, ver, build, patch);
138
-
139
- return buf;
157
+#define ICE_PRIV_FLAG(_name, _bitno) { \
158
+ .name = _name, \
159
+ .bitno = _bitno, \
140160 }
161
+
162
+static const struct ice_priv_flag ice_gstrings_priv_flags[] = {
163
+ ICE_PRIV_FLAG("link-down-on-close", ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA),
164
+ ICE_PRIV_FLAG("fw-lldp-agent", ICE_FLAG_FW_LLDP_AGENT),
165
+ ICE_PRIV_FLAG("vf-true-promisc-support",
166
+ ICE_FLAG_VF_TRUE_PROMISC_ENA),
167
+ ICE_PRIV_FLAG("mdd-auto-reset-vf", ICE_FLAG_MDD_AUTO_RESET_VF),
168
+ ICE_PRIV_FLAG("legacy-rx", ICE_FLAG_LEGACY_RX),
169
+};
170
+
171
+#define ICE_PRIV_FLAG_ARRAY_SIZE ARRAY_SIZE(ice_gstrings_priv_flags)
141172
142173 static void
143174 ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
....@@ -145,13 +176,25 @@
145176 struct ice_netdev_priv *np = netdev_priv(netdev);
146177 struct ice_vsi *vsi = np->vsi;
147178 struct ice_pf *pf = vsi->back;
179
+ struct ice_hw *hw = &pf->hw;
180
+ struct ice_orom_info *orom;
181
+ struct ice_nvm_info *nvm;
148182
149
- strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
150
- strlcpy(drvinfo->version, ice_drv_ver, sizeof(drvinfo->version));
151
- strlcpy(drvinfo->fw_version, ice_nvm_version_str(&pf->hw),
152
- sizeof(drvinfo->fw_version));
153
- strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
183
+ nvm = &hw->nvm;
184
+ orom = &nvm->orom;
185
+
186
+ strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
187
+
188
+ /* Display NVM version (from which the firmware version can be
189
+ * determined) which contains more pertinent information.
190
+ */
191
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
192
+ "%x.%02x 0x%x %d.%d.%d", nvm->major_ver, nvm->minor_ver,
193
+ nvm->eetrack, orom->major, orom->build, orom->patch);
194
+
195
+ strscpy(drvinfo->bus_info, pci_name(pf->pdev),
154196 sizeof(drvinfo->bus_info));
197
+ drvinfo->n_priv_flags = ICE_PRIV_FLAG_ARRAY_SIZE;
155198 }
156199
157200 static int ice_get_regs_len(struct net_device __always_unused *netdev)
....@@ -166,7 +209,7 @@
166209 struct ice_pf *pf = np->vsi->back;
167210 struct ice_hw *hw = &pf->hw;
168211 u32 *regs_buf = (u32 *)p;
169
- int i;
212
+ unsigned int i;
170213
171214 regs->version = 1;
172215
....@@ -203,6 +246,628 @@
203246 #endif /* !CONFIG_DYNAMIC_DEBUG */
204247 }
205248
249
+static int ice_get_eeprom_len(struct net_device *netdev)
250
+{
251
+ struct ice_netdev_priv *np = netdev_priv(netdev);
252
+ struct ice_pf *pf = np->vsi->back;
253
+
254
+ return (int)pf->hw.nvm.flash_size;
255
+}
256
+
257
+static int
258
+ice_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
259
+ u8 *bytes)
260
+{
261
+ struct ice_netdev_priv *np = netdev_priv(netdev);
262
+ struct ice_vsi *vsi = np->vsi;
263
+ struct ice_pf *pf = vsi->back;
264
+ struct ice_hw *hw = &pf->hw;
265
+ enum ice_status status;
266
+ struct device *dev;
267
+ int ret = 0;
268
+ u8 *buf;
269
+
270
+ dev = ice_pf_to_dev(pf);
271
+
272
+ eeprom->magic = hw->vendor_id | (hw->device_id << 16);
273
+ netdev_dbg(netdev, "GEEPROM cmd 0x%08x, offset 0x%08x, len 0x%08x\n",
274
+ eeprom->cmd, eeprom->offset, eeprom->len);
275
+
276
+ buf = kzalloc(eeprom->len, GFP_KERNEL);
277
+ if (!buf)
278
+ return -ENOMEM;
279
+
280
+ status = ice_acquire_nvm(hw, ICE_RES_READ);
281
+ if (status) {
282
+ dev_err(dev, "ice_acquire_nvm failed, err %s aq_err %s\n",
283
+ ice_stat_str(status),
284
+ ice_aq_str(hw->adminq.sq_last_status));
285
+ ret = -EIO;
286
+ goto out;
287
+ }
288
+
289
+ status = ice_read_flat_nvm(hw, eeprom->offset, &eeprom->len, buf,
290
+ false);
291
+ if (status) {
292
+ dev_err(dev, "ice_read_flat_nvm failed, err %s aq_err %s\n",
293
+ ice_stat_str(status),
294
+ ice_aq_str(hw->adminq.sq_last_status));
295
+ ret = -EIO;
296
+ goto release;
297
+ }
298
+
299
+ memcpy(bytes, buf, eeprom->len);
300
+release:
301
+ ice_release_nvm(hw);
302
+out:
303
+ kfree(buf);
304
+ return ret;
305
+}
306
+
307
+/**
308
+ * ice_active_vfs - check if there are any active VFs
309
+ * @pf: board private structure
310
+ *
311
+ * Returns true if an active VF is found, otherwise returns false
312
+ */
313
+static bool ice_active_vfs(struct ice_pf *pf)
314
+{
315
+ unsigned int i;
316
+
317
+ ice_for_each_vf(pf, i) {
318
+ struct ice_vf *vf = &pf->vf[i];
319
+
320
+ if (test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
321
+ return true;
322
+ }
323
+
324
+ return false;
325
+}
326
+
327
+/**
328
+ * ice_link_test - perform a link test on a given net_device
329
+ * @netdev: network interface device structure
330
+ *
331
+ * This function performs one of the self-tests required by ethtool.
332
+ * Returns 0 on success, non-zero on failure.
333
+ */
334
+static u64 ice_link_test(struct net_device *netdev)
335
+{
336
+ struct ice_netdev_priv *np = netdev_priv(netdev);
337
+ enum ice_status status;
338
+ bool link_up = false;
339
+
340
+ netdev_info(netdev, "link test\n");
341
+ status = ice_get_link_status(np->vsi->port_info, &link_up);
342
+ if (status) {
343
+ netdev_err(netdev, "link query error, status = %s\n",
344
+ ice_stat_str(status));
345
+ return 1;
346
+ }
347
+
348
+ if (!link_up)
349
+ return 2;
350
+
351
+ return 0;
352
+}
353
+
354
+/**
355
+ * ice_eeprom_test - perform an EEPROM test on a given net_device
356
+ * @netdev: network interface device structure
357
+ *
358
+ * This function performs one of the self-tests required by ethtool.
359
+ * Returns 0 on success, non-zero on failure.
360
+ */
361
+static u64 ice_eeprom_test(struct net_device *netdev)
362
+{
363
+ struct ice_netdev_priv *np = netdev_priv(netdev);
364
+ struct ice_pf *pf = np->vsi->back;
365
+
366
+ netdev_info(netdev, "EEPROM test\n");
367
+ return !!(ice_nvm_validate_checksum(&pf->hw));
368
+}
369
+
370
+/**
371
+ * ice_reg_pattern_test
372
+ * @hw: pointer to the HW struct
373
+ * @reg: reg to be tested
374
+ * @mask: bits to be touched
375
+ */
376
+static int ice_reg_pattern_test(struct ice_hw *hw, u32 reg, u32 mask)
377
+{
378
+ struct ice_pf *pf = (struct ice_pf *)hw->back;
379
+ struct device *dev = ice_pf_to_dev(pf);
380
+ static const u32 patterns[] = {
381
+ 0x5A5A5A5A, 0xA5A5A5A5,
382
+ 0x00000000, 0xFFFFFFFF
383
+ };
384
+ u32 val, orig_val;
385
+ unsigned int i;
386
+
387
+ orig_val = rd32(hw, reg);
388
+ for (i = 0; i < ARRAY_SIZE(patterns); ++i) {
389
+ u32 pattern = patterns[i] & mask;
390
+
391
+ wr32(hw, reg, pattern);
392
+ val = rd32(hw, reg);
393
+ if (val == pattern)
394
+ continue;
395
+ dev_err(dev, "%s: reg pattern test failed - reg 0x%08x pat 0x%08x val 0x%08x\n"
396
+ , __func__, reg, pattern, val);
397
+ return 1;
398
+ }
399
+
400
+ wr32(hw, reg, orig_val);
401
+ val = rd32(hw, reg);
402
+ if (val != orig_val) {
403
+ dev_err(dev, "%s: reg restore test failed - reg 0x%08x orig 0x%08x val 0x%08x\n"
404
+ , __func__, reg, orig_val, val);
405
+ return 1;
406
+ }
407
+
408
+ return 0;
409
+}
410
+
411
+/**
412
+ * ice_reg_test - perform a register test on a given net_device
413
+ * @netdev: network interface device structure
414
+ *
415
+ * This function performs one of the self-tests required by ethtool.
416
+ * Returns 0 on success, non-zero on failure.
417
+ */
418
+static u64 ice_reg_test(struct net_device *netdev)
419
+{
420
+ struct ice_netdev_priv *np = netdev_priv(netdev);
421
+ struct ice_hw *hw = np->vsi->port_info->hw;
422
+ u32 int_elements = hw->func_caps.common_cap.num_msix_vectors ?
423
+ hw->func_caps.common_cap.num_msix_vectors - 1 : 1;
424
+ struct ice_diag_reg_test_info {
425
+ u32 address;
426
+ u32 mask;
427
+ u32 elem_num;
428
+ u32 elem_size;
429
+ } ice_reg_list[] = {
430
+ {GLINT_ITR(0, 0), 0x00000fff, int_elements,
431
+ GLINT_ITR(0, 1) - GLINT_ITR(0, 0)},
432
+ {GLINT_ITR(1, 0), 0x00000fff, int_elements,
433
+ GLINT_ITR(1, 1) - GLINT_ITR(1, 0)},
434
+ {GLINT_ITR(0, 0), 0x00000fff, int_elements,
435
+ GLINT_ITR(2, 1) - GLINT_ITR(2, 0)},
436
+ {GLINT_CTL, 0xffff0001, 1, 0}
437
+ };
438
+ unsigned int i;
439
+
440
+ netdev_dbg(netdev, "Register test\n");
441
+ for (i = 0; i < ARRAY_SIZE(ice_reg_list); ++i) {
442
+ u32 j;
443
+
444
+ for (j = 0; j < ice_reg_list[i].elem_num; ++j) {
445
+ u32 mask = ice_reg_list[i].mask;
446
+ u32 reg = ice_reg_list[i].address +
447
+ (j * ice_reg_list[i].elem_size);
448
+
449
+ /* bail on failure (non-zero return) */
450
+ if (ice_reg_pattern_test(hw, reg, mask))
451
+ return 1;
452
+ }
453
+ }
454
+
455
+ return 0;
456
+}
457
+
458
+/**
459
+ * ice_lbtest_prepare_rings - configure Tx/Rx test rings
460
+ * @vsi: pointer to the VSI structure
461
+ *
462
+ * Function configures rings of a VSI for loopback test without
463
+ * enabling interrupts or informing the kernel about new queues.
464
+ *
465
+ * Returns 0 on success, negative on failure.
466
+ */
467
+static int ice_lbtest_prepare_rings(struct ice_vsi *vsi)
468
+{
469
+ int status;
470
+
471
+ status = ice_vsi_setup_tx_rings(vsi);
472
+ if (status)
473
+ goto err_setup_tx_ring;
474
+
475
+ status = ice_vsi_setup_rx_rings(vsi);
476
+ if (status)
477
+ goto err_setup_rx_ring;
478
+
479
+ status = ice_vsi_cfg(vsi);
480
+ if (status)
481
+ goto err_setup_rx_ring;
482
+
483
+ status = ice_vsi_start_all_rx_rings(vsi);
484
+ if (status)
485
+ goto err_start_rx_ring;
486
+
487
+ return status;
488
+
489
+err_start_rx_ring:
490
+ ice_vsi_free_rx_rings(vsi);
491
+err_setup_rx_ring:
492
+ ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, 0);
493
+err_setup_tx_ring:
494
+ ice_vsi_free_tx_rings(vsi);
495
+
496
+ return status;
497
+}
498
+
499
+/**
500
+ * ice_lbtest_disable_rings - disable Tx/Rx test rings after loopback test
501
+ * @vsi: pointer to the VSI structure
502
+ *
503
+ * Function stops and frees VSI rings after a loopback test.
504
+ * Returns 0 on success, negative on failure.
505
+ */
506
+static int ice_lbtest_disable_rings(struct ice_vsi *vsi)
507
+{
508
+ int status;
509
+
510
+ status = ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, 0);
511
+ if (status)
512
+ netdev_err(vsi->netdev, "Failed to stop Tx rings, VSI %d error %d\n",
513
+ vsi->vsi_num, status);
514
+
515
+ status = ice_vsi_stop_all_rx_rings(vsi);
516
+ if (status)
517
+ netdev_err(vsi->netdev, "Failed to stop Rx rings, VSI %d error %d\n",
518
+ vsi->vsi_num, status);
519
+
520
+ ice_vsi_free_tx_rings(vsi);
521
+ ice_vsi_free_rx_rings(vsi);
522
+
523
+ return status;
524
+}
525
+
526
+/**
527
+ * ice_lbtest_create_frame - create test packet
528
+ * @pf: pointer to the PF structure
529
+ * @ret_data: allocated frame buffer
530
+ * @size: size of the packet data
531
+ *
532
+ * Function allocates a frame with a test pattern on specific offsets.
533
+ * Returns 0 on success, non-zero on failure.
534
+ */
535
+static int ice_lbtest_create_frame(struct ice_pf *pf, u8 **ret_data, u16 size)
536
+{
537
+ u8 *data;
538
+
539
+ if (!pf)
540
+ return -EINVAL;
541
+
542
+ data = devm_kzalloc(ice_pf_to_dev(pf), size, GFP_KERNEL);
543
+ if (!data)
544
+ return -ENOMEM;
545
+
546
+ /* Since the ethernet test frame should always be at least
547
+ * 64 bytes long, fill some octets in the payload with test data.
548
+ */
549
+ memset(data, 0xFF, size);
550
+ data[32] = 0xDE;
551
+ data[42] = 0xAD;
552
+ data[44] = 0xBE;
553
+ data[46] = 0xEF;
554
+
555
+ *ret_data = data;
556
+
557
+ return 0;
558
+}
559
+
560
+/**
561
+ * ice_lbtest_check_frame - verify received loopback frame
562
+ * @frame: pointer to the raw packet data
563
+ *
564
+ * Function verifies received test frame with a pattern.
565
+ * Returns true if frame matches the pattern, false otherwise.
566
+ */
567
+static bool ice_lbtest_check_frame(u8 *frame)
568
+{
569
+ /* Validate bytes of a frame under offsets chosen earlier */
570
+ if (frame[32] == 0xDE &&
571
+ frame[42] == 0xAD &&
572
+ frame[44] == 0xBE &&
573
+ frame[46] == 0xEF &&
574
+ frame[48] == 0xFF)
575
+ return true;
576
+
577
+ return false;
578
+}
579
+
580
+/**
581
+ * ice_diag_send - send test frames to the test ring
582
+ * @tx_ring: pointer to the transmit ring
583
+ * @data: pointer to the raw packet data
584
+ * @size: size of the packet to send
585
+ *
586
+ * Function sends loopback packets on a test Tx ring.
587
+ */
588
+static int ice_diag_send(struct ice_ring *tx_ring, u8 *data, u16 size)
589
+{
590
+ struct ice_tx_desc *tx_desc;
591
+ struct ice_tx_buf *tx_buf;
592
+ dma_addr_t dma;
593
+ u64 td_cmd;
594
+
595
+ tx_desc = ICE_TX_DESC(tx_ring, tx_ring->next_to_use);
596
+ tx_buf = &tx_ring->tx_buf[tx_ring->next_to_use];
597
+
598
+ dma = dma_map_single(tx_ring->dev, data, size, DMA_TO_DEVICE);
599
+ if (dma_mapping_error(tx_ring->dev, dma))
600
+ return -EINVAL;
601
+
602
+ tx_desc->buf_addr = cpu_to_le64(dma);
603
+
604
+ /* These flags are required for a descriptor to be pushed out */
605
+ td_cmd = (u64)(ICE_TX_DESC_CMD_EOP | ICE_TX_DESC_CMD_RS);
606
+ tx_desc->cmd_type_offset_bsz =
607
+ cpu_to_le64(ICE_TX_DESC_DTYPE_DATA |
608
+ (td_cmd << ICE_TXD_QW1_CMD_S) |
609
+ ((u64)0 << ICE_TXD_QW1_OFFSET_S) |
610
+ ((u64)size << ICE_TXD_QW1_TX_BUF_SZ_S) |
611
+ ((u64)0 << ICE_TXD_QW1_L2TAG1_S));
612
+
613
+ tx_buf->next_to_watch = tx_desc;
614
+
615
+ /* Force memory write to complete before letting h/w know
616
+ * there are new descriptors to fetch.
617
+ */
618
+ wmb();
619
+
620
+ tx_ring->next_to_use++;
621
+ if (tx_ring->next_to_use >= tx_ring->count)
622
+ tx_ring->next_to_use = 0;
623
+
624
+ writel_relaxed(tx_ring->next_to_use, tx_ring->tail);
625
+
626
+ /* Wait until the packets get transmitted to the receive queue. */
627
+ usleep_range(1000, 2000);
628
+ dma_unmap_single(tx_ring->dev, dma, size, DMA_TO_DEVICE);
629
+
630
+ return 0;
631
+}
632
+
633
+#define ICE_LB_FRAME_SIZE 64
634
+/**
635
+ * ice_lbtest_receive_frames - receive and verify test frames
636
+ * @rx_ring: pointer to the receive ring
637
+ *
638
+ * Function receives loopback packets and verify their correctness.
639
+ * Returns number of received valid frames.
640
+ */
641
+static int ice_lbtest_receive_frames(struct ice_ring *rx_ring)
642
+{
643
+ struct ice_rx_buf *rx_buf;
644
+ int valid_frames, i;
645
+ u8 *received_buf;
646
+
647
+ valid_frames = 0;
648
+
649
+ for (i = 0; i < rx_ring->count; i++) {
650
+ union ice_32b_rx_flex_desc *rx_desc;
651
+
652
+ rx_desc = ICE_RX_DESC(rx_ring, i);
653
+
654
+ if (!(rx_desc->wb.status_error0 &
655
+ (cpu_to_le16(BIT(ICE_RX_FLEX_DESC_STATUS0_DD_S)) |
656
+ cpu_to_le16(BIT(ICE_RX_FLEX_DESC_STATUS0_EOF_S)))))
657
+ continue;
658
+
659
+ rx_buf = &rx_ring->rx_buf[i];
660
+ received_buf = page_address(rx_buf->page) + rx_buf->page_offset;
661
+
662
+ if (ice_lbtest_check_frame(received_buf))
663
+ valid_frames++;
664
+ }
665
+
666
+ return valid_frames;
667
+}
668
+
669
+/**
670
+ * ice_loopback_test - perform a loopback test on a given net_device
671
+ * @netdev: network interface device structure
672
+ *
673
+ * This function performs one of the self-tests required by ethtool.
674
+ * Returns 0 on success, non-zero on failure.
675
+ */
676
+static u64 ice_loopback_test(struct net_device *netdev)
677
+{
678
+ struct ice_netdev_priv *np = netdev_priv(netdev);
679
+ struct ice_vsi *orig_vsi = np->vsi, *test_vsi;
680
+ struct ice_pf *pf = orig_vsi->back;
681
+ struct ice_ring *tx_ring, *rx_ring;
682
+ u8 broadcast[ETH_ALEN], ret = 0;
683
+ int num_frames, valid_frames;
684
+ struct device *dev;
685
+ u8 *tx_frame;
686
+ int i;
687
+
688
+ dev = ice_pf_to_dev(pf);
689
+ netdev_info(netdev, "loopback test\n");
690
+
691
+ test_vsi = ice_lb_vsi_setup(pf, pf->hw.port_info);
692
+ if (!test_vsi) {
693
+ netdev_err(netdev, "Failed to create a VSI for the loopback test\n");
694
+ return 1;
695
+ }
696
+
697
+ test_vsi->netdev = netdev;
698
+ tx_ring = test_vsi->tx_rings[0];
699
+ rx_ring = test_vsi->rx_rings[0];
700
+
701
+ if (ice_lbtest_prepare_rings(test_vsi)) {
702
+ ret = 2;
703
+ goto lbtest_vsi_close;
704
+ }
705
+
706
+ if (ice_alloc_rx_bufs(rx_ring, rx_ring->count)) {
707
+ ret = 3;
708
+ goto lbtest_rings_dis;
709
+ }
710
+
711
+ /* Enable MAC loopback in firmware */
712
+ if (ice_aq_set_mac_loopback(&pf->hw, true, NULL)) {
713
+ ret = 4;
714
+ goto lbtest_mac_dis;
715
+ }
716
+
717
+ /* Test VSI needs to receive broadcast packets */
718
+ eth_broadcast_addr(broadcast);
719
+ if (ice_fltr_add_mac(test_vsi, broadcast, ICE_FWD_TO_VSI)) {
720
+ ret = 5;
721
+ goto lbtest_mac_dis;
722
+ }
723
+
724
+ if (ice_lbtest_create_frame(pf, &tx_frame, ICE_LB_FRAME_SIZE)) {
725
+ ret = 7;
726
+ goto remove_mac_filters;
727
+ }
728
+
729
+ num_frames = min_t(int, tx_ring->count, 32);
730
+ for (i = 0; i < num_frames; i++) {
731
+ if (ice_diag_send(tx_ring, tx_frame, ICE_LB_FRAME_SIZE)) {
732
+ ret = 8;
733
+ goto lbtest_free_frame;
734
+ }
735
+ }
736
+
737
+ valid_frames = ice_lbtest_receive_frames(rx_ring);
738
+ if (!valid_frames)
739
+ ret = 9;
740
+ else if (valid_frames != num_frames)
741
+ ret = 10;
742
+
743
+lbtest_free_frame:
744
+ devm_kfree(dev, tx_frame);
745
+remove_mac_filters:
746
+ if (ice_fltr_remove_mac(test_vsi, broadcast, ICE_FWD_TO_VSI))
747
+ netdev_err(netdev, "Could not remove MAC filter for the test VSI\n");
748
+lbtest_mac_dis:
749
+ /* Disable MAC loopback after the test is completed. */
750
+ if (ice_aq_set_mac_loopback(&pf->hw, false, NULL))
751
+ netdev_err(netdev, "Could not disable MAC loopback\n");
752
+lbtest_rings_dis:
753
+ if (ice_lbtest_disable_rings(test_vsi))
754
+ netdev_err(netdev, "Could not disable test rings\n");
755
+lbtest_vsi_close:
756
+ test_vsi->netdev = NULL;
757
+ if (ice_vsi_release(test_vsi))
758
+ netdev_err(netdev, "Failed to remove the test VSI\n");
759
+
760
+ return ret;
761
+}
762
+
763
+/**
764
+ * ice_intr_test - perform an interrupt test on a given net_device
765
+ * @netdev: network interface device structure
766
+ *
767
+ * This function performs one of the self-tests required by ethtool.
768
+ * Returns 0 on success, non-zero on failure.
769
+ */
770
+static u64 ice_intr_test(struct net_device *netdev)
771
+{
772
+ struct ice_netdev_priv *np = netdev_priv(netdev);
773
+ struct ice_pf *pf = np->vsi->back;
774
+ u16 swic_old = pf->sw_int_count;
775
+
776
+ netdev_info(netdev, "interrupt test\n");
777
+
778
+ wr32(&pf->hw, GLINT_DYN_CTL(pf->oicr_idx),
779
+ GLINT_DYN_CTL_SW_ITR_INDX_M |
780
+ GLINT_DYN_CTL_INTENA_MSK_M |
781
+ GLINT_DYN_CTL_SWINT_TRIG_M);
782
+
783
+ usleep_range(1000, 2000);
784
+ return (swic_old == pf->sw_int_count);
785
+}
786
+
787
+/**
788
+ * ice_self_test - handler function for performing a self-test by ethtool
789
+ * @netdev: network interface device structure
790
+ * @eth_test: ethtool_test structure
791
+ * @data: required by ethtool.self_test
792
+ *
793
+ * This function is called after invoking 'ethtool -t devname' command where
794
+ * devname is the name of the network device on which ethtool should operate.
795
+ * It performs a set of self-tests to check if a device works properly.
796
+ */
797
+static void
798
+ice_self_test(struct net_device *netdev, struct ethtool_test *eth_test,
799
+ u64 *data)
800
+{
801
+ struct ice_netdev_priv *np = netdev_priv(netdev);
802
+ bool if_running = netif_running(netdev);
803
+ struct ice_pf *pf = np->vsi->back;
804
+ struct device *dev;
805
+
806
+ dev = ice_pf_to_dev(pf);
807
+
808
+ if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
809
+ netdev_info(netdev, "offline testing starting\n");
810
+
811
+ set_bit(__ICE_TESTING, pf->state);
812
+
813
+ if (ice_active_vfs(pf)) {
814
+ dev_warn(dev, "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n");
815
+ data[ICE_ETH_TEST_REG] = 1;
816
+ data[ICE_ETH_TEST_EEPROM] = 1;
817
+ data[ICE_ETH_TEST_INTR] = 1;
818
+ data[ICE_ETH_TEST_LOOP] = 1;
819
+ data[ICE_ETH_TEST_LINK] = 1;
820
+ eth_test->flags |= ETH_TEST_FL_FAILED;
821
+ clear_bit(__ICE_TESTING, pf->state);
822
+ goto skip_ol_tests;
823
+ }
824
+ /* If the device is online then take it offline */
825
+ if (if_running)
826
+ /* indicate we're in test mode */
827
+ ice_stop(netdev);
828
+
829
+ data[ICE_ETH_TEST_LINK] = ice_link_test(netdev);
830
+ data[ICE_ETH_TEST_EEPROM] = ice_eeprom_test(netdev);
831
+ data[ICE_ETH_TEST_INTR] = ice_intr_test(netdev);
832
+ data[ICE_ETH_TEST_LOOP] = ice_loopback_test(netdev);
833
+ data[ICE_ETH_TEST_REG] = ice_reg_test(netdev);
834
+
835
+ if (data[ICE_ETH_TEST_LINK] ||
836
+ data[ICE_ETH_TEST_EEPROM] ||
837
+ data[ICE_ETH_TEST_LOOP] ||
838
+ data[ICE_ETH_TEST_INTR] ||
839
+ data[ICE_ETH_TEST_REG])
840
+ eth_test->flags |= ETH_TEST_FL_FAILED;
841
+
842
+ clear_bit(__ICE_TESTING, pf->state);
843
+
844
+ if (if_running) {
845
+ int status = ice_open(netdev);
846
+
847
+ if (status) {
848
+ dev_err(dev, "Could not open device %s, err %d\n",
849
+ pf->int_name, status);
850
+ }
851
+ }
852
+ } else {
853
+ /* Online tests */
854
+ netdev_info(netdev, "online testing starting\n");
855
+
856
+ data[ICE_ETH_TEST_LINK] = ice_link_test(netdev);
857
+ if (data[ICE_ETH_TEST_LINK])
858
+ eth_test->flags |= ETH_TEST_FL_FAILED;
859
+
860
+ /* Offline only tests, not run in online; pass by default */
861
+ data[ICE_ETH_TEST_REG] = 0;
862
+ data[ICE_ETH_TEST_EEPROM] = 0;
863
+ data[ICE_ETH_TEST_INTR] = 0;
864
+ data[ICE_ETH_TEST_LOOP] = 0;
865
+ }
866
+
867
+skip_ol_tests:
868
+ netdev_info(netdev, "testing finished\n");
869
+}
870
+
206871 static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
207872 {
208873 struct ice_netdev_priv *np = netdev_priv(netdev);
....@@ -220,17 +885,17 @@
220885
221886 ice_for_each_alloc_txq(vsi, i) {
222887 snprintf(p, ETH_GSTRING_LEN,
223
- "tx-queue-%u.tx_packets", i);
888
+ "tx_queue_%u_packets", i);
224889 p += ETH_GSTRING_LEN;
225
- snprintf(p, ETH_GSTRING_LEN, "tx-queue-%u.tx_bytes", i);
890
+ snprintf(p, ETH_GSTRING_LEN, "tx_queue_%u_bytes", i);
226891 p += ETH_GSTRING_LEN;
227892 }
228893
229894 ice_for_each_alloc_rxq(vsi, i) {
230895 snprintf(p, ETH_GSTRING_LEN,
231
- "rx-queue-%u.rx_packets", i);
896
+ "rx_queue_%u_packets", i);
232897 p += ETH_GSTRING_LEN;
233
- snprintf(p, ETH_GSTRING_LEN, "rx-queue-%u.rx_bytes", i);
898
+ snprintf(p, ETH_GSTRING_LEN, "rx_queue_%u_bytes", i);
234899 p += ETH_GSTRING_LEN;
235900 }
236901
....@@ -238,15 +903,412 @@
238903 return;
239904
240905 for (i = 0; i < ICE_PF_STATS_LEN; i++) {
241
- snprintf(p, ETH_GSTRING_LEN, "port.%s",
906
+ snprintf(p, ETH_GSTRING_LEN, "%s",
242907 ice_gstrings_pf_stats[i].stat_string);
243908 p += ETH_GSTRING_LEN;
244909 }
245910
911
+ for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
912
+ snprintf(p, ETH_GSTRING_LEN,
913
+ "tx_priority_%u_xon.nic", i);
914
+ p += ETH_GSTRING_LEN;
915
+ snprintf(p, ETH_GSTRING_LEN,
916
+ "tx_priority_%u_xoff.nic", i);
917
+ p += ETH_GSTRING_LEN;
918
+ }
919
+ for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
920
+ snprintf(p, ETH_GSTRING_LEN,
921
+ "rx_priority_%u_xon.nic", i);
922
+ p += ETH_GSTRING_LEN;
923
+ snprintf(p, ETH_GSTRING_LEN,
924
+ "rx_priority_%u_xoff.nic", i);
925
+ p += ETH_GSTRING_LEN;
926
+ }
927
+ break;
928
+ case ETH_SS_TEST:
929
+ memcpy(data, ice_gstrings_test, ICE_TEST_LEN * ETH_GSTRING_LEN);
930
+ break;
931
+ case ETH_SS_PRIV_FLAGS:
932
+ for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
933
+ snprintf(p, ETH_GSTRING_LEN, "%s",
934
+ ice_gstrings_priv_flags[i].name);
935
+ p += ETH_GSTRING_LEN;
936
+ }
246937 break;
247938 default:
248939 break;
249940 }
941
+}
942
+
943
+static int
944
+ice_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
945
+{
946
+ struct ice_netdev_priv *np = netdev_priv(netdev);
947
+ bool led_active;
948
+
949
+ switch (state) {
950
+ case ETHTOOL_ID_ACTIVE:
951
+ led_active = true;
952
+ break;
953
+ case ETHTOOL_ID_INACTIVE:
954
+ led_active = false;
955
+ break;
956
+ default:
957
+ return -EINVAL;
958
+ }
959
+
960
+ if (ice_aq_set_port_id_led(np->vsi->port_info, !led_active, NULL))
961
+ return -EIO;
962
+
963
+ return 0;
964
+}
965
+
966
+/**
967
+ * ice_set_fec_cfg - Set link FEC options
968
+ * @netdev: network interface device structure
969
+ * @req_fec: FEC mode to configure
970
+ */
971
+static int ice_set_fec_cfg(struct net_device *netdev, enum ice_fec_mode req_fec)
972
+{
973
+ struct ice_netdev_priv *np = netdev_priv(netdev);
974
+ struct ice_aqc_set_phy_cfg_data config = { 0 };
975
+ struct ice_vsi *vsi = np->vsi;
976
+ struct ice_port_info *pi;
977
+
978
+ pi = vsi->port_info;
979
+ if (!pi)
980
+ return -EOPNOTSUPP;
981
+
982
+ /* Changing the FEC parameters is not supported if not the PF VSI */
983
+ if (vsi->type != ICE_VSI_PF) {
984
+ netdev_info(netdev, "Changing FEC parameters only supported for PF VSI\n");
985
+ return -EOPNOTSUPP;
986
+ }
987
+
988
+ /* Proceed only if requesting different FEC mode */
989
+ if (pi->phy.curr_user_fec_req == req_fec)
990
+ return 0;
991
+
992
+ /* Copy the current user PHY configuration. The current user PHY
993
+ * configuration is initialized during probe from PHY capabilities
994
+ * software mode, and updated on set PHY configuration.
995
+ */
996
+ memcpy(&config, &pi->phy.curr_user_phy_cfg, sizeof(config));
997
+
998
+ ice_cfg_phy_fec(pi, &config, req_fec);
999
+ config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
1000
+
1001
+ if (ice_aq_set_phy_cfg(pi->hw, pi, &config, NULL))
1002
+ return -EAGAIN;
1003
+
1004
+ /* Save requested FEC config */
1005
+ pi->phy.curr_user_fec_req = req_fec;
1006
+
1007
+ return 0;
1008
+}
1009
+
1010
+/**
1011
+ * ice_set_fecparam - Set FEC link options
1012
+ * @netdev: network interface device structure
1013
+ * @fecparam: Ethtool structure to retrieve FEC parameters
1014
+ */
1015
+static int
1016
+ice_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
1017
+{
1018
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1019
+ struct ice_vsi *vsi = np->vsi;
1020
+ enum ice_fec_mode fec;
1021
+
1022
+ switch (fecparam->fec) {
1023
+ case ETHTOOL_FEC_AUTO:
1024
+ fec = ICE_FEC_AUTO;
1025
+ break;
1026
+ case ETHTOOL_FEC_RS:
1027
+ fec = ICE_FEC_RS;
1028
+ break;
1029
+ case ETHTOOL_FEC_BASER:
1030
+ fec = ICE_FEC_BASER;
1031
+ break;
1032
+ case ETHTOOL_FEC_OFF:
1033
+ case ETHTOOL_FEC_NONE:
1034
+ fec = ICE_FEC_NONE;
1035
+ break;
1036
+ default:
1037
+ dev_warn(ice_pf_to_dev(vsi->back), "Unsupported FEC mode: %d\n",
1038
+ fecparam->fec);
1039
+ return -EINVAL;
1040
+ }
1041
+
1042
+ return ice_set_fec_cfg(netdev, fec);
1043
+}
1044
+
1045
+/**
1046
+ * ice_get_fecparam - Get link FEC options
1047
+ * @netdev: network interface device structure
1048
+ * @fecparam: Ethtool structure to retrieve FEC parameters
1049
+ */
1050
+static int
1051
+ice_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
1052
+{
1053
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1054
+ struct ice_aqc_get_phy_caps_data *caps;
1055
+ struct ice_link_status *link_info;
1056
+ struct ice_vsi *vsi = np->vsi;
1057
+ struct ice_port_info *pi;
1058
+ enum ice_status status;
1059
+ int err = 0;
1060
+
1061
+ pi = vsi->port_info;
1062
+
1063
+ if (!pi)
1064
+ return -EOPNOTSUPP;
1065
+ link_info = &pi->phy.link_info;
1066
+
1067
+ /* Set FEC mode based on negotiated link info */
1068
+ switch (link_info->fec_info) {
1069
+ case ICE_AQ_LINK_25G_KR_FEC_EN:
1070
+ fecparam->active_fec = ETHTOOL_FEC_BASER;
1071
+ break;
1072
+ case ICE_AQ_LINK_25G_RS_528_FEC_EN:
1073
+ case ICE_AQ_LINK_25G_RS_544_FEC_EN:
1074
+ fecparam->active_fec = ETHTOOL_FEC_RS;
1075
+ break;
1076
+ default:
1077
+ fecparam->active_fec = ETHTOOL_FEC_OFF;
1078
+ break;
1079
+ }
1080
+
1081
+ caps = kzalloc(sizeof(*caps), GFP_KERNEL);
1082
+ if (!caps)
1083
+ return -ENOMEM;
1084
+
1085
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
1086
+ caps, NULL);
1087
+ if (status) {
1088
+ err = -EAGAIN;
1089
+ goto done;
1090
+ }
1091
+
1092
+ /* Set supported/configured FEC modes based on PHY capability */
1093
+ if (caps->caps & ICE_AQC_PHY_EN_AUTO_FEC)
1094
+ fecparam->fec |= ETHTOOL_FEC_AUTO;
1095
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN ||
1096
+ caps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ ||
1097
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN ||
1098
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_REQ)
1099
+ fecparam->fec |= ETHTOOL_FEC_BASER;
1100
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_528_REQ ||
1101
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_544_REQ ||
1102
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN)
1103
+ fecparam->fec |= ETHTOOL_FEC_RS;
1104
+ if (caps->link_fec_options == 0)
1105
+ fecparam->fec |= ETHTOOL_FEC_OFF;
1106
+
1107
+done:
1108
+ kfree(caps);
1109
+ return err;
1110
+}
1111
+
1112
+/**
1113
+ * ice_nway_reset - restart autonegotiation
1114
+ * @netdev: network interface device structure
1115
+ */
1116
+static int ice_nway_reset(struct net_device *netdev)
1117
+{
1118
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1119
+ struct ice_vsi *vsi = np->vsi;
1120
+ struct ice_port_info *pi;
1121
+ enum ice_status status;
1122
+
1123
+ pi = vsi->port_info;
1124
+ /* If VSI state is up, then restart autoneg with link up */
1125
+ if (!test_bit(__ICE_DOWN, vsi->back->state))
1126
+ status = ice_aq_set_link_restart_an(pi, true, NULL);
1127
+ else
1128
+ status = ice_aq_set_link_restart_an(pi, false, NULL);
1129
+
1130
+ if (status) {
1131
+ netdev_info(netdev, "link restart failed, err %s aq_err %s\n",
1132
+ ice_stat_str(status),
1133
+ ice_aq_str(pi->hw->adminq.sq_last_status));
1134
+ return -EIO;
1135
+ }
1136
+
1137
+ return 0;
1138
+}
1139
+
1140
+/**
1141
+ * ice_get_priv_flags - report device private flags
1142
+ * @netdev: network interface device structure
1143
+ *
1144
+ * The get string set count and the string set should be matched for each
1145
+ * flag returned. Add new strings for each flag to the ice_gstrings_priv_flags
1146
+ * array.
1147
+ *
1148
+ * Returns a u32 bitmap of flags.
1149
+ */
1150
+static u32 ice_get_priv_flags(struct net_device *netdev)
1151
+{
1152
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1153
+ struct ice_vsi *vsi = np->vsi;
1154
+ struct ice_pf *pf = vsi->back;
1155
+ u32 i, ret_flags = 0;
1156
+
1157
+ for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
1158
+ const struct ice_priv_flag *priv_flag;
1159
+
1160
+ priv_flag = &ice_gstrings_priv_flags[i];
1161
+
1162
+ if (test_bit(priv_flag->bitno, pf->flags))
1163
+ ret_flags |= BIT(i);
1164
+ }
1165
+
1166
+ return ret_flags;
1167
+}
1168
+
1169
+/**
1170
+ * ice_set_priv_flags - set private flags
1171
+ * @netdev: network interface device structure
1172
+ * @flags: bit flags to be set
1173
+ */
1174
+static int ice_set_priv_flags(struct net_device *netdev, u32 flags)
1175
+{
1176
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1177
+ DECLARE_BITMAP(change_flags, ICE_PF_FLAGS_NBITS);
1178
+ DECLARE_BITMAP(orig_flags, ICE_PF_FLAGS_NBITS);
1179
+ struct ice_vsi *vsi = np->vsi;
1180
+ struct ice_pf *pf = vsi->back;
1181
+ struct device *dev;
1182
+ int ret = 0;
1183
+ u32 i;
1184
+
1185
+ if (flags > BIT(ICE_PRIV_FLAG_ARRAY_SIZE))
1186
+ return -EINVAL;
1187
+
1188
+ dev = ice_pf_to_dev(pf);
1189
+ set_bit(ICE_FLAG_ETHTOOL_CTXT, pf->flags);
1190
+
1191
+ bitmap_copy(orig_flags, pf->flags, ICE_PF_FLAGS_NBITS);
1192
+ for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++) {
1193
+ const struct ice_priv_flag *priv_flag;
1194
+
1195
+ priv_flag = &ice_gstrings_priv_flags[i];
1196
+
1197
+ if (flags & BIT(i))
1198
+ set_bit(priv_flag->bitno, pf->flags);
1199
+ else
1200
+ clear_bit(priv_flag->bitno, pf->flags);
1201
+ }
1202
+
1203
+ bitmap_xor(change_flags, pf->flags, orig_flags, ICE_PF_FLAGS_NBITS);
1204
+
1205
+ /* Do not allow change to link-down-on-close when Total Port Shutdown
1206
+ * is enabled.
1207
+ */
1208
+ if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, change_flags) &&
1209
+ test_bit(ICE_FLAG_TOTAL_PORT_SHUTDOWN_ENA, pf->flags)) {
1210
+ dev_err(dev, "Setting link-down-on-close not supported on this port\n");
1211
+ set_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags);
1212
+ ret = -EINVAL;
1213
+ goto ethtool_exit;
1214
+ }
1215
+
1216
+ if (test_bit(ICE_FLAG_FW_LLDP_AGENT, change_flags)) {
1217
+ if (!test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) {
1218
+ enum ice_status status;
1219
+
1220
+ /* Disable FW LLDP engine */
1221
+ status = ice_cfg_lldp_mib_change(&pf->hw, false);
1222
+
1223
+ /* If unregistering for LLDP events fails, this is
1224
+ * not an error state, as there shouldn't be any
1225
+ * events to respond to.
1226
+ */
1227
+ if (status)
1228
+ dev_info(dev, "Failed to unreg for LLDP events\n");
1229
+
1230
+ /* The AQ call to stop the FW LLDP agent will generate
1231
+ * an error if the agent is already stopped.
1232
+ */
1233
+ status = ice_aq_stop_lldp(&pf->hw, true, true, NULL);
1234
+ if (status)
1235
+ dev_warn(dev, "Fail to stop LLDP agent\n");
1236
+ /* Use case for having the FW LLDP agent stopped
1237
+ * will likely not need DCB, so failure to init is
1238
+ * not a concern of ethtool
1239
+ */
1240
+ status = ice_init_pf_dcb(pf, true);
1241
+ if (status)
1242
+ dev_warn(dev, "Fail to init DCB\n");
1243
+
1244
+ pf->dcbx_cap &= ~DCB_CAP_DCBX_LLD_MANAGED;
1245
+ pf->dcbx_cap |= DCB_CAP_DCBX_HOST;
1246
+ } else {
1247
+ enum ice_status status;
1248
+ bool dcbx_agent_status;
1249
+
1250
+ /* AQ command to start FW LLDP agent will return an
1251
+ * error if the agent is already started
1252
+ */
1253
+ status = ice_aq_start_lldp(&pf->hw, true, NULL);
1254
+ if (status)
1255
+ dev_warn(dev, "Fail to start LLDP Agent\n");
1256
+
1257
+ /* AQ command to start FW DCBX agent will fail if
1258
+ * the agent is already started
1259
+ */
1260
+ status = ice_aq_start_stop_dcbx(&pf->hw, true,
1261
+ &dcbx_agent_status,
1262
+ NULL);
1263
+ if (status)
1264
+ dev_dbg(dev, "Failed to start FW DCBX\n");
1265
+
1266
+ dev_info(dev, "FW DCBX agent is %s\n",
1267
+ dcbx_agent_status ? "ACTIVE" : "DISABLED");
1268
+
1269
+ /* Failure to configure MIB change or init DCB is not
1270
+ * relevant to ethtool. Print notification that
1271
+ * registration/init failed but do not return error
1272
+ * state to ethtool
1273
+ */
1274
+ status = ice_init_pf_dcb(pf, true);
1275
+ if (status)
1276
+ dev_dbg(dev, "Fail to init DCB\n");
1277
+
1278
+ /* Remove rule to direct LLDP packets to default VSI.
1279
+ * The FW LLDP engine will now be consuming them.
1280
+ */
1281
+ ice_cfg_sw_lldp(vsi, false, false);
1282
+
1283
+ /* Register for MIB change events */
1284
+ status = ice_cfg_lldp_mib_change(&pf->hw, true);
1285
+ if (status)
1286
+ dev_dbg(dev, "Fail to enable MIB change events\n");
1287
+
1288
+ pf->dcbx_cap &= ~DCB_CAP_DCBX_HOST;
1289
+ pf->dcbx_cap |= DCB_CAP_DCBX_LLD_MANAGED;
1290
+
1291
+ ice_nway_reset(netdev);
1292
+ }
1293
+ }
1294
+ if (test_bit(ICE_FLAG_LEGACY_RX, change_flags)) {
1295
+ /* down and up VSI so that changes of Rx cfg are reflected. */
1296
+ ice_down(vsi);
1297
+ ice_up(vsi);
1298
+ }
1299
+ /* don't allow modification of this flag when a single VF is in
1300
+ * promiscuous mode because it's not supported
1301
+ */
1302
+ if (test_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, change_flags) &&
1303
+ ice_is_any_vf_in_promisc(pf)) {
1304
+ dev_err(dev, "Changing vf-true-promisc-support flag while VF(s) are in promiscuous mode not supported\n");
1305
+ /* toggle bit back to previous state */
1306
+ change_bit(ICE_FLAG_VF_TRUE_PROMISC_ENA, pf->flags);
1307
+ ret = -EAGAIN;
1308
+ }
1309
+ethtool_exit:
1310
+ clear_bit(ICE_FLAG_ETHTOOL_CTXT, pf->flags);
1311
+ return ret;
2501312 }
2511313
2521314 static int ice_get_sset_count(struct net_device *netdev, int sset)
....@@ -260,10 +1322,10 @@
2601322 * a private ethtool flag). This is due to the nature of the
2611323 * ethtool stats API.
2621324 *
263
- * User space programs such as ethtool must make 3 separate
1325
+ * Userspace programs such as ethtool must make 3 separate
2641326 * ioctl requests, one for size, one for the strings, and
2651327 * finally one for the stats. Since these cross into
266
- * user space, changes to the number or size could result in
1328
+ * userspace, changes to the number or size could result in
2671329 * undefined memory access or incorrect string<->value
2681330 * correlations for statistics.
2691331 *
....@@ -272,6 +1334,10 @@
2721334 * not safe.
2731335 */
2741336 return ICE_ALL_STATS_LEN(netdev);
1337
+ case ETH_SS_TEST:
1338
+ return ICE_TEST_LEN;
1339
+ case ETH_SS_PRIV_FLAGS:
1340
+ return ICE_PRIV_FLAG_ARRAY_SIZE;
2751341 default:
2761342 return -EOPNOTSUPP;
2771343 }
....@@ -285,14 +1351,17 @@
2851351 struct ice_vsi *vsi = np->vsi;
2861352 struct ice_pf *pf = vsi->back;
2871353 struct ice_ring *ring;
288
- unsigned int j = 0;
1354
+ unsigned int j;
2891355 int i = 0;
2901356 char *p;
1357
+
1358
+ ice_update_pf_stats(pf);
1359
+ ice_update_vsi_stats(vsi);
2911360
2921361 for (j = 0; j < ICE_VSI_STATS_LEN; j++) {
2931362 p = (char *)vsi + ice_gstrings_vsi_stats[j].stat_offset;
2941363 data[i++] = (ice_gstrings_vsi_stats[j].sizeof_stat ==
295
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1364
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
2961365 }
2971366
2981367 /* populate per queue stats */
....@@ -330,60 +1399,548 @@
3301399 data[i++] = (ice_gstrings_pf_stats[j].sizeof_stat ==
3311400 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
3321401 }
1402
+
1403
+ for (j = 0; j < ICE_MAX_USER_PRIORITY; j++) {
1404
+ data[i++] = pf->stats.priority_xon_tx[j];
1405
+ data[i++] = pf->stats.priority_xoff_tx[j];
1406
+ }
1407
+
1408
+ for (j = 0; j < ICE_MAX_USER_PRIORITY; j++) {
1409
+ data[i++] = pf->stats.priority_xon_rx[j];
1410
+ data[i++] = pf->stats.priority_xoff_rx[j];
1411
+ }
3331412 }
3341413
1414
+#define ICE_PHY_TYPE_LOW_MASK_MIN_1G (ICE_PHY_TYPE_LOW_100BASE_TX | \
1415
+ ICE_PHY_TYPE_LOW_100M_SGMII)
1416
+
1417
+#define ICE_PHY_TYPE_LOW_MASK_MIN_25G (ICE_PHY_TYPE_LOW_MASK_MIN_1G | \
1418
+ ICE_PHY_TYPE_LOW_1000BASE_T | \
1419
+ ICE_PHY_TYPE_LOW_1000BASE_SX | \
1420
+ ICE_PHY_TYPE_LOW_1000BASE_LX | \
1421
+ ICE_PHY_TYPE_LOW_1000BASE_KX | \
1422
+ ICE_PHY_TYPE_LOW_1G_SGMII | \
1423
+ ICE_PHY_TYPE_LOW_2500BASE_T | \
1424
+ ICE_PHY_TYPE_LOW_2500BASE_X | \
1425
+ ICE_PHY_TYPE_LOW_2500BASE_KX | \
1426
+ ICE_PHY_TYPE_LOW_5GBASE_T | \
1427
+ ICE_PHY_TYPE_LOW_5GBASE_KR | \
1428
+ ICE_PHY_TYPE_LOW_10GBASE_T | \
1429
+ ICE_PHY_TYPE_LOW_10G_SFI_DA | \
1430
+ ICE_PHY_TYPE_LOW_10GBASE_SR | \
1431
+ ICE_PHY_TYPE_LOW_10GBASE_LR | \
1432
+ ICE_PHY_TYPE_LOW_10GBASE_KR_CR1 | \
1433
+ ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC | \
1434
+ ICE_PHY_TYPE_LOW_10G_SFI_C2C)
1435
+
1436
+#define ICE_PHY_TYPE_LOW_MASK_100G (ICE_PHY_TYPE_LOW_100GBASE_CR4 | \
1437
+ ICE_PHY_TYPE_LOW_100GBASE_SR4 | \
1438
+ ICE_PHY_TYPE_LOW_100GBASE_LR4 | \
1439
+ ICE_PHY_TYPE_LOW_100GBASE_KR4 | \
1440
+ ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC | \
1441
+ ICE_PHY_TYPE_LOW_100G_CAUI4 | \
1442
+ ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC | \
1443
+ ICE_PHY_TYPE_LOW_100G_AUI4 | \
1444
+ ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 | \
1445
+ ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 | \
1446
+ ICE_PHY_TYPE_LOW_100GBASE_CP2 | \
1447
+ ICE_PHY_TYPE_LOW_100GBASE_SR2 | \
1448
+ ICE_PHY_TYPE_LOW_100GBASE_DR)
1449
+
1450
+#define ICE_PHY_TYPE_HIGH_MASK_100G (ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4 | \
1451
+ ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |\
1452
+ ICE_PHY_TYPE_HIGH_100G_CAUI2 | \
1453
+ ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC | \
1454
+ ICE_PHY_TYPE_HIGH_100G_AUI2)
1455
+
1456
+/**
1457
+ * ice_mask_min_supported_speeds
1458
+ * @phy_types_high: PHY type high
1459
+ * @phy_types_low: PHY type low to apply minimum supported speeds mask
1460
+ *
1461
+ * Apply minimum supported speeds mask to PHY type low. These are the speeds
1462
+ * for ethtool supported link mode.
1463
+ */
1464
+static
1465
+void ice_mask_min_supported_speeds(u64 phy_types_high, u64 *phy_types_low)
1466
+{
1467
+ /* if QSFP connection with 100G speed, minimum supported speed is 25G */
1468
+ if (*phy_types_low & ICE_PHY_TYPE_LOW_MASK_100G ||
1469
+ phy_types_high & ICE_PHY_TYPE_HIGH_MASK_100G)
1470
+ *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_25G;
1471
+ else
1472
+ *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_1G;
1473
+}
1474
+
1475
+#define ice_ethtool_advertise_link_mode(aq_link_speed, ethtool_link_mode) \
1476
+ do { \
1477
+ if (req_speeds & (aq_link_speed) || \
1478
+ (!req_speeds && \
1479
+ (adv_phy_type_lo & phy_type_mask_lo || \
1480
+ adv_phy_type_hi & phy_type_mask_hi))) \
1481
+ ethtool_link_ksettings_add_link_mode(ks, advertising,\
1482
+ ethtool_link_mode); \
1483
+ } while (0)
1484
+
1485
+/**
1486
+ * ice_phy_type_to_ethtool - convert the phy_types to ethtool link modes
1487
+ * @netdev: network interface device structure
1488
+ * @ks: ethtool link ksettings struct to fill out
1489
+ */
1490
+static void
1491
+ice_phy_type_to_ethtool(struct net_device *netdev,
1492
+ struct ethtool_link_ksettings *ks)
1493
+{
1494
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1495
+ struct ice_vsi *vsi = np->vsi;
1496
+ struct ice_pf *pf = vsi->back;
1497
+ u64 phy_type_mask_lo = 0;
1498
+ u64 phy_type_mask_hi = 0;
1499
+ u64 adv_phy_type_lo = 0;
1500
+ u64 adv_phy_type_hi = 0;
1501
+ u64 phy_types_high = 0;
1502
+ u64 phy_types_low = 0;
1503
+ u16 req_speeds;
1504
+
1505
+ req_speeds = vsi->port_info->phy.link_info.req_speeds;
1506
+
1507
+ /* Check if lenient mode is supported and enabled, or in strict mode.
1508
+ *
1509
+ * In lenient mode the Supported link modes are the PHY types without
1510
+ * media. The Advertising link mode is either 1. the user requested
1511
+ * speed, 2. the override PHY mask, or 3. the PHY types with media.
1512
+ *
1513
+ * In strict mode Supported link mode are the PHY type with media,
1514
+ * and Advertising link modes are the media PHY type or the speed
1515
+ * requested by user.
1516
+ */
1517
+ if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
1518
+ struct ice_link_default_override_tlv *ldo;
1519
+
1520
+ ldo = &pf->link_dflt_override;
1521
+ phy_types_low = le64_to_cpu(pf->nvm_phy_type_lo);
1522
+ phy_types_high = le64_to_cpu(pf->nvm_phy_type_hi);
1523
+
1524
+ ice_mask_min_supported_speeds(phy_types_high, &phy_types_low);
1525
+
1526
+ /* If override enabled and PHY mask set, then
1527
+ * Advertising link mode is the intersection of the PHY
1528
+ * types without media and the override PHY mask.
1529
+ */
1530
+ if (ldo->options & ICE_LINK_OVERRIDE_EN &&
1531
+ (ldo->phy_type_low || ldo->phy_type_high)) {
1532
+ adv_phy_type_lo =
1533
+ le64_to_cpu(pf->nvm_phy_type_lo) &
1534
+ ldo->phy_type_low;
1535
+ adv_phy_type_hi =
1536
+ le64_to_cpu(pf->nvm_phy_type_hi) &
1537
+ ldo->phy_type_high;
1538
+ }
1539
+ } else {
1540
+ phy_types_low = vsi->port_info->phy.phy_type_low;
1541
+ phy_types_high = vsi->port_info->phy.phy_type_high;
1542
+ }
1543
+
1544
+ /* If Advertising link mode PHY type is not using override PHY type,
1545
+ * then use PHY type with media.
1546
+ */
1547
+ if (!adv_phy_type_lo && !adv_phy_type_hi) {
1548
+ adv_phy_type_lo = vsi->port_info->phy.phy_type_low;
1549
+ adv_phy_type_hi = vsi->port_info->phy.phy_type_high;
1550
+ }
1551
+
1552
+ ethtool_link_ksettings_zero_link_mode(ks, supported);
1553
+ ethtool_link_ksettings_zero_link_mode(ks, advertising);
1554
+
1555
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100BASE_TX |
1556
+ ICE_PHY_TYPE_LOW_100M_SGMII;
1557
+ if (phy_types_low & phy_type_mask_lo) {
1558
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1559
+ 100baseT_Full);
1560
+
1561
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100MB,
1562
+ 100baseT_Full);
1563
+ }
1564
+
1565
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_T |
1566
+ ICE_PHY_TYPE_LOW_1G_SGMII;
1567
+ if (phy_types_low & phy_type_mask_lo) {
1568
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1569
+ 1000baseT_Full);
1570
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
1571
+ 1000baseT_Full);
1572
+ }
1573
+
1574
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_KX;
1575
+ if (phy_types_low & phy_type_mask_lo) {
1576
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1577
+ 1000baseKX_Full);
1578
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
1579
+ 1000baseKX_Full);
1580
+ }
1581
+
1582
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_SX |
1583
+ ICE_PHY_TYPE_LOW_1000BASE_LX;
1584
+ if (phy_types_low & phy_type_mask_lo) {
1585
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1586
+ 1000baseX_Full);
1587
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
1588
+ 1000baseX_Full);
1589
+ }
1590
+
1591
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_T;
1592
+ if (phy_types_low & phy_type_mask_lo) {
1593
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1594
+ 2500baseT_Full);
1595
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
1596
+ 2500baseT_Full);
1597
+ }
1598
+
1599
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_X |
1600
+ ICE_PHY_TYPE_LOW_2500BASE_KX;
1601
+ if (phy_types_low & phy_type_mask_lo) {
1602
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1603
+ 2500baseX_Full);
1604
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
1605
+ 2500baseX_Full);
1606
+ }
1607
+
1608
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_5GBASE_T |
1609
+ ICE_PHY_TYPE_LOW_5GBASE_KR;
1610
+ if (phy_types_low & phy_type_mask_lo) {
1611
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1612
+ 5000baseT_Full);
1613
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_5GB,
1614
+ 5000baseT_Full);
1615
+ }
1616
+
1617
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_T |
1618
+ ICE_PHY_TYPE_LOW_10G_SFI_DA |
1619
+ ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC |
1620
+ ICE_PHY_TYPE_LOW_10G_SFI_C2C;
1621
+ if (phy_types_low & phy_type_mask_lo) {
1622
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1623
+ 10000baseT_Full);
1624
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
1625
+ 10000baseT_Full);
1626
+ }
1627
+
1628
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_KR_CR1;
1629
+ if (phy_types_low & phy_type_mask_lo) {
1630
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1631
+ 10000baseKR_Full);
1632
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
1633
+ 10000baseKR_Full);
1634
+ }
1635
+
1636
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_SR;
1637
+ if (phy_types_low & phy_type_mask_lo) {
1638
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1639
+ 10000baseSR_Full);
1640
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
1641
+ 10000baseSR_Full);
1642
+ }
1643
+
1644
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_LR;
1645
+ if (phy_types_low & phy_type_mask_lo) {
1646
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1647
+ 10000baseLR_Full);
1648
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
1649
+ 10000baseLR_Full);
1650
+ }
1651
+
1652
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_T |
1653
+ ICE_PHY_TYPE_LOW_25GBASE_CR |
1654
+ ICE_PHY_TYPE_LOW_25GBASE_CR_S |
1655
+ ICE_PHY_TYPE_LOW_25GBASE_CR1 |
1656
+ ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC |
1657
+ ICE_PHY_TYPE_LOW_25G_AUI_C2C;
1658
+ if (phy_types_low & phy_type_mask_lo) {
1659
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1660
+ 25000baseCR_Full);
1661
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
1662
+ 25000baseCR_Full);
1663
+ }
1664
+
1665
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_SR |
1666
+ ICE_PHY_TYPE_LOW_25GBASE_LR;
1667
+ if (phy_types_low & phy_type_mask_lo) {
1668
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1669
+ 25000baseSR_Full);
1670
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
1671
+ 25000baseSR_Full);
1672
+ }
1673
+
1674
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_KR |
1675
+ ICE_PHY_TYPE_LOW_25GBASE_KR_S |
1676
+ ICE_PHY_TYPE_LOW_25GBASE_KR1;
1677
+ if (phy_types_low & phy_type_mask_lo) {
1678
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1679
+ 25000baseKR_Full);
1680
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
1681
+ 25000baseKR_Full);
1682
+ }
1683
+
1684
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_KR4;
1685
+ if (phy_types_low & phy_type_mask_lo) {
1686
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1687
+ 40000baseKR4_Full);
1688
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
1689
+ 40000baseKR4_Full);
1690
+ }
1691
+
1692
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_CR4 |
1693
+ ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC |
1694
+ ICE_PHY_TYPE_LOW_40G_XLAUI;
1695
+ if (phy_types_low & phy_type_mask_lo) {
1696
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1697
+ 40000baseCR4_Full);
1698
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
1699
+ 40000baseCR4_Full);
1700
+ }
1701
+
1702
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_SR4;
1703
+ if (phy_types_low & phy_type_mask_lo) {
1704
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1705
+ 40000baseSR4_Full);
1706
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
1707
+ 40000baseSR4_Full);
1708
+ }
1709
+
1710
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_LR4;
1711
+ if (phy_types_low & phy_type_mask_lo) {
1712
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1713
+ 40000baseLR4_Full);
1714
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
1715
+ 40000baseLR4_Full);
1716
+ }
1717
+
1718
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_CR2 |
1719
+ ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC |
1720
+ ICE_PHY_TYPE_LOW_50G_LAUI2 |
1721
+ ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC |
1722
+ ICE_PHY_TYPE_LOW_50G_AUI2 |
1723
+ ICE_PHY_TYPE_LOW_50GBASE_CP |
1724
+ ICE_PHY_TYPE_LOW_50GBASE_SR |
1725
+ ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC |
1726
+ ICE_PHY_TYPE_LOW_50G_AUI1;
1727
+ if (phy_types_low & phy_type_mask_lo) {
1728
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1729
+ 50000baseCR2_Full);
1730
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
1731
+ 50000baseCR2_Full);
1732
+ }
1733
+
1734
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_KR2 |
1735
+ ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4;
1736
+ if (phy_types_low & phy_type_mask_lo) {
1737
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1738
+ 50000baseKR2_Full);
1739
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
1740
+ 50000baseKR2_Full);
1741
+ }
1742
+
1743
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_SR2 |
1744
+ ICE_PHY_TYPE_LOW_50GBASE_LR2 |
1745
+ ICE_PHY_TYPE_LOW_50GBASE_FR |
1746
+ ICE_PHY_TYPE_LOW_50GBASE_LR;
1747
+ if (phy_types_low & phy_type_mask_lo) {
1748
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1749
+ 50000baseSR2_Full);
1750
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
1751
+ 50000baseSR2_Full);
1752
+ }
1753
+
1754
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_CR4 |
1755
+ ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC |
1756
+ ICE_PHY_TYPE_LOW_100G_CAUI4 |
1757
+ ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC |
1758
+ ICE_PHY_TYPE_LOW_100G_AUI4 |
1759
+ ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 |
1760
+ ICE_PHY_TYPE_LOW_100GBASE_CP2;
1761
+ phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |
1762
+ ICE_PHY_TYPE_HIGH_100G_CAUI2 |
1763
+ ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC |
1764
+ ICE_PHY_TYPE_HIGH_100G_AUI2;
1765
+ if (phy_types_low & phy_type_mask_lo ||
1766
+ phy_types_high & phy_type_mask_hi) {
1767
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1768
+ 100000baseCR4_Full);
1769
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
1770
+ 100000baseCR4_Full);
1771
+ }
1772
+
1773
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_SR4 |
1774
+ ICE_PHY_TYPE_LOW_100GBASE_SR2;
1775
+ if (phy_types_low & phy_type_mask_lo) {
1776
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1777
+ 100000baseSR4_Full);
1778
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
1779
+ 100000baseSR4_Full);
1780
+ }
1781
+
1782
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_LR4 |
1783
+ ICE_PHY_TYPE_LOW_100GBASE_DR;
1784
+ if (phy_types_low & phy_type_mask_lo) {
1785
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1786
+ 100000baseLR4_ER4_Full);
1787
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
1788
+ 100000baseLR4_ER4_Full);
1789
+ }
1790
+
1791
+ phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_KR4 |
1792
+ ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4;
1793
+ phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4;
1794
+ if (phy_types_low & phy_type_mask_lo ||
1795
+ phy_types_high & phy_type_mask_hi) {
1796
+ ethtool_link_ksettings_add_link_mode(ks, supported,
1797
+ 100000baseKR4_Full);
1798
+ ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
1799
+ 100000baseKR4_Full);
1800
+ }
1801
+}
1802
+
1803
+#define TEST_SET_BITS_TIMEOUT 50
1804
+#define TEST_SET_BITS_SLEEP_MAX 2000
1805
+#define TEST_SET_BITS_SLEEP_MIN 1000
1806
+
1807
+/**
1808
+ * ice_get_settings_link_up - Get Link settings for when link is up
1809
+ * @ks: ethtool ksettings to fill in
1810
+ * @netdev: network interface device structure
1811
+ */
1812
+static void
1813
+ice_get_settings_link_up(struct ethtool_link_ksettings *ks,
1814
+ struct net_device *netdev)
1815
+{
1816
+ struct ice_netdev_priv *np = netdev_priv(netdev);
1817
+ struct ice_port_info *pi = np->vsi->port_info;
1818
+ struct ice_link_status *link_info;
1819
+ struct ice_vsi *vsi = np->vsi;
1820
+
1821
+ link_info = &vsi->port_info->phy.link_info;
1822
+
1823
+ /* Get supported and advertised settings from PHY ability with media */
1824
+ ice_phy_type_to_ethtool(netdev, ks);
1825
+
1826
+ switch (link_info->link_speed) {
1827
+ case ICE_AQ_LINK_SPEED_100GB:
1828
+ ks->base.speed = SPEED_100000;
1829
+ break;
1830
+ case ICE_AQ_LINK_SPEED_50GB:
1831
+ ks->base.speed = SPEED_50000;
1832
+ break;
1833
+ case ICE_AQ_LINK_SPEED_40GB:
1834
+ ks->base.speed = SPEED_40000;
1835
+ break;
1836
+ case ICE_AQ_LINK_SPEED_25GB:
1837
+ ks->base.speed = SPEED_25000;
1838
+ break;
1839
+ case ICE_AQ_LINK_SPEED_20GB:
1840
+ ks->base.speed = SPEED_20000;
1841
+ break;
1842
+ case ICE_AQ_LINK_SPEED_10GB:
1843
+ ks->base.speed = SPEED_10000;
1844
+ break;
1845
+ case ICE_AQ_LINK_SPEED_5GB:
1846
+ ks->base.speed = SPEED_5000;
1847
+ break;
1848
+ case ICE_AQ_LINK_SPEED_2500MB:
1849
+ ks->base.speed = SPEED_2500;
1850
+ break;
1851
+ case ICE_AQ_LINK_SPEED_1000MB:
1852
+ ks->base.speed = SPEED_1000;
1853
+ break;
1854
+ case ICE_AQ_LINK_SPEED_100MB:
1855
+ ks->base.speed = SPEED_100;
1856
+ break;
1857
+ default:
1858
+ netdev_info(netdev, "WARNING: Unrecognized link_speed (0x%x).\n",
1859
+ link_info->link_speed);
1860
+ break;
1861
+ }
1862
+ ks->base.duplex = DUPLEX_FULL;
1863
+
1864
+ if (link_info->an_info & ICE_AQ_AN_COMPLETED)
1865
+ ethtool_link_ksettings_add_link_mode(ks, lp_advertising,
1866
+ Autoneg);
1867
+
1868
+ /* Set flow control negotiated Rx/Tx pause */
1869
+ switch (pi->fc.current_mode) {
1870
+ case ICE_FC_FULL:
1871
+ ethtool_link_ksettings_add_link_mode(ks, lp_advertising, Pause);
1872
+ break;
1873
+ case ICE_FC_TX_PAUSE:
1874
+ ethtool_link_ksettings_add_link_mode(ks, lp_advertising, Pause);
1875
+ ethtool_link_ksettings_add_link_mode(ks, lp_advertising,
1876
+ Asym_Pause);
1877
+ break;
1878
+ case ICE_FC_RX_PAUSE:
1879
+ ethtool_link_ksettings_add_link_mode(ks, lp_advertising,
1880
+ Asym_Pause);
1881
+ break;
1882
+ case ICE_FC_PFC:
1883
+ default:
1884
+ ethtool_link_ksettings_del_link_mode(ks, lp_advertising, Pause);
1885
+ ethtool_link_ksettings_del_link_mode(ks, lp_advertising,
1886
+ Asym_Pause);
1887
+ break;
1888
+ }
1889
+}
1890
+
1891
+/**
1892
+ * ice_get_settings_link_down - Get the Link settings when link is down
1893
+ * @ks: ethtool ksettings to fill in
1894
+ * @netdev: network interface device structure
1895
+ *
1896
+ * Reports link settings that can be determined when link is down
1897
+ */
1898
+static void
1899
+ice_get_settings_link_down(struct ethtool_link_ksettings *ks,
1900
+ struct net_device *netdev)
1901
+{
1902
+ /* link is down and the driver needs to fall back on
1903
+ * supported PHY types to figure out what info to display
1904
+ */
1905
+ ice_phy_type_to_ethtool(netdev, ks);
1906
+
1907
+ /* With no link, speed and duplex are unknown */
1908
+ ks->base.speed = SPEED_UNKNOWN;
1909
+ ks->base.duplex = DUPLEX_UNKNOWN;
1910
+}
1911
+
1912
+/**
1913
+ * ice_get_link_ksettings - Get Link Speed and Duplex settings
1914
+ * @netdev: network interface device structure
1915
+ * @ks: ethtool ksettings
1916
+ *
1917
+ * Reports speed/duplex settings based on media_type
1918
+ */
3351919 static int
3361920 ice_get_link_ksettings(struct net_device *netdev,
3371921 struct ethtool_link_ksettings *ks)
3381922 {
3391923 struct ice_netdev_priv *np = netdev_priv(netdev);
1924
+ struct ice_aqc_get_phy_caps_data *caps;
3401925 struct ice_link_status *hw_link_info;
3411926 struct ice_vsi *vsi = np->vsi;
342
- bool link_up;
1927
+ enum ice_status status;
1928
+ int err = 0;
3431929
1930
+ ethtool_link_ksettings_zero_link_mode(ks, supported);
1931
+ ethtool_link_ksettings_zero_link_mode(ks, advertising);
1932
+ ethtool_link_ksettings_zero_link_mode(ks, lp_advertising);
3441933 hw_link_info = &vsi->port_info->phy.link_info;
345
- link_up = hw_link_info->link_info & ICE_AQ_LINK_UP;
346
-
347
- ethtool_link_ksettings_add_link_mode(ks, supported,
348
- 10000baseT_Full);
349
- ethtool_link_ksettings_add_link_mode(ks, advertising,
350
- 10000baseT_Full);
3511934
3521935 /* set speed and duplex */
353
- if (link_up) {
354
- switch (hw_link_info->link_speed) {
355
- case ICE_AQ_LINK_SPEED_100MB:
356
- ks->base.speed = SPEED_100;
357
- break;
358
- case ICE_AQ_LINK_SPEED_2500MB:
359
- ks->base.speed = SPEED_2500;
360
- break;
361
- case ICE_AQ_LINK_SPEED_5GB:
362
- ks->base.speed = SPEED_5000;
363
- break;
364
- case ICE_AQ_LINK_SPEED_10GB:
365
- ks->base.speed = SPEED_10000;
366
- break;
367
- case ICE_AQ_LINK_SPEED_25GB:
368
- ks->base.speed = SPEED_25000;
369
- break;
370
- case ICE_AQ_LINK_SPEED_40GB:
371
- ks->base.speed = SPEED_40000;
372
- break;
373
- default:
374
- ks->base.speed = SPEED_UNKNOWN;
375
- break;
376
- }
377
-
378
- ks->base.duplex = DUPLEX_FULL;
379
- } else {
380
- ks->base.speed = SPEED_UNKNOWN;
381
- ks->base.duplex = DUPLEX_UNKNOWN;
382
- }
1936
+ if (hw_link_info->link_info & ICE_AQ_LINK_UP)
1937
+ ice_get_settings_link_up(ks, netdev);
1938
+ else
1939
+ ice_get_settings_link_down(ks, netdev);
3831940
3841941 /* set autoneg settings */
385
- ks->base.autoneg = ((hw_link_info->an_info & ICE_AQ_AN_COMPLETED) ?
386
- AUTONEG_ENABLE : AUTONEG_DISABLE);
1942
+ ks->base.autoneg = (hw_link_info->an_info & ICE_AQ_AN_COMPLETED) ?
1943
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
3871944
3881945 /* set media type settings */
3891946 switch (vsi->port_info->phy.media_type) {
....@@ -397,9 +1954,7 @@
3971954 ks->base.port = PORT_TP;
3981955 break;
3991956 case ICE_MEDIA_BACKPLANE:
400
- ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
4011957 ethtool_link_ksettings_add_link_mode(ks, supported, Backplane);
402
- ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
4031958 ethtool_link_ksettings_add_link_mode(ks, advertising,
4041959 Backplane);
4051960 ks->base.port = PORT_NONE;
....@@ -417,48 +1972,733 @@
4171972 /* flow control is symmetric and always supported */
4181973 ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
4191974
420
- switch (vsi->port_info->fc.req_mode) {
421
- case ICE_FC_FULL:
422
- ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
423
- break;
424
- case ICE_FC_TX_PAUSE:
425
- ethtool_link_ksettings_add_link_mode(ks, advertising,
426
- Asym_Pause);
427
- break;
428
- case ICE_FC_RX_PAUSE:
1975
+ caps = kzalloc(sizeof(*caps), GFP_KERNEL);
1976
+ if (!caps)
1977
+ return -ENOMEM;
1978
+
1979
+ status = ice_aq_get_phy_caps(vsi->port_info, false,
1980
+ ICE_AQC_REPORT_ACTIVE_CFG, caps, NULL);
1981
+ if (status) {
1982
+ err = -EIO;
1983
+ goto done;
1984
+ }
1985
+
1986
+ /* Set the advertised flow control based on the PHY capability */
1987
+ if ((caps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE) &&
1988
+ (caps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)) {
4291989 ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
4301990 ethtool_link_ksettings_add_link_mode(ks, advertising,
4311991 Asym_Pause);
432
- break;
433
- case ICE_FC_PFC:
434
- default:
1992
+ } else if (caps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE) {
1993
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
1994
+ Asym_Pause);
1995
+ } else if (caps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE) {
1996
+ ethtool_link_ksettings_add_link_mode(ks, advertising, Pause);
1997
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
1998
+ Asym_Pause);
1999
+ } else {
4352000 ethtool_link_ksettings_del_link_mode(ks, advertising, Pause);
4362001 ethtool_link_ksettings_del_link_mode(ks, advertising,
4372002 Asym_Pause);
2003
+ }
2004
+
2005
+ /* Set advertised FEC modes based on PHY capability */
2006
+ ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE);
2007
+
2008
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ ||
2009
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_REQ)
2010
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
2011
+ FEC_BASER);
2012
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_528_REQ ||
2013
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_544_REQ)
2014
+ ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
2015
+
2016
+ status = ice_aq_get_phy_caps(vsi->port_info, false,
2017
+ ICE_AQC_REPORT_TOPO_CAP_MEDIA, caps, NULL);
2018
+ if (status) {
2019
+ err = -EIO;
2020
+ goto done;
2021
+ }
2022
+
2023
+ /* Set supported FEC modes based on PHY capability */
2024
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
2025
+
2026
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN ||
2027
+ caps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN)
2028
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
2029
+ if (caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN)
2030
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
2031
+
2032
+ /* Set supported and advertised autoneg */
2033
+ if (ice_is_phy_caps_an_enabled(caps)) {
2034
+ ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
2035
+ ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
2036
+ }
2037
+
2038
+done:
2039
+ kfree(caps);
2040
+ return err;
2041
+}
2042
+
2043
+/**
2044
+ * ice_ksettings_find_adv_link_speed - Find advertising link speed
2045
+ * @ks: ethtool ksettings
2046
+ */
2047
+static u16
2048
+ice_ksettings_find_adv_link_speed(const struct ethtool_link_ksettings *ks)
2049
+{
2050
+ u16 adv_link_speed = 0;
2051
+
2052
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2053
+ 100baseT_Full))
2054
+ adv_link_speed |= ICE_AQ_LINK_SPEED_100MB;
2055
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2056
+ 1000baseX_Full))
2057
+ adv_link_speed |= ICE_AQ_LINK_SPEED_1000MB;
2058
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2059
+ 1000baseT_Full) ||
2060
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2061
+ 1000baseKX_Full))
2062
+ adv_link_speed |= ICE_AQ_LINK_SPEED_1000MB;
2063
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2064
+ 2500baseT_Full))
2065
+ adv_link_speed |= ICE_AQ_LINK_SPEED_2500MB;
2066
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2067
+ 2500baseX_Full))
2068
+ adv_link_speed |= ICE_AQ_LINK_SPEED_2500MB;
2069
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2070
+ 5000baseT_Full))
2071
+ adv_link_speed |= ICE_AQ_LINK_SPEED_5GB;
2072
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2073
+ 10000baseT_Full) ||
2074
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2075
+ 10000baseKR_Full))
2076
+ adv_link_speed |= ICE_AQ_LINK_SPEED_10GB;
2077
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2078
+ 10000baseSR_Full) ||
2079
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2080
+ 10000baseLR_Full))
2081
+ adv_link_speed |= ICE_AQ_LINK_SPEED_10GB;
2082
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2083
+ 25000baseCR_Full) ||
2084
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2085
+ 25000baseSR_Full) ||
2086
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2087
+ 25000baseKR_Full))
2088
+ adv_link_speed |= ICE_AQ_LINK_SPEED_25GB;
2089
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2090
+ 40000baseCR4_Full) ||
2091
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2092
+ 40000baseSR4_Full) ||
2093
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2094
+ 40000baseLR4_Full) ||
2095
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2096
+ 40000baseKR4_Full))
2097
+ adv_link_speed |= ICE_AQ_LINK_SPEED_40GB;
2098
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2099
+ 50000baseCR2_Full) ||
2100
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2101
+ 50000baseKR2_Full))
2102
+ adv_link_speed |= ICE_AQ_LINK_SPEED_50GB;
2103
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2104
+ 50000baseSR2_Full))
2105
+ adv_link_speed |= ICE_AQ_LINK_SPEED_50GB;
2106
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2107
+ 100000baseCR4_Full) ||
2108
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2109
+ 100000baseSR4_Full) ||
2110
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2111
+ 100000baseLR4_ER4_Full) ||
2112
+ ethtool_link_ksettings_test_link_mode(ks, advertising,
2113
+ 100000baseKR4_Full))
2114
+ adv_link_speed |= ICE_AQ_LINK_SPEED_100GB;
2115
+
2116
+ return adv_link_speed;
2117
+}
2118
+
2119
+/**
2120
+ * ice_setup_autoneg
2121
+ * @p: port info
2122
+ * @ks: ethtool_link_ksettings
2123
+ * @config: configuration that will be sent down to FW
2124
+ * @autoneg_enabled: autonegotiation is enabled or not
2125
+ * @autoneg_changed: will there a change in autonegotiation
2126
+ * @netdev: network interface device structure
2127
+ *
2128
+ * Setup PHY autonegotiation feature
2129
+ */
2130
+static int
2131
+ice_setup_autoneg(struct ice_port_info *p, struct ethtool_link_ksettings *ks,
2132
+ struct ice_aqc_set_phy_cfg_data *config,
2133
+ u8 autoneg_enabled, u8 *autoneg_changed,
2134
+ struct net_device *netdev)
2135
+{
2136
+ int err = 0;
2137
+
2138
+ *autoneg_changed = 0;
2139
+
2140
+ /* Check autoneg */
2141
+ if (autoneg_enabled == AUTONEG_ENABLE) {
2142
+ /* If autoneg was not already enabled */
2143
+ if (!(p->phy.link_info.an_info & ICE_AQ_AN_COMPLETED)) {
2144
+ /* If autoneg is not supported, return error */
2145
+ if (!ethtool_link_ksettings_test_link_mode(ks,
2146
+ supported,
2147
+ Autoneg)) {
2148
+ netdev_info(netdev, "Autoneg not supported on this phy.\n");
2149
+ err = -EINVAL;
2150
+ } else {
2151
+ /* Autoneg is allowed to change */
2152
+ config->caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
2153
+ *autoneg_changed = 1;
2154
+ }
2155
+ }
2156
+ } else {
2157
+ /* If autoneg is currently enabled */
2158
+ if (p->phy.link_info.an_info & ICE_AQ_AN_COMPLETED) {
2159
+ /* If autoneg is supported 10GBASE_T is the only PHY
2160
+ * that can disable it, so otherwise return error
2161
+ */
2162
+ if (ethtool_link_ksettings_test_link_mode(ks,
2163
+ supported,
2164
+ Autoneg)) {
2165
+ netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
2166
+ err = -EINVAL;
2167
+ } else {
2168
+ /* Autoneg is allowed to change */
2169
+ config->caps &= ~ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
2170
+ *autoneg_changed = 1;
2171
+ }
2172
+ }
2173
+ }
2174
+
2175
+ return err;
2176
+}
2177
+
2178
+/**
2179
+ * ice_set_phy_type_from_speed - set phy_types based on speeds
2180
+ * and advertised modes
2181
+ * @ks: ethtool link ksettings struct
2182
+ * @phy_type_low: pointer to the lower part of phy_type
2183
+ * @phy_type_high: pointer to the higher part of phy_type
2184
+ * @adv_link_speed: targeted link speeds bitmap
2185
+ */
2186
+static void
2187
+ice_set_phy_type_from_speed(const struct ethtool_link_ksettings *ks,
2188
+ u64 *phy_type_low, u64 *phy_type_high,
2189
+ u16 adv_link_speed)
2190
+{
2191
+ /* Handle 1000M speed in a special way because ice_update_phy_type
2192
+ * enables all link modes, but having mixed copper and optical
2193
+ * standards is not supported.
2194
+ */
2195
+ adv_link_speed &= ~ICE_AQ_LINK_SPEED_1000MB;
2196
+
2197
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2198
+ 1000baseT_Full))
2199
+ *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_T |
2200
+ ICE_PHY_TYPE_LOW_1G_SGMII;
2201
+
2202
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2203
+ 1000baseKX_Full))
2204
+ *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_KX;
2205
+
2206
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2207
+ 1000baseX_Full))
2208
+ *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_SX |
2209
+ ICE_PHY_TYPE_LOW_1000BASE_LX;
2210
+
2211
+ ice_update_phy_type(phy_type_low, phy_type_high, adv_link_speed);
2212
+}
2213
+
2214
+/**
2215
+ * ice_set_link_ksettings - Set Speed and Duplex
2216
+ * @netdev: network interface device structure
2217
+ * @ks: ethtool ksettings
2218
+ *
2219
+ * Set speed/duplex per media_types advertised/forced
2220
+ */
2221
+static int
2222
+ice_set_link_ksettings(struct net_device *netdev,
2223
+ const struct ethtool_link_ksettings *ks)
2224
+{
2225
+ struct ice_netdev_priv *np = netdev_priv(netdev);
2226
+ struct ethtool_link_ksettings safe_ks, copy_ks;
2227
+ u8 autoneg, timeout = TEST_SET_BITS_TIMEOUT;
2228
+ struct ice_aqc_get_phy_caps_data *phy_caps;
2229
+ struct ice_aqc_set_phy_cfg_data config;
2230
+ u16 adv_link_speed, curr_link_speed;
2231
+ struct ice_pf *pf = np->vsi->back;
2232
+ struct ice_port_info *pi;
2233
+ u8 autoneg_changed = 0;
2234
+ enum ice_status status;
2235
+ u64 phy_type_high = 0;
2236
+ u64 phy_type_low = 0;
2237
+ int err = 0;
2238
+ bool linkup;
2239
+
2240
+ pi = np->vsi->port_info;
2241
+
2242
+ if (!pi)
2243
+ return -EOPNOTSUPP;
2244
+
2245
+ if (pi->phy.media_type != ICE_MEDIA_BASET &&
2246
+ pi->phy.media_type != ICE_MEDIA_FIBER &&
2247
+ pi->phy.media_type != ICE_MEDIA_BACKPLANE &&
2248
+ pi->phy.media_type != ICE_MEDIA_DA &&
2249
+ pi->phy.link_info.link_info & ICE_AQ_LINK_UP)
2250
+ return -EOPNOTSUPP;
2251
+
2252
+ phy_caps = kzalloc(sizeof(*phy_caps), GFP_KERNEL);
2253
+ if (!phy_caps)
2254
+ return -ENOMEM;
2255
+
2256
+ /* Get the PHY capabilities based on media */
2257
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
2258
+ phy_caps, NULL);
2259
+ if (status) {
2260
+ err = -EAGAIN;
2261
+ goto done;
2262
+ }
2263
+
2264
+ /* copy the ksettings to copy_ks to avoid modifying the original */
2265
+ memcpy(&copy_ks, ks, sizeof(copy_ks));
2266
+
2267
+ /* save autoneg out of ksettings */
2268
+ autoneg = copy_ks.base.autoneg;
2269
+
2270
+ memset(&safe_ks, 0, sizeof(safe_ks));
2271
+
2272
+ /* Get link modes supported by hardware.*/
2273
+ ice_phy_type_to_ethtool(netdev, &safe_ks);
2274
+
2275
+ /* and check against modes requested by user.
2276
+ * Return an error if unsupported mode was set.
2277
+ */
2278
+ if (!bitmap_subset(copy_ks.link_modes.advertising,
2279
+ safe_ks.link_modes.supported,
2280
+ __ETHTOOL_LINK_MODE_MASK_NBITS)) {
2281
+ if (!test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags))
2282
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
2283
+ err = -EINVAL;
2284
+ goto done;
2285
+ }
2286
+
2287
+ /* get our own copy of the bits to check against */
2288
+ memset(&safe_ks, 0, sizeof(safe_ks));
2289
+ safe_ks.base.cmd = copy_ks.base.cmd;
2290
+ safe_ks.base.link_mode_masks_nwords =
2291
+ copy_ks.base.link_mode_masks_nwords;
2292
+ ice_get_link_ksettings(netdev, &safe_ks);
2293
+
2294
+ /* set autoneg back to what it currently is */
2295
+ copy_ks.base.autoneg = safe_ks.base.autoneg;
2296
+ /* we don't compare the speed */
2297
+ copy_ks.base.speed = safe_ks.base.speed;
2298
+
2299
+ /* If copy_ks.base and safe_ks.base are not the same now, then they are
2300
+ * trying to set something that we do not support.
2301
+ */
2302
+ if (memcmp(&copy_ks.base, &safe_ks.base, sizeof(copy_ks.base))) {
2303
+ err = -EOPNOTSUPP;
2304
+ goto done;
2305
+ }
2306
+
2307
+ while (test_and_set_bit(__ICE_CFG_BUSY, pf->state)) {
2308
+ timeout--;
2309
+ if (!timeout) {
2310
+ err = -EBUSY;
2311
+ goto done;
2312
+ }
2313
+ usleep_range(TEST_SET_BITS_SLEEP_MIN, TEST_SET_BITS_SLEEP_MAX);
2314
+ }
2315
+
2316
+ /* Copy the current user PHY configuration. The current user PHY
2317
+ * configuration is initialized during probe from PHY capabilities
2318
+ * software mode, and updated on set PHY configuration.
2319
+ */
2320
+ memcpy(&config, &pi->phy.curr_user_phy_cfg, sizeof(config));
2321
+
2322
+ config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
2323
+
2324
+ /* Check autoneg */
2325
+ err = ice_setup_autoneg(pi, &safe_ks, &config, autoneg, &autoneg_changed,
2326
+ netdev);
2327
+
2328
+ if (err)
2329
+ goto done;
2330
+
2331
+ /* Call to get the current link speed */
2332
+ pi->phy.get_link_info = true;
2333
+ status = ice_get_link_status(pi, &linkup);
2334
+ if (status) {
2335
+ err = -EAGAIN;
2336
+ goto done;
2337
+ }
2338
+
2339
+ curr_link_speed = pi->phy.curr_user_speed_req;
2340
+ adv_link_speed = ice_ksettings_find_adv_link_speed(ks);
2341
+
2342
+ /* If speed didn't get set, set it to what it currently is.
2343
+ * This is needed because if advertise is 0 (as it is when autoneg
2344
+ * is disabled) then speed won't get set.
2345
+ */
2346
+ if (!adv_link_speed)
2347
+ adv_link_speed = curr_link_speed;
2348
+
2349
+ /* Convert the advertise link speeds to their corresponded PHY_TYPE */
2350
+ ice_set_phy_type_from_speed(ks, &phy_type_low, &phy_type_high,
2351
+ adv_link_speed);
2352
+
2353
+ if (!autoneg_changed && adv_link_speed == curr_link_speed) {
2354
+ netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
2355
+ goto done;
2356
+ }
2357
+
2358
+ /* save the requested speeds */
2359
+ pi->phy.link_info.req_speeds = adv_link_speed;
2360
+
2361
+ /* set link and auto negotiation so changes take effect */
2362
+ config.caps |= ICE_AQ_PHY_ENA_LINK;
2363
+
2364
+ /* check if there is a PHY type for the requested advertised speed */
2365
+ if (!(phy_type_low || phy_type_high)) {
2366
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
2367
+ err = -EAGAIN;
2368
+ goto done;
2369
+ }
2370
+
2371
+ /* intersect requested advertised speed PHY types with media PHY types
2372
+ * for set PHY configuration
2373
+ */
2374
+ config.phy_type_high = cpu_to_le64(phy_type_high) &
2375
+ phy_caps->phy_type_high;
2376
+ config.phy_type_low = cpu_to_le64(phy_type_low) &
2377
+ phy_caps->phy_type_low;
2378
+
2379
+ if (!(config.phy_type_high || config.phy_type_low)) {
2380
+ /* If there is no intersection and lenient mode is enabled, then
2381
+ * intersect the requested advertised speed with NVM media type
2382
+ * PHY types.
2383
+ */
2384
+ if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
2385
+ config.phy_type_high = cpu_to_le64(phy_type_high) &
2386
+ pf->nvm_phy_type_hi;
2387
+ config.phy_type_low = cpu_to_le64(phy_type_low) &
2388
+ pf->nvm_phy_type_lo;
2389
+ } else {
2390
+ netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
2391
+ err = -EAGAIN;
2392
+ goto done;
2393
+ }
2394
+ }
2395
+
2396
+ /* If link is up put link down */
2397
+ if (pi->phy.link_info.link_info & ICE_AQ_LINK_UP) {
2398
+ /* Tell the OS link is going down, the link will go
2399
+ * back up when fw says it is ready asynchronously
2400
+ */
2401
+ ice_print_link_msg(np->vsi, false);
2402
+ netif_carrier_off(netdev);
2403
+ netif_tx_stop_all_queues(netdev);
2404
+ }
2405
+
2406
+ /* make the aq call */
2407
+ status = ice_aq_set_phy_cfg(&pf->hw, pi, &config, NULL);
2408
+ if (status) {
2409
+ netdev_info(netdev, "Set phy config failed,\n");
2410
+ err = -EAGAIN;
2411
+ goto done;
2412
+ }
2413
+
2414
+ /* Save speed request */
2415
+ pi->phy.curr_user_speed_req = adv_link_speed;
2416
+done:
2417
+ kfree(phy_caps);
2418
+ clear_bit(__ICE_CFG_BUSY, pf->state);
2419
+
2420
+ return err;
2421
+}
2422
+
2423
+/**
2424
+ * ice_parse_hdrs - parses headers from RSS hash input
2425
+ * @nfc: ethtool rxnfc command
2426
+ *
2427
+ * This function parses the rxnfc command and returns intended
2428
+ * header types for RSS configuration
2429
+ */
2430
+static u32 ice_parse_hdrs(struct ethtool_rxnfc *nfc)
2431
+{
2432
+ u32 hdrs = ICE_FLOW_SEG_HDR_NONE;
2433
+
2434
+ switch (nfc->flow_type) {
2435
+ case TCP_V4_FLOW:
2436
+ hdrs |= ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4;
4382437 break;
2438
+ case UDP_V4_FLOW:
2439
+ hdrs |= ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4;
2440
+ break;
2441
+ case SCTP_V4_FLOW:
2442
+ hdrs |= ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4;
2443
+ break;
2444
+ case TCP_V6_FLOW:
2445
+ hdrs |= ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6;
2446
+ break;
2447
+ case UDP_V6_FLOW:
2448
+ hdrs |= ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6;
2449
+ break;
2450
+ case SCTP_V6_FLOW:
2451
+ hdrs |= ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6;
2452
+ break;
2453
+ default:
2454
+ break;
2455
+ }
2456
+ return hdrs;
2457
+}
2458
+
2459
+#define ICE_FLOW_HASH_FLD_IPV4_SA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)
2460
+#define ICE_FLOW_HASH_FLD_IPV6_SA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)
2461
+#define ICE_FLOW_HASH_FLD_IPV4_DA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)
2462
+#define ICE_FLOW_HASH_FLD_IPV6_DA BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)
2463
+#define ICE_FLOW_HASH_FLD_TCP_SRC_PORT BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)
2464
+#define ICE_FLOW_HASH_FLD_TCP_DST_PORT BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)
2465
+#define ICE_FLOW_HASH_FLD_UDP_SRC_PORT BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)
2466
+#define ICE_FLOW_HASH_FLD_UDP_DST_PORT BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)
2467
+#define ICE_FLOW_HASH_FLD_SCTP_SRC_PORT \
2468
+ BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)
2469
+#define ICE_FLOW_HASH_FLD_SCTP_DST_PORT \
2470
+ BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)
2471
+
2472
+/**
2473
+ * ice_parse_hash_flds - parses hash fields from RSS hash input
2474
+ * @nfc: ethtool rxnfc command
2475
+ *
2476
+ * This function parses the rxnfc command and returns intended
2477
+ * hash fields for RSS configuration
2478
+ */
2479
+static u64 ice_parse_hash_flds(struct ethtool_rxnfc *nfc)
2480
+{
2481
+ u64 hfld = ICE_HASH_INVALID;
2482
+
2483
+ if (nfc->data & RXH_IP_SRC || nfc->data & RXH_IP_DST) {
2484
+ switch (nfc->flow_type) {
2485
+ case TCP_V4_FLOW:
2486
+ case UDP_V4_FLOW:
2487
+ case SCTP_V4_FLOW:
2488
+ if (nfc->data & RXH_IP_SRC)
2489
+ hfld |= ICE_FLOW_HASH_FLD_IPV4_SA;
2490
+ if (nfc->data & RXH_IP_DST)
2491
+ hfld |= ICE_FLOW_HASH_FLD_IPV4_DA;
2492
+ break;
2493
+ case TCP_V6_FLOW:
2494
+ case UDP_V6_FLOW:
2495
+ case SCTP_V6_FLOW:
2496
+ if (nfc->data & RXH_IP_SRC)
2497
+ hfld |= ICE_FLOW_HASH_FLD_IPV6_SA;
2498
+ if (nfc->data & RXH_IP_DST)
2499
+ hfld |= ICE_FLOW_HASH_FLD_IPV6_DA;
2500
+ break;
2501
+ default:
2502
+ break;
2503
+ }
2504
+ }
2505
+
2506
+ if (nfc->data & RXH_L4_B_0_1 || nfc->data & RXH_L4_B_2_3) {
2507
+ switch (nfc->flow_type) {
2508
+ case TCP_V4_FLOW:
2509
+ case TCP_V6_FLOW:
2510
+ if (nfc->data & RXH_L4_B_0_1)
2511
+ hfld |= ICE_FLOW_HASH_FLD_TCP_SRC_PORT;
2512
+ if (nfc->data & RXH_L4_B_2_3)
2513
+ hfld |= ICE_FLOW_HASH_FLD_TCP_DST_PORT;
2514
+ break;
2515
+ case UDP_V4_FLOW:
2516
+ case UDP_V6_FLOW:
2517
+ if (nfc->data & RXH_L4_B_0_1)
2518
+ hfld |= ICE_FLOW_HASH_FLD_UDP_SRC_PORT;
2519
+ if (nfc->data & RXH_L4_B_2_3)
2520
+ hfld |= ICE_FLOW_HASH_FLD_UDP_DST_PORT;
2521
+ break;
2522
+ case SCTP_V4_FLOW:
2523
+ case SCTP_V6_FLOW:
2524
+ if (nfc->data & RXH_L4_B_0_1)
2525
+ hfld |= ICE_FLOW_HASH_FLD_SCTP_SRC_PORT;
2526
+ if (nfc->data & RXH_L4_B_2_3)
2527
+ hfld |= ICE_FLOW_HASH_FLD_SCTP_DST_PORT;
2528
+ break;
2529
+ default:
2530
+ break;
2531
+ }
2532
+ }
2533
+
2534
+ return hfld;
2535
+}
2536
+
2537
+/**
2538
+ * ice_set_rss_hash_opt - Enable/Disable flow types for RSS hash
2539
+ * @vsi: the VSI being configured
2540
+ * @nfc: ethtool rxnfc command
2541
+ *
2542
+ * Returns Success if the flow input set is supported.
2543
+ */
2544
+static int
2545
+ice_set_rss_hash_opt(struct ice_vsi *vsi, struct ethtool_rxnfc *nfc)
2546
+{
2547
+ struct ice_pf *pf = vsi->back;
2548
+ enum ice_status status;
2549
+ struct device *dev;
2550
+ u64 hashed_flds;
2551
+ u32 hdrs;
2552
+
2553
+ dev = ice_pf_to_dev(pf);
2554
+ if (ice_is_safe_mode(pf)) {
2555
+ dev_dbg(dev, "Advanced RSS disabled. Package download failed, vsi num = %d\n",
2556
+ vsi->vsi_num);
2557
+ return -EINVAL;
2558
+ }
2559
+
2560
+ hashed_flds = ice_parse_hash_flds(nfc);
2561
+ if (hashed_flds == ICE_HASH_INVALID) {
2562
+ dev_dbg(dev, "Invalid hash fields, vsi num = %d\n",
2563
+ vsi->vsi_num);
2564
+ return -EINVAL;
2565
+ }
2566
+
2567
+ hdrs = ice_parse_hdrs(nfc);
2568
+ if (hdrs == ICE_FLOW_SEG_HDR_NONE) {
2569
+ dev_dbg(dev, "Header type is not valid, vsi num = %d\n",
2570
+ vsi->vsi_num);
2571
+ return -EINVAL;
2572
+ }
2573
+
2574
+ status = ice_add_rss_cfg(&pf->hw, vsi->idx, hashed_flds, hdrs);
2575
+ if (status) {
2576
+ dev_dbg(dev, "ice_add_rss_cfg failed, vsi num = %d, error = %s\n",
2577
+ vsi->vsi_num, ice_stat_str(status));
2578
+ return -EINVAL;
4392579 }
4402580
4412581 return 0;
4422582 }
4432583
4442584 /**
445
- * ice_get_rxnfc - command to get RX flow classification rules
2585
+ * ice_get_rss_hash_opt - Retrieve hash fields for a given flow-type
2586
+ * @vsi: the VSI being configured
2587
+ * @nfc: ethtool rxnfc command
2588
+ */
2589
+static void
2590
+ice_get_rss_hash_opt(struct ice_vsi *vsi, struct ethtool_rxnfc *nfc)
2591
+{
2592
+ struct ice_pf *pf = vsi->back;
2593
+ struct device *dev;
2594
+ u64 hash_flds;
2595
+ u32 hdrs;
2596
+
2597
+ dev = ice_pf_to_dev(pf);
2598
+
2599
+ nfc->data = 0;
2600
+ if (ice_is_safe_mode(pf)) {
2601
+ dev_dbg(dev, "Advanced RSS disabled. Package download failed, vsi num = %d\n",
2602
+ vsi->vsi_num);
2603
+ return;
2604
+ }
2605
+
2606
+ hdrs = ice_parse_hdrs(nfc);
2607
+ if (hdrs == ICE_FLOW_SEG_HDR_NONE) {
2608
+ dev_dbg(dev, "Header type is not valid, vsi num = %d\n",
2609
+ vsi->vsi_num);
2610
+ return;
2611
+ }
2612
+
2613
+ hash_flds = ice_get_rss_cfg(&pf->hw, vsi->idx, hdrs);
2614
+ if (hash_flds == ICE_HASH_INVALID) {
2615
+ dev_dbg(dev, "No hash fields found for the given header type, vsi num = %d\n",
2616
+ vsi->vsi_num);
2617
+ return;
2618
+ }
2619
+
2620
+ if (hash_flds & ICE_FLOW_HASH_FLD_IPV4_SA ||
2621
+ hash_flds & ICE_FLOW_HASH_FLD_IPV6_SA)
2622
+ nfc->data |= (u64)RXH_IP_SRC;
2623
+
2624
+ if (hash_flds & ICE_FLOW_HASH_FLD_IPV4_DA ||
2625
+ hash_flds & ICE_FLOW_HASH_FLD_IPV6_DA)
2626
+ nfc->data |= (u64)RXH_IP_DST;
2627
+
2628
+ if (hash_flds & ICE_FLOW_HASH_FLD_TCP_SRC_PORT ||
2629
+ hash_flds & ICE_FLOW_HASH_FLD_UDP_SRC_PORT ||
2630
+ hash_flds & ICE_FLOW_HASH_FLD_SCTP_SRC_PORT)
2631
+ nfc->data |= (u64)RXH_L4_B_0_1;
2632
+
2633
+ if (hash_flds & ICE_FLOW_HASH_FLD_TCP_DST_PORT ||
2634
+ hash_flds & ICE_FLOW_HASH_FLD_UDP_DST_PORT ||
2635
+ hash_flds & ICE_FLOW_HASH_FLD_SCTP_DST_PORT)
2636
+ nfc->data |= (u64)RXH_L4_B_2_3;
2637
+}
2638
+
2639
+/**
2640
+ * ice_set_rxnfc - command to set Rx flow rules.
2641
+ * @netdev: network interface device structure
2642
+ * @cmd: ethtool rxnfc command
2643
+ *
2644
+ * Returns 0 for success and negative values for errors
2645
+ */
2646
+static int ice_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
2647
+{
2648
+ struct ice_netdev_priv *np = netdev_priv(netdev);
2649
+ struct ice_vsi *vsi = np->vsi;
2650
+
2651
+ switch (cmd->cmd) {
2652
+ case ETHTOOL_SRXCLSRLINS:
2653
+ return ice_add_fdir_ethtool(vsi, cmd);
2654
+ case ETHTOOL_SRXCLSRLDEL:
2655
+ return ice_del_fdir_ethtool(vsi, cmd);
2656
+ case ETHTOOL_SRXFH:
2657
+ return ice_set_rss_hash_opt(vsi, cmd);
2658
+ default:
2659
+ break;
2660
+ }
2661
+ return -EOPNOTSUPP;
2662
+}
2663
+
2664
+/**
2665
+ * ice_get_rxnfc - command to get Rx flow classification rules
4462666 * @netdev: network interface device structure
4472667 * @cmd: ethtool rxnfc command
4482668 * @rule_locs: buffer to rturn Rx flow classification rules
4492669 *
4502670 * Returns Success if the command is supported.
4512671 */
452
-static int ice_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
453
- u32 __always_unused *rule_locs)
2672
+static int
2673
+ice_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
2674
+ u32 __always_unused *rule_locs)
4542675 {
4552676 struct ice_netdev_priv *np = netdev_priv(netdev);
4562677 struct ice_vsi *vsi = np->vsi;
4572678 int ret = -EOPNOTSUPP;
2679
+ struct ice_hw *hw;
2680
+
2681
+ hw = &vsi->back->hw;
4582682
4592683 switch (cmd->cmd) {
4602684 case ETHTOOL_GRXRINGS:
4612685 cmd->data = vsi->rss_size;
2686
+ ret = 0;
2687
+ break;
2688
+ case ETHTOOL_GRXCLSRLCNT:
2689
+ cmd->rule_cnt = hw->fdir_active_fltr;
2690
+ /* report total rule count */
2691
+ cmd->data = ice_get_fdir_cnt_all(hw);
2692
+ ret = 0;
2693
+ break;
2694
+ case ETHTOOL_GRXCLSRULE:
2695
+ ret = ice_get_ethtool_fdir_entry(hw, cmd);
2696
+ break;
2697
+ case ETHTOOL_GRXCLSRLALL:
2698
+ ret = ice_get_fdir_fltr_ids(hw, cmd, (u32 *)rule_locs);
2699
+ break;
2700
+ case ETHTOOL_GRXFH:
2701
+ ice_get_rss_hash_opt(vsi, cmd);
4622702 ret = 0;
4632703 break;
4642704 default:
....@@ -491,10 +2731,11 @@
4912731 {
4922732 struct ice_ring *tx_rings = NULL, *rx_rings = NULL;
4932733 struct ice_netdev_priv *np = netdev_priv(netdev);
2734
+ struct ice_ring *xdp_rings = NULL;
4942735 struct ice_vsi *vsi = np->vsi;
4952736 struct ice_pf *pf = vsi->back;
4962737 int i, timeout = 50, err = 0;
497
- u32 new_rx_cnt, new_tx_cnt;
2738
+ u16 new_rx_cnt, new_tx_cnt;
4982739
4992740 if (ring->tx_pending > ICE_MAX_NUM_DESC ||
5002741 ring->tx_pending < ICE_MIN_NUM_DESC ||
....@@ -509,13 +2750,11 @@
5092750
5102751 new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE);
5112752 if (new_tx_cnt != ring->tx_pending)
512
- netdev_info(netdev,
513
- "Requested Tx descriptor count rounded up to %d\n",
2753
+ netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n",
5142754 new_tx_cnt);
5152755 new_rx_cnt = ALIGN(ring->rx_pending, ICE_REQ_DESC_MULTIPLE);
5162756 if (new_rx_cnt != ring->rx_pending)
517
- netdev_info(netdev,
518
- "Requested Rx descriptor count rounded up to %d\n",
2757
+ netdev_info(netdev, "Requested Rx descriptor count rounded up to %d\n",
5192758 new_rx_cnt);
5202759
5212760 /* if nothing to do return success */
....@@ -524,6 +2763,13 @@
5242763 netdev_dbg(netdev, "Nothing to change, descriptor count is same as requested\n");
5252764 return 0;
5262765 }
2766
+
2767
+ /* If there is a AF_XDP UMEM attached to any of Rx rings,
2768
+ * disallow changing the number of descriptors -- regardless
2769
+ * if the netdev is running or not.
2770
+ */
2771
+ if (ice_xsk_any_rx_ring_ena(vsi))
2772
+ return -EBUSY;
5272773
5282774 while (test_and_set_bit(__ICE_CFG_BUSY, pf->state)) {
5292775 timeout--;
....@@ -538,6 +2784,11 @@
5382784 vsi->tx_rings[i]->count = new_tx_cnt;
5392785 for (i = 0; i < vsi->alloc_rxq; i++)
5402786 vsi->rx_rings[i]->count = new_rx_cnt;
2787
+ if (ice_is_xdp_ena_vsi(vsi))
2788
+ for (i = 0; i < vsi->num_xdp_txq; i++)
2789
+ vsi->xdp_rings[i]->count = new_tx_cnt;
2790
+ vsi->num_tx_desc = (u16)new_tx_cnt;
2791
+ vsi->num_rx_desc = (u16)new_rx_cnt;
5412792 netdev_dbg(netdev, "Link is down, descriptor count change happens when link is brought up\n");
5422793 goto done;
5432794 }
....@@ -549,14 +2800,13 @@
5492800 netdev_info(netdev, "Changing Tx descriptor count from %d to %d\n",
5502801 vsi->tx_rings[0]->count, new_tx_cnt);
5512802
552
- tx_rings = devm_kcalloc(&pf->pdev->dev, vsi->alloc_txq,
553
- sizeof(struct ice_ring), GFP_KERNEL);
2803
+ tx_rings = kcalloc(vsi->num_txq, sizeof(*tx_rings), GFP_KERNEL);
5542804 if (!tx_rings) {
5552805 err = -ENOMEM;
5562806 goto done;
5572807 }
5582808
559
- for (i = 0; i < vsi->alloc_txq; i++) {
2809
+ ice_for_each_txq(vsi, i) {
5602810 /* clone ring and setup updated count */
5612811 tx_rings[i] = *vsi->tx_rings[i];
5622812 tx_rings[i].count = new_tx_cnt;
....@@ -564,13 +2814,40 @@
5642814 tx_rings[i].tx_buf = NULL;
5652815 err = ice_setup_tx_ring(&tx_rings[i]);
5662816 if (err) {
567
- while (i) {
568
- i--;
2817
+ while (i--)
5692818 ice_clean_tx_ring(&tx_rings[i]);
570
- }
571
- devm_kfree(&pf->pdev->dev, tx_rings);
2819
+ kfree(tx_rings);
5722820 goto done;
5732821 }
2822
+ }
2823
+
2824
+ if (!ice_is_xdp_ena_vsi(vsi))
2825
+ goto process_rx;
2826
+
2827
+ /* alloc updated XDP resources */
2828
+ netdev_info(netdev, "Changing XDP descriptor count from %d to %d\n",
2829
+ vsi->xdp_rings[0]->count, new_tx_cnt);
2830
+
2831
+ xdp_rings = kcalloc(vsi->num_xdp_txq, sizeof(*xdp_rings), GFP_KERNEL);
2832
+ if (!xdp_rings) {
2833
+ err = -ENOMEM;
2834
+ goto free_tx;
2835
+ }
2836
+
2837
+ for (i = 0; i < vsi->num_xdp_txq; i++) {
2838
+ /* clone ring and setup updated count */
2839
+ xdp_rings[i] = *vsi->xdp_rings[i];
2840
+ xdp_rings[i].count = new_tx_cnt;
2841
+ xdp_rings[i].desc = NULL;
2842
+ xdp_rings[i].tx_buf = NULL;
2843
+ err = ice_setup_tx_ring(&xdp_rings[i]);
2844
+ if (err) {
2845
+ while (i--)
2846
+ ice_clean_tx_ring(&xdp_rings[i]);
2847
+ kfree(xdp_rings);
2848
+ goto free_tx;
2849
+ }
2850
+ ice_set_ring_xdp(&xdp_rings[i]);
5742851 }
5752852
5762853 process_rx:
....@@ -581,14 +2858,13 @@
5812858 netdev_info(netdev, "Changing Rx descriptor count from %d to %d\n",
5822859 vsi->rx_rings[0]->count, new_rx_cnt);
5832860
584
- rx_rings = devm_kcalloc(&pf->pdev->dev, vsi->alloc_rxq,
585
- sizeof(struct ice_ring), GFP_KERNEL);
2861
+ rx_rings = kcalloc(vsi->num_rxq, sizeof(*rx_rings), GFP_KERNEL);
5862862 if (!rx_rings) {
5872863 err = -ENOMEM;
5882864 goto done;
5892865 }
5902866
591
- for (i = 0; i < vsi->alloc_rxq; i++) {
2867
+ ice_for_each_rxq(vsi, i) {
5922868 /* clone ring and setup updated count */
5932869 rx_rings[i] = *vsi->rx_rings[i];
5942870 rx_rings[i].count = new_rx_cnt;
....@@ -612,7 +2888,7 @@
6122888 i--;
6132889 ice_free_rx_ring(&rx_rings[i]);
6142890 }
615
- devm_kfree(&pf->pdev->dev, rx_rings);
2891
+ kfree(rx_rings);
6162892 err = -ENOMEM;
6172893 goto free_tx;
6182894 }
....@@ -626,15 +2902,15 @@
6262902 ice_down(vsi);
6272903
6282904 if (tx_rings) {
629
- for (i = 0; i < vsi->alloc_txq; i++) {
2905
+ ice_for_each_txq(vsi, i) {
6302906 ice_free_tx_ring(vsi->tx_rings[i]);
6312907 *vsi->tx_rings[i] = tx_rings[i];
6322908 }
633
- devm_kfree(&pf->pdev->dev, tx_rings);
2909
+ kfree(tx_rings);
6342910 }
6352911
6362912 if (rx_rings) {
637
- for (i = 0; i < vsi->alloc_rxq; i++) {
2913
+ ice_for_each_rxq(vsi, i) {
6382914 ice_free_rx_ring(vsi->rx_rings[i]);
6392915 /* copy the real tail offset */
6402916 rx_rings[i].tail = vsi->rx_rings[i]->tail;
....@@ -648,9 +2924,19 @@
6482924 rx_rings[i].next_to_alloc = 0;
6492925 *vsi->rx_rings[i] = rx_rings[i];
6502926 }
651
- devm_kfree(&pf->pdev->dev, rx_rings);
2927
+ kfree(rx_rings);
6522928 }
6532929
2930
+ if (xdp_rings) {
2931
+ for (i = 0; i < vsi->num_xdp_txq; i++) {
2932
+ ice_free_tx_ring(vsi->xdp_rings[i]);
2933
+ *vsi->xdp_rings[i] = xdp_rings[i];
2934
+ }
2935
+ kfree(xdp_rings);
2936
+ }
2937
+
2938
+ vsi->num_tx_desc = new_tx_cnt;
2939
+ vsi->num_rx_desc = new_rx_cnt;
6542940 ice_up(vsi);
6552941 }
6562942 goto done;
....@@ -658,9 +2944,9 @@
6582944 free_tx:
6592945 /* error cleanup if the Rx allocations failed after getting Tx */
6602946 if (tx_rings) {
661
- for (i = 0; i < vsi->alloc_txq; i++)
2947
+ ice_for_each_txq(vsi, i)
6622948 ice_free_tx_ring(&tx_rings[i]);
663
- devm_kfree(&pf->pdev->dev, tx_rings);
2949
+ kfree(tx_rings);
6642950 }
6652951
6662952 done:
....@@ -668,67 +2954,70 @@
6682954 return err;
6692955 }
6702956
671
-static int ice_nway_reset(struct net_device *netdev)
672
-{
673
- /* restart autonegotiation */
674
- struct ice_netdev_priv *np = netdev_priv(netdev);
675
- struct ice_link_status *hw_link_info;
676
- struct ice_vsi *vsi = np->vsi;
677
- struct ice_port_info *pi;
678
- enum ice_status status;
679
- bool link_up;
680
-
681
- pi = vsi->port_info;
682
- hw_link_info = &pi->phy.link_info;
683
- link_up = hw_link_info->link_info & ICE_AQ_LINK_UP;
684
-
685
- status = ice_aq_set_link_restart_an(pi, link_up, NULL);
686
- if (status) {
687
- netdev_info(netdev, "link restart failed, err %d aq_err %d\n",
688
- status, pi->hw->adminq.sq_last_status);
689
- return -EIO;
690
- }
691
-
692
- return 0;
693
-}
694
-
6952957 /**
6962958 * ice_get_pauseparam - Get Flow Control status
6972959 * @netdev: network interface device structure
6982960 * @pause: ethernet pause (flow control) parameters
2961
+ *
2962
+ * Get requested flow control status from PHY capability.
2963
+ * If autoneg is true, then ethtool will send the ETHTOOL_GSET ioctl which
2964
+ * is handled by ice_get_link_ksettings. ice_get_link_ksettings will report
2965
+ * the negotiated Rx/Tx pause via lp_advertising.
6992966 */
7002967 static void
7012968 ice_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
7022969 {
7032970 struct ice_netdev_priv *np = netdev_priv(netdev);
704
- struct ice_port_info *pi;
2971
+ struct ice_port_info *pi = np->vsi->port_info;
2972
+ struct ice_aqc_get_phy_caps_data *pcaps;
2973
+ struct ice_dcbx_cfg *dcbx_cfg;
2974
+ enum ice_status status;
7052975
706
- pi = np->vsi->port_info;
707
- pause->autoneg =
708
- ((pi->phy.link_info.an_info & ICE_AQ_AN_COMPLETED) ?
709
- AUTONEG_ENABLE : AUTONEG_DISABLE);
2976
+ /* Initialize pause params */
2977
+ pause->rx_pause = 0;
2978
+ pause->tx_pause = 0;
7102979
711
- if (pi->fc.current_mode == ICE_FC_RX_PAUSE) {
712
- pause->rx_pause = 1;
713
- } else if (pi->fc.current_mode == ICE_FC_TX_PAUSE) {
2980
+ dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
2981
+
2982
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
2983
+ if (!pcaps)
2984
+ return;
2985
+
2986
+ /* Get current PHY config */
2987
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG, pcaps,
2988
+ NULL);
2989
+ if (status)
2990
+ goto out;
2991
+
2992
+ pause->autoneg = ice_is_phy_caps_an_enabled(pcaps) ? AUTONEG_ENABLE :
2993
+ AUTONEG_DISABLE;
2994
+
2995
+ if (dcbx_cfg->pfc.pfcena)
2996
+ /* PFC enabled so report LFC as off */
2997
+ goto out;
2998
+
2999
+ if (pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE)
7143000 pause->tx_pause = 1;
715
- } else if (pi->fc.current_mode == ICE_FC_FULL) {
3001
+ if (pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
7163002 pause->rx_pause = 1;
717
- pause->tx_pause = 1;
718
- }
3003
+
3004
+out:
3005
+ kfree(pcaps);
7193006 }
7203007
7213008 /**
7223009 * ice_set_pauseparam - Set Flow Control parameter
7233010 * @netdev: network interface device structure
724
- * @pause: return tx/rx flow control status
3011
+ * @pause: return Tx/Rx flow control status
7253012 */
7263013 static int
7273014 ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
7283015 {
7293016 struct ice_netdev_priv *np = netdev_priv(netdev);
3017
+ struct ice_aqc_get_phy_caps_data *pcaps;
7303018 struct ice_link_status *hw_link_info;
7313019 struct ice_pf *pf = np->vsi->back;
3020
+ struct ice_dcbx_cfg *dcbx_cfg;
7323021 struct ice_vsi *vsi = np->vsi;
7333022 struct ice_hw *hw = &pf->hw;
7343023 struct ice_port_info *pi;
....@@ -736,9 +3025,11 @@
7363025 u8 aq_failures;
7373026 bool link_up;
7383027 int err = 0;
3028
+ u32 is_an;
7393029
7403030 pi = vsi->port_info;
7413031 hw_link_info = &pi->phy.link_info;
3032
+ dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
7423033 link_up = hw_link_info->link_info & ICE_AQ_LINK_UP;
7433034
7443035 /* Changing the port's flow control is not supported if this isn't the
....@@ -749,7 +3040,30 @@
7493040 return -EOPNOTSUPP;
7503041 }
7513042
752
- if (pause->autoneg != (hw_link_info->an_info & ICE_AQ_AN_COMPLETED)) {
3043
+ /* Get pause param reports configured and negotiated flow control pause
3044
+ * when ETHTOOL_GLINKSETTINGS is defined. Since ETHTOOL_GLINKSETTINGS is
3045
+ * defined get pause param pause->autoneg reports SW configured setting,
3046
+ * so compare pause->autoneg with SW configured to prevent the user from
3047
+ * using set pause param to chance autoneg.
3048
+ */
3049
+ pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
3050
+ if (!pcaps)
3051
+ return -ENOMEM;
3052
+
3053
+ /* Get current PHY config */
3054
+ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG, pcaps,
3055
+ NULL);
3056
+ if (status) {
3057
+ kfree(pcaps);
3058
+ return -EIO;
3059
+ }
3060
+
3061
+ is_an = ice_is_phy_caps_an_enabled(pcaps) ? AUTONEG_ENABLE :
3062
+ AUTONEG_DISABLE;
3063
+
3064
+ kfree(pcaps);
3065
+
3066
+ if (pause->autoneg != is_an) {
7533067 netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
7543068 return -EOPNOTSUPP;
7553069 }
....@@ -761,6 +3075,10 @@
7613075 netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n");
7623076 }
7633077
3078
+ if (dcbx_cfg->pfc.pfcena) {
3079
+ netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n");
3080
+ return -EOPNOTSUPP;
3081
+ }
7643082 if (pause->rx_pause && pause->tx_pause)
7653083 pi->fc.req_mode = ICE_FC_FULL;
7663084 else if (pause->rx_pause && !pause->tx_pause)
....@@ -776,29 +3094,20 @@
7763094 status = ice_set_fc(pi, &aq_failures, link_up);
7773095
7783096 if (aq_failures & ICE_SET_FC_AQ_FAIL_GET) {
779
- netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %d aq_err %d\n",
780
- status, hw->adminq.sq_last_status);
3097
+ netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %s aq_err %s\n",
3098
+ ice_stat_str(status),
3099
+ ice_aq_str(hw->adminq.sq_last_status));
7813100 err = -EAGAIN;
7823101 } else if (aq_failures & ICE_SET_FC_AQ_FAIL_SET) {
783
- netdev_info(netdev, "Set fc failed on the set_phy_config call with err %d aq_err %d\n",
784
- status, hw->adminq.sq_last_status);
3102
+ netdev_info(netdev, "Set fc failed on the set_phy_config call with err %s aq_err %s\n",
3103
+ ice_stat_str(status),
3104
+ ice_aq_str(hw->adminq.sq_last_status));
7853105 err = -EAGAIN;
7863106 } else if (aq_failures & ICE_SET_FC_AQ_FAIL_UPDATE) {
787
- netdev_info(netdev, "Set fc failed on the get_link_info call with err %d aq_err %d\n",
788
- status, hw->adminq.sq_last_status);
3107
+ netdev_info(netdev, "Set fc failed on the get_link_info call with err %s aq_err %s\n",
3108
+ ice_stat_str(status),
3109
+ ice_aq_str(hw->adminq.sq_last_status));
7893110 err = -EAGAIN;
790
- }
791
-
792
- if (!test_bit(__ICE_DOWN, pf->state)) {
793
- /* Give it a little more time to try to come back. If still
794
- * down, restart autoneg link or reinitialize the interface.
795
- */
796
- msleep(75);
797
- if (!test_bit(__ICE_DOWN, pf->state))
798
- return ice_nway_reset(netdev);
799
-
800
- ice_down(vsi);
801
- ice_up(vsi);
8023111 }
8033112
8043113 return err;
....@@ -816,7 +3125,7 @@
8163125 }
8173126
8183127 /**
819
- * ice_get_rxfh_indir_size - get the rx flow hash indirection table size
3128
+ * ice_get_rxfh_indir_size - get the Rx flow hash indirection table size
8203129 * @netdev: network interface device structure
8213130 *
8223131 * Returns the table size.
....@@ -829,7 +3138,7 @@
8293138 }
8303139
8313140 /**
832
- * ice_get_rxfh - get the rx flow hash indirection table
3141
+ * ice_get_rxfh - get the Rx flow hash indirection table
8333142 * @netdev: network interface device structure
8343143 * @indir: indirection table
8353144 * @key: hash key
....@@ -858,7 +3167,7 @@
8583167 return -EIO;
8593168 }
8603169
861
- lut = devm_kzalloc(&pf->pdev->dev, vsi->rss_table_size, GFP_KERNEL);
3170
+ lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
8623171 if (!lut)
8633172 return -ENOMEM;
8643173
....@@ -871,28 +3180,31 @@
8713180 indir[i] = (u32)(lut[i]);
8723181
8733182 out:
874
- devm_kfree(&pf->pdev->dev, lut);
3183
+ kfree(lut);
8753184 return ret;
8763185 }
8773186
8783187 /**
879
- * ice_set_rxfh - set the rx flow hash indirection table
3188
+ * ice_set_rxfh - set the Rx flow hash indirection table
8803189 * @netdev: network interface device structure
8813190 * @indir: indirection table
8823191 * @key: hash key
8833192 * @hfunc: hash function
8843193 *
885
- * Returns -EINVAL if the table specifies an invalid queue id, otherwise
3194
+ * Returns -EINVAL if the table specifies an invalid queue ID, otherwise
8863195 * returns 0 after programming the table.
8873196 */
888
-static int ice_set_rxfh(struct net_device *netdev, const u32 *indir,
889
- const u8 *key, const u8 hfunc)
3197
+static int
3198
+ice_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key,
3199
+ const u8 hfunc)
8903200 {
8913201 struct ice_netdev_priv *np = netdev_priv(netdev);
8923202 struct ice_vsi *vsi = np->vsi;
8933203 struct ice_pf *pf = vsi->back;
3204
+ struct device *dev;
8943205 u8 *seed = NULL;
8953206
3207
+ dev = ice_pf_to_dev(pf);
8963208 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
8973209 return -EOPNOTSUPP;
8983210
....@@ -905,8 +3217,7 @@
9053217 if (key) {
9063218 if (!vsi->rss_hkey_user) {
9073219 vsi->rss_hkey_user =
908
- devm_kzalloc(&pf->pdev->dev,
909
- ICE_VSIQF_HKEY_ARRAY_SIZE,
3220
+ devm_kzalloc(dev, ICE_VSIQF_HKEY_ARRAY_SIZE,
9103221 GFP_KERNEL);
9113222 if (!vsi->rss_hkey_user)
9123223 return -ENOMEM;
....@@ -916,8 +3227,7 @@
9163227 }
9173228
9183229 if (!vsi->rss_lut_user) {
919
- vsi->rss_lut_user = devm_kzalloc(&pf->pdev->dev,
920
- vsi->rss_table_size,
3230
+ vsi->rss_lut_user = devm_kzalloc(dev, vsi->rss_table_size,
9213231 GFP_KERNEL);
9223232 if (!vsi->rss_lut_user)
9233233 return -ENOMEM;
....@@ -940,18 +3250,754 @@
9403250 return 0;
9413251 }
9423252
3253
+/**
3254
+ * ice_get_max_txq - return the maximum number of Tx queues for in a PF
3255
+ * @pf: PF structure
3256
+ */
3257
+static int ice_get_max_txq(struct ice_pf *pf)
3258
+{
3259
+ return min3(pf->num_lan_msix, (u16)num_online_cpus(),
3260
+ (u16)pf->hw.func_caps.common_cap.num_txq);
3261
+}
3262
+
3263
+/**
3264
+ * ice_get_max_rxq - return the maximum number of Rx queues for in a PF
3265
+ * @pf: PF structure
3266
+ */
3267
+static int ice_get_max_rxq(struct ice_pf *pf)
3268
+{
3269
+ return min3(pf->num_lan_msix, (u16)num_online_cpus(),
3270
+ (u16)pf->hw.func_caps.common_cap.num_rxq);
3271
+}
3272
+
3273
+/**
3274
+ * ice_get_combined_cnt - return the current number of combined channels
3275
+ * @vsi: PF VSI pointer
3276
+ *
3277
+ * Go through all queue vectors and count ones that have both Rx and Tx ring
3278
+ * attached
3279
+ */
3280
+static u32 ice_get_combined_cnt(struct ice_vsi *vsi)
3281
+{
3282
+ u32 combined = 0;
3283
+ int q_idx;
3284
+
3285
+ ice_for_each_q_vector(vsi, q_idx) {
3286
+ struct ice_q_vector *q_vector = vsi->q_vectors[q_idx];
3287
+
3288
+ if (q_vector->rx.ring && q_vector->tx.ring)
3289
+ combined++;
3290
+ }
3291
+
3292
+ return combined;
3293
+}
3294
+
3295
+/**
3296
+ * ice_get_channels - get the current and max supported channels
3297
+ * @dev: network interface device structure
3298
+ * @ch: ethtool channel data structure
3299
+ */
3300
+static void
3301
+ice_get_channels(struct net_device *dev, struct ethtool_channels *ch)
3302
+{
3303
+ struct ice_netdev_priv *np = netdev_priv(dev);
3304
+ struct ice_vsi *vsi = np->vsi;
3305
+ struct ice_pf *pf = vsi->back;
3306
+
3307
+ /* report maximum channels */
3308
+ ch->max_rx = ice_get_max_rxq(pf);
3309
+ ch->max_tx = ice_get_max_txq(pf);
3310
+ ch->max_combined = min_t(int, ch->max_rx, ch->max_tx);
3311
+
3312
+ /* report current channels */
3313
+ ch->combined_count = ice_get_combined_cnt(vsi);
3314
+ ch->rx_count = vsi->num_rxq - ch->combined_count;
3315
+ ch->tx_count = vsi->num_txq - ch->combined_count;
3316
+
3317
+ /* report other queues */
3318
+ ch->other_count = test_bit(ICE_FLAG_FD_ENA, pf->flags) ? 1 : 0;
3319
+ ch->max_other = ch->other_count;
3320
+}
3321
+
3322
+/**
3323
+ * ice_get_valid_rss_size - return valid number of RSS queues
3324
+ * @hw: pointer to the HW structure
3325
+ * @new_size: requested RSS queues
3326
+ */
3327
+static int ice_get_valid_rss_size(struct ice_hw *hw, int new_size)
3328
+{
3329
+ struct ice_hw_common_caps *caps = &hw->func_caps.common_cap;
3330
+
3331
+ return min_t(int, new_size, BIT(caps->rss_table_entry_width));
3332
+}
3333
+
3334
+/**
3335
+ * ice_vsi_set_dflt_rss_lut - set default RSS LUT with requested RSS size
3336
+ * @vsi: VSI to reconfigure RSS LUT on
3337
+ * @req_rss_size: requested range of queue numbers for hashing
3338
+ *
3339
+ * Set the VSI's RSS parameters, configure the RSS LUT based on these.
3340
+ */
3341
+static int ice_vsi_set_dflt_rss_lut(struct ice_vsi *vsi, int req_rss_size)
3342
+{
3343
+ struct ice_pf *pf = vsi->back;
3344
+ enum ice_status status;
3345
+ struct device *dev;
3346
+ struct ice_hw *hw;
3347
+ int err = 0;
3348
+ u8 *lut;
3349
+
3350
+ dev = ice_pf_to_dev(pf);
3351
+ hw = &pf->hw;
3352
+
3353
+ if (!req_rss_size)
3354
+ return -EINVAL;
3355
+
3356
+ lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
3357
+ if (!lut)
3358
+ return -ENOMEM;
3359
+
3360
+ /* set RSS LUT parameters */
3361
+ if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags))
3362
+ vsi->rss_size = 1;
3363
+ else
3364
+ vsi->rss_size = ice_get_valid_rss_size(hw, req_rss_size);
3365
+
3366
+ /* create/set RSS LUT */
3367
+ ice_fill_rss_lut(lut, vsi->rss_table_size, vsi->rss_size);
3368
+ status = ice_aq_set_rss_lut(hw, vsi->idx, vsi->rss_lut_type, lut,
3369
+ vsi->rss_table_size);
3370
+ if (status) {
3371
+ dev_err(dev, "Cannot set RSS lut, err %s aq_err %s\n",
3372
+ ice_stat_str(status),
3373
+ ice_aq_str(hw->adminq.sq_last_status));
3374
+ err = -EIO;
3375
+ }
3376
+
3377
+ kfree(lut);
3378
+ return err;
3379
+}
3380
+
3381
+/**
3382
+ * ice_set_channels - set the number channels
3383
+ * @dev: network interface device structure
3384
+ * @ch: ethtool channel data structure
3385
+ */
3386
+static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
3387
+{
3388
+ struct ice_netdev_priv *np = netdev_priv(dev);
3389
+ struct ice_vsi *vsi = np->vsi;
3390
+ struct ice_pf *pf = vsi->back;
3391
+ int new_rx = 0, new_tx = 0;
3392
+ u32 curr_combined;
3393
+
3394
+ /* do not support changing channels in Safe Mode */
3395
+ if (ice_is_safe_mode(pf)) {
3396
+ netdev_err(dev, "Changing channel in Safe Mode is not supported\n");
3397
+ return -EOPNOTSUPP;
3398
+ }
3399
+ /* do not support changing other_count */
3400
+ if (ch->other_count != (test_bit(ICE_FLAG_FD_ENA, pf->flags) ? 1U : 0U))
3401
+ return -EINVAL;
3402
+
3403
+ if (test_bit(ICE_FLAG_FD_ENA, pf->flags) && pf->hw.fdir_active_fltr) {
3404
+ netdev_err(dev, "Cannot set channels when Flow Director filters are active\n");
3405
+ return -EOPNOTSUPP;
3406
+ }
3407
+
3408
+ curr_combined = ice_get_combined_cnt(vsi);
3409
+
3410
+ /* these checks are for cases where user didn't specify a particular
3411
+ * value on cmd line but we get non-zero value anyway via
3412
+ * get_channels(); look at ethtool.c in ethtool repository (the user
3413
+ * space part), particularly, do_schannels() routine
3414
+ */
3415
+ if (ch->rx_count == vsi->num_rxq - curr_combined)
3416
+ ch->rx_count = 0;
3417
+ if (ch->tx_count == vsi->num_txq - curr_combined)
3418
+ ch->tx_count = 0;
3419
+ if (ch->combined_count == curr_combined)
3420
+ ch->combined_count = 0;
3421
+
3422
+ if (!(ch->combined_count || (ch->rx_count && ch->tx_count))) {
3423
+ netdev_err(dev, "Please specify at least 1 Rx and 1 Tx channel\n");
3424
+ return -EINVAL;
3425
+ }
3426
+
3427
+ new_rx = ch->combined_count + ch->rx_count;
3428
+ new_tx = ch->combined_count + ch->tx_count;
3429
+
3430
+ if (new_rx > ice_get_max_rxq(pf)) {
3431
+ netdev_err(dev, "Maximum allowed Rx channels is %d\n",
3432
+ ice_get_max_rxq(pf));
3433
+ return -EINVAL;
3434
+ }
3435
+ if (new_tx > ice_get_max_txq(pf)) {
3436
+ netdev_err(dev, "Maximum allowed Tx channels is %d\n",
3437
+ ice_get_max_txq(pf));
3438
+ return -EINVAL;
3439
+ }
3440
+
3441
+ ice_vsi_recfg_qs(vsi, new_rx, new_tx);
3442
+
3443
+ if (!netif_is_rxfh_configured(dev))
3444
+ return ice_vsi_set_dflt_rss_lut(vsi, new_rx);
3445
+
3446
+ /* Update rss_size due to change in Rx queues */
3447
+ vsi->rss_size = ice_get_valid_rss_size(&pf->hw, new_rx);
3448
+
3449
+ return 0;
3450
+}
3451
+
3452
+/**
3453
+ * ice_get_wol - get current Wake on LAN configuration
3454
+ * @netdev: network interface device structure
3455
+ * @wol: Ethtool structure to retrieve WoL settings
3456
+ */
3457
+static void ice_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
3458
+{
3459
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3460
+ struct ice_pf *pf = np->vsi->back;
3461
+
3462
+ if (np->vsi->type != ICE_VSI_PF)
3463
+ netdev_warn(netdev, "Wake on LAN is not supported on this interface!\n");
3464
+
3465
+ /* Get WoL settings based on the HW capability */
3466
+ if (ice_is_wol_supported(&pf->hw)) {
3467
+ wol->supported = WAKE_MAGIC;
3468
+ wol->wolopts = pf->wol_ena ? WAKE_MAGIC : 0;
3469
+ } else {
3470
+ wol->supported = 0;
3471
+ wol->wolopts = 0;
3472
+ }
3473
+}
3474
+
3475
+/**
3476
+ * ice_set_wol - set Wake on LAN on supported device
3477
+ * @netdev: network interface device structure
3478
+ * @wol: Ethtool structure to set WoL
3479
+ */
3480
+static int ice_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
3481
+{
3482
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3483
+ struct ice_vsi *vsi = np->vsi;
3484
+ struct ice_pf *pf = vsi->back;
3485
+
3486
+ if (vsi->type != ICE_VSI_PF || !ice_is_wol_supported(&pf->hw))
3487
+ return -EOPNOTSUPP;
3488
+
3489
+ /* only magic packet is supported */
3490
+ if (wol->wolopts && wol->wolopts != WAKE_MAGIC)
3491
+ return -EOPNOTSUPP;
3492
+
3493
+ /* Set WoL only if there is a new value */
3494
+ if (pf->wol_ena != !!wol->wolopts) {
3495
+ pf->wol_ena = !!wol->wolopts;
3496
+ device_set_wakeup_enable(ice_pf_to_dev(pf), pf->wol_ena);
3497
+ netdev_dbg(netdev, "WoL magic packet %sabled\n",
3498
+ pf->wol_ena ? "en" : "dis");
3499
+ }
3500
+
3501
+ return 0;
3502
+}
3503
+
3504
+enum ice_container_type {
3505
+ ICE_RX_CONTAINER,
3506
+ ICE_TX_CONTAINER,
3507
+};
3508
+
3509
+/**
3510
+ * ice_get_rc_coalesce - get ITR values for specific ring container
3511
+ * @ec: ethtool structure to fill with driver's coalesce settings
3512
+ * @c_type: container type, Rx or Tx
3513
+ * @rc: ring container that the ITR values will come from
3514
+ *
3515
+ * Query the device for ice_ring_container specific ITR values. This is
3516
+ * done per ice_ring_container because each q_vector can have 1 or more rings
3517
+ * and all of said ring(s) will have the same ITR values.
3518
+ *
3519
+ * Returns 0 on success, negative otherwise.
3520
+ */
3521
+static int
3522
+ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type,
3523
+ struct ice_ring_container *rc)
3524
+{
3525
+ if (!rc->ring)
3526
+ return -EINVAL;
3527
+
3528
+ switch (c_type) {
3529
+ case ICE_RX_CONTAINER:
3530
+ ec->use_adaptive_rx_coalesce = ITR_IS_DYNAMIC(rc->itr_setting);
3531
+ ec->rx_coalesce_usecs = rc->itr_setting & ~ICE_ITR_DYNAMIC;
3532
+ ec->rx_coalesce_usecs_high = rc->ring->q_vector->intrl;
3533
+ break;
3534
+ case ICE_TX_CONTAINER:
3535
+ ec->use_adaptive_tx_coalesce = ITR_IS_DYNAMIC(rc->itr_setting);
3536
+ ec->tx_coalesce_usecs = rc->itr_setting & ~ICE_ITR_DYNAMIC;
3537
+ break;
3538
+ default:
3539
+ dev_dbg(ice_pf_to_dev(rc->ring->vsi->back), "Invalid c_type %d\n", c_type);
3540
+ return -EINVAL;
3541
+ }
3542
+
3543
+ return 0;
3544
+}
3545
+
3546
+/**
3547
+ * ice_get_q_coalesce - get a queue's ITR/INTRL (coalesce) settings
3548
+ * @vsi: VSI associated to the queue for getting ITR/INTRL (coalesce) settings
3549
+ * @ec: coalesce settings to program the device with
3550
+ * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index
3551
+ *
3552
+ * Return 0 on success, and negative under the following conditions:
3553
+ * 1. Getting Tx or Rx ITR/INTRL (coalesce) settings failed.
3554
+ * 2. The q_num passed in is not a valid number/index for Tx and Rx rings.
3555
+ */
3556
+static int
3557
+ice_get_q_coalesce(struct ice_vsi *vsi, struct ethtool_coalesce *ec, int q_num)
3558
+{
3559
+ if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
3560
+ if (ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
3561
+ &vsi->rx_rings[q_num]->q_vector->rx))
3562
+ return -EINVAL;
3563
+ if (ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
3564
+ &vsi->tx_rings[q_num]->q_vector->tx))
3565
+ return -EINVAL;
3566
+ } else if (q_num < vsi->num_rxq) {
3567
+ if (ice_get_rc_coalesce(ec, ICE_RX_CONTAINER,
3568
+ &vsi->rx_rings[q_num]->q_vector->rx))
3569
+ return -EINVAL;
3570
+ } else if (q_num < vsi->num_txq) {
3571
+ if (ice_get_rc_coalesce(ec, ICE_TX_CONTAINER,
3572
+ &vsi->tx_rings[q_num]->q_vector->tx))
3573
+ return -EINVAL;
3574
+ } else {
3575
+ return -EINVAL;
3576
+ }
3577
+
3578
+ return 0;
3579
+}
3580
+
3581
+/**
3582
+ * __ice_get_coalesce - get ITR/INTRL values for the device
3583
+ * @netdev: pointer to the netdev associated with this query
3584
+ * @ec: ethtool structure to fill with driver's coalesce settings
3585
+ * @q_num: queue number to get the coalesce settings for
3586
+ *
3587
+ * If the caller passes in a negative q_num then we return coalesce settings
3588
+ * based on queue number 0, else use the actual q_num passed in.
3589
+ */
3590
+static int
3591
+__ice_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
3592
+ int q_num)
3593
+{
3594
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3595
+ struct ice_vsi *vsi = np->vsi;
3596
+
3597
+ if (q_num < 0)
3598
+ q_num = 0;
3599
+
3600
+ if (ice_get_q_coalesce(vsi, ec, q_num))
3601
+ return -EINVAL;
3602
+
3603
+ return 0;
3604
+}
3605
+
3606
+static int
3607
+ice_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
3608
+{
3609
+ return __ice_get_coalesce(netdev, ec, -1);
3610
+}
3611
+
3612
+static int
3613
+ice_get_per_q_coalesce(struct net_device *netdev, u32 q_num,
3614
+ struct ethtool_coalesce *ec)
3615
+{
3616
+ return __ice_get_coalesce(netdev, ec, q_num);
3617
+}
3618
+
3619
+/**
3620
+ * ice_set_rc_coalesce - set ITR values for specific ring container
3621
+ * @c_type: container type, Rx or Tx
3622
+ * @ec: ethtool structure from user to update ITR settings
3623
+ * @rc: ring container that the ITR values will come from
3624
+ * @vsi: VSI associated to the ring container
3625
+ *
3626
+ * Set specific ITR values. This is done per ice_ring_container because each
3627
+ * q_vector can have 1 or more rings and all of said ring(s) will have the same
3628
+ * ITR values.
3629
+ *
3630
+ * Returns 0 on success, negative otherwise.
3631
+ */
3632
+static int
3633
+ice_set_rc_coalesce(enum ice_container_type c_type, struct ethtool_coalesce *ec,
3634
+ struct ice_ring_container *rc, struct ice_vsi *vsi)
3635
+{
3636
+ const char *c_type_str = (c_type == ICE_RX_CONTAINER) ? "rx" : "tx";
3637
+ u32 use_adaptive_coalesce, coalesce_usecs;
3638
+ struct ice_pf *pf = vsi->back;
3639
+ u16 itr_setting;
3640
+
3641
+ if (!rc->ring)
3642
+ return -EINVAL;
3643
+
3644
+ switch (c_type) {
3645
+ case ICE_RX_CONTAINER:
3646
+ if (ec->rx_coalesce_usecs_high > ICE_MAX_INTRL ||
3647
+ (ec->rx_coalesce_usecs_high &&
3648
+ ec->rx_coalesce_usecs_high < pf->hw.intrl_gran)) {
3649
+ netdev_info(vsi->netdev, "Invalid value, %s-usecs-high valid values are 0 (disabled), %d-%d\n",
3650
+ c_type_str, pf->hw.intrl_gran,
3651
+ ICE_MAX_INTRL);
3652
+ return -EINVAL;
3653
+ }
3654
+ if (ec->rx_coalesce_usecs_high != rc->ring->q_vector->intrl) {
3655
+ rc->ring->q_vector->intrl = ec->rx_coalesce_usecs_high;
3656
+ wr32(&pf->hw, GLINT_RATE(rc->ring->q_vector->reg_idx),
3657
+ ice_intrl_usec_to_reg(ec->rx_coalesce_usecs_high,
3658
+ pf->hw.intrl_gran));
3659
+ }
3660
+
3661
+ use_adaptive_coalesce = ec->use_adaptive_rx_coalesce;
3662
+ coalesce_usecs = ec->rx_coalesce_usecs;
3663
+
3664
+ break;
3665
+ case ICE_TX_CONTAINER:
3666
+ use_adaptive_coalesce = ec->use_adaptive_tx_coalesce;
3667
+ coalesce_usecs = ec->tx_coalesce_usecs;
3668
+
3669
+ break;
3670
+ default:
3671
+ dev_dbg(ice_pf_to_dev(pf), "Invalid container type %d\n",
3672
+ c_type);
3673
+ return -EINVAL;
3674
+ }
3675
+
3676
+ itr_setting = rc->itr_setting & ~ICE_ITR_DYNAMIC;
3677
+ if (coalesce_usecs != itr_setting && use_adaptive_coalesce) {
3678
+ netdev_info(vsi->netdev, "%s interrupt throttling cannot be changed if adaptive-%s is enabled\n",
3679
+ c_type_str, c_type_str);
3680
+ return -EINVAL;
3681
+ }
3682
+
3683
+ if (coalesce_usecs > ICE_ITR_MAX) {
3684
+ netdev_info(vsi->netdev, "Invalid value, %s-usecs range is 0-%d\n",
3685
+ c_type_str, ICE_ITR_MAX);
3686
+ return -EINVAL;
3687
+ }
3688
+
3689
+ if (use_adaptive_coalesce) {
3690
+ rc->itr_setting |= ICE_ITR_DYNAMIC;
3691
+ } else {
3692
+ /* save the user set usecs */
3693
+ rc->itr_setting = coalesce_usecs;
3694
+ /* device ITR granularity is in 2 usec increments */
3695
+ rc->target_itr = ITR_REG_ALIGN(rc->itr_setting);
3696
+ }
3697
+
3698
+ return 0;
3699
+}
3700
+
3701
+/**
3702
+ * ice_set_q_coalesce - set a queue's ITR/INTRL (coalesce) settings
3703
+ * @vsi: VSI associated to the queue that need updating
3704
+ * @ec: coalesce settings to program the device with
3705
+ * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index
3706
+ *
3707
+ * Return 0 on success, and negative under the following conditions:
3708
+ * 1. Setting Tx or Rx ITR/INTRL (coalesce) settings failed.
3709
+ * 2. The q_num passed in is not a valid number/index for Tx and Rx rings.
3710
+ */
3711
+static int
3712
+ice_set_q_coalesce(struct ice_vsi *vsi, struct ethtool_coalesce *ec, int q_num)
3713
+{
3714
+ if (q_num < vsi->num_rxq && q_num < vsi->num_txq) {
3715
+ if (ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
3716
+ &vsi->rx_rings[q_num]->q_vector->rx,
3717
+ vsi))
3718
+ return -EINVAL;
3719
+
3720
+ if (ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
3721
+ &vsi->tx_rings[q_num]->q_vector->tx,
3722
+ vsi))
3723
+ return -EINVAL;
3724
+ } else if (q_num < vsi->num_rxq) {
3725
+ if (ice_set_rc_coalesce(ICE_RX_CONTAINER, ec,
3726
+ &vsi->rx_rings[q_num]->q_vector->rx,
3727
+ vsi))
3728
+ return -EINVAL;
3729
+ } else if (q_num < vsi->num_txq) {
3730
+ if (ice_set_rc_coalesce(ICE_TX_CONTAINER, ec,
3731
+ &vsi->tx_rings[q_num]->q_vector->tx,
3732
+ vsi))
3733
+ return -EINVAL;
3734
+ } else {
3735
+ return -EINVAL;
3736
+ }
3737
+
3738
+ return 0;
3739
+}
3740
+
3741
+/**
3742
+ * ice_print_if_odd_usecs - print message if user tries to set odd [tx|rx]-usecs
3743
+ * @netdev: netdev used for print
3744
+ * @itr_setting: previous user setting
3745
+ * @use_adaptive_coalesce: if adaptive coalesce is enabled or being enabled
3746
+ * @coalesce_usecs: requested value of [tx|rx]-usecs
3747
+ * @c_type_str: either "rx" or "tx" to match user set field of [tx|rx]-usecs
3748
+ */
3749
+static void
3750
+ice_print_if_odd_usecs(struct net_device *netdev, u16 itr_setting,
3751
+ u32 use_adaptive_coalesce, u32 coalesce_usecs,
3752
+ const char *c_type_str)
3753
+{
3754
+ if (use_adaptive_coalesce)
3755
+ return;
3756
+
3757
+ itr_setting = ITR_TO_REG(itr_setting);
3758
+
3759
+ if (itr_setting != coalesce_usecs && (coalesce_usecs % 2))
3760
+ netdev_info(netdev, "User set %s-usecs to %d, device only supports even values. Rounding down and attempting to set %s-usecs to %d\n",
3761
+ c_type_str, coalesce_usecs, c_type_str,
3762
+ ITR_REG_ALIGN(coalesce_usecs));
3763
+}
3764
+
3765
+/**
3766
+ * __ice_set_coalesce - set ITR/INTRL values for the device
3767
+ * @netdev: pointer to the netdev associated with this query
3768
+ * @ec: ethtool structure to fill with driver's coalesce settings
3769
+ * @q_num: queue number to get the coalesce settings for
3770
+ *
3771
+ * If the caller passes in a negative q_num then we set the coalesce settings
3772
+ * for all Tx/Rx queues, else use the actual q_num passed in.
3773
+ */
3774
+static int
3775
+__ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec,
3776
+ int q_num)
3777
+{
3778
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3779
+ struct ice_vsi *vsi = np->vsi;
3780
+
3781
+ if (q_num < 0) {
3782
+ struct ice_q_vector *q_vector = vsi->q_vectors[0];
3783
+ int v_idx;
3784
+
3785
+ if (q_vector) {
3786
+ ice_print_if_odd_usecs(netdev, q_vector->rx.itr_setting,
3787
+ ec->use_adaptive_rx_coalesce,
3788
+ ec->rx_coalesce_usecs, "rx");
3789
+
3790
+ ice_print_if_odd_usecs(netdev, q_vector->tx.itr_setting,
3791
+ ec->use_adaptive_tx_coalesce,
3792
+ ec->tx_coalesce_usecs, "tx");
3793
+ }
3794
+
3795
+ ice_for_each_q_vector(vsi, v_idx) {
3796
+ /* In some cases if DCB is configured the num_[rx|tx]q
3797
+ * can be less than vsi->num_q_vectors. This check
3798
+ * accounts for that so we don't report a false failure
3799
+ */
3800
+ if (v_idx >= vsi->num_rxq && v_idx >= vsi->num_txq)
3801
+ goto set_complete;
3802
+
3803
+ if (ice_set_q_coalesce(vsi, ec, v_idx))
3804
+ return -EINVAL;
3805
+ }
3806
+ goto set_complete;
3807
+ }
3808
+
3809
+ if (ice_set_q_coalesce(vsi, ec, q_num))
3810
+ return -EINVAL;
3811
+
3812
+set_complete:
3813
+
3814
+ return 0;
3815
+}
3816
+
3817
+static int
3818
+ice_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
3819
+{
3820
+ return __ice_set_coalesce(netdev, ec, -1);
3821
+}
3822
+
3823
+static int
3824
+ice_set_per_q_coalesce(struct net_device *netdev, u32 q_num,
3825
+ struct ethtool_coalesce *ec)
3826
+{
3827
+ return __ice_set_coalesce(netdev, ec, q_num);
3828
+}
3829
+
3830
+#define ICE_I2C_EEPROM_DEV_ADDR 0xA0
3831
+#define ICE_I2C_EEPROM_DEV_ADDR2 0xA2
3832
+#define ICE_MODULE_TYPE_SFP 0x03
3833
+#define ICE_MODULE_TYPE_QSFP_PLUS 0x0D
3834
+#define ICE_MODULE_TYPE_QSFP28 0x11
3835
+#define ICE_MODULE_SFF_ADDR_MODE 0x04
3836
+#define ICE_MODULE_SFF_DIAG_CAPAB 0x40
3837
+#define ICE_MODULE_REVISION_ADDR 0x01
3838
+#define ICE_MODULE_SFF_8472_COMP 0x5E
3839
+#define ICE_MODULE_SFF_8472_SWAP 0x5C
3840
+#define ICE_MODULE_QSFP_MAX_LEN 640
3841
+
3842
+/**
3843
+ * ice_get_module_info - get SFF module type and revision information
3844
+ * @netdev: network interface device structure
3845
+ * @modinfo: module EEPROM size and layout information structure
3846
+ */
3847
+static int
3848
+ice_get_module_info(struct net_device *netdev,
3849
+ struct ethtool_modinfo *modinfo)
3850
+{
3851
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3852
+ struct ice_vsi *vsi = np->vsi;
3853
+ struct ice_pf *pf = vsi->back;
3854
+ struct ice_hw *hw = &pf->hw;
3855
+ enum ice_status status;
3856
+ u8 sff8472_comp = 0;
3857
+ u8 sff8472_swap = 0;
3858
+ u8 sff8636_rev = 0;
3859
+ u8 value = 0;
3860
+
3861
+ status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR, 0x00, 0x00,
3862
+ 0, &value, 1, 0, NULL);
3863
+ if (status)
3864
+ return -EIO;
3865
+
3866
+ switch (value) {
3867
+ case ICE_MODULE_TYPE_SFP:
3868
+ status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR,
3869
+ ICE_MODULE_SFF_8472_COMP, 0x00, 0,
3870
+ &sff8472_comp, 1, 0, NULL);
3871
+ if (status)
3872
+ return -EIO;
3873
+ status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR,
3874
+ ICE_MODULE_SFF_8472_SWAP, 0x00, 0,
3875
+ &sff8472_swap, 1, 0, NULL);
3876
+ if (status)
3877
+ return -EIO;
3878
+
3879
+ if (sff8472_swap & ICE_MODULE_SFF_ADDR_MODE) {
3880
+ modinfo->type = ETH_MODULE_SFF_8079;
3881
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
3882
+ } else if (sff8472_comp &&
3883
+ (sff8472_swap & ICE_MODULE_SFF_DIAG_CAPAB)) {
3884
+ modinfo->type = ETH_MODULE_SFF_8472;
3885
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
3886
+ } else {
3887
+ modinfo->type = ETH_MODULE_SFF_8079;
3888
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
3889
+ }
3890
+ break;
3891
+ case ICE_MODULE_TYPE_QSFP_PLUS:
3892
+ case ICE_MODULE_TYPE_QSFP28:
3893
+ status = ice_aq_sff_eeprom(hw, 0, ICE_I2C_EEPROM_DEV_ADDR,
3894
+ ICE_MODULE_REVISION_ADDR, 0x00, 0,
3895
+ &sff8636_rev, 1, 0, NULL);
3896
+ if (status)
3897
+ return -EIO;
3898
+ /* Check revision compliance */
3899
+ if (sff8636_rev > 0x02) {
3900
+ /* Module is SFF-8636 compliant */
3901
+ modinfo->type = ETH_MODULE_SFF_8636;
3902
+ modinfo->eeprom_len = ICE_MODULE_QSFP_MAX_LEN;
3903
+ } else {
3904
+ modinfo->type = ETH_MODULE_SFF_8436;
3905
+ modinfo->eeprom_len = ICE_MODULE_QSFP_MAX_LEN;
3906
+ }
3907
+ break;
3908
+ default:
3909
+ netdev_warn(netdev, "SFF Module Type not recognized.\n");
3910
+ return -EINVAL;
3911
+ }
3912
+ return 0;
3913
+}
3914
+
3915
+/**
3916
+ * ice_get_module_eeprom - fill buffer with SFF EEPROM contents
3917
+ * @netdev: network interface device structure
3918
+ * @ee: EEPROM dump request structure
3919
+ * @data: buffer to be filled with EEPROM contents
3920
+ */
3921
+static int
3922
+ice_get_module_eeprom(struct net_device *netdev,
3923
+ struct ethtool_eeprom *ee, u8 *data)
3924
+{
3925
+ struct ice_netdev_priv *np = netdev_priv(netdev);
3926
+ u8 addr = ICE_I2C_EEPROM_DEV_ADDR;
3927
+ struct ice_vsi *vsi = np->vsi;
3928
+ struct ice_pf *pf = vsi->back;
3929
+ struct ice_hw *hw = &pf->hw;
3930
+ enum ice_status status;
3931
+ bool is_sfp = false;
3932
+ unsigned int i;
3933
+ u16 offset = 0;
3934
+ u8 value = 0;
3935
+ u8 page = 0;
3936
+
3937
+ status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, 0,
3938
+ &value, 1, 0, NULL);
3939
+ if (status)
3940
+ return -EIO;
3941
+
3942
+ if (!ee || !ee->len || !data)
3943
+ return -EINVAL;
3944
+
3945
+ if (value == ICE_MODULE_TYPE_SFP)
3946
+ is_sfp = true;
3947
+
3948
+ for (i = 0; i < ee->len; i++) {
3949
+ offset = i + ee->offset;
3950
+
3951
+ /* Check if we need to access the other memory page */
3952
+ if (is_sfp) {
3953
+ if (offset >= ETH_MODULE_SFF_8079_LEN) {
3954
+ offset -= ETH_MODULE_SFF_8079_LEN;
3955
+ addr = ICE_I2C_EEPROM_DEV_ADDR2;
3956
+ }
3957
+ } else {
3958
+ while (offset >= ETH_MODULE_SFF_8436_LEN) {
3959
+ /* Compute memory page number and offset. */
3960
+ offset -= ETH_MODULE_SFF_8436_LEN / 2;
3961
+ page++;
3962
+ }
3963
+ }
3964
+
3965
+ status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, !is_sfp,
3966
+ &value, 1, 0, NULL);
3967
+ if (status)
3968
+ value = 0;
3969
+ data[i] = value;
3970
+ }
3971
+ return 0;
3972
+}
3973
+
9433974 static const struct ethtool_ops ice_ethtool_ops = {
3975
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
3976
+ ETHTOOL_COALESCE_USE_ADAPTIVE |
3977
+ ETHTOOL_COALESCE_RX_USECS_HIGH,
9443978 .get_link_ksettings = ice_get_link_ksettings,
945
- .get_drvinfo = ice_get_drvinfo,
946
- .get_regs_len = ice_get_regs_len,
947
- .get_regs = ice_get_regs,
948
- .get_msglevel = ice_get_msglevel,
949
- .set_msglevel = ice_set_msglevel,
3979
+ .set_link_ksettings = ice_set_link_ksettings,
3980
+ .get_drvinfo = ice_get_drvinfo,
3981
+ .get_regs_len = ice_get_regs_len,
3982
+ .get_regs = ice_get_regs,
3983
+ .get_wol = ice_get_wol,
3984
+ .set_wol = ice_set_wol,
3985
+ .get_msglevel = ice_get_msglevel,
3986
+ .set_msglevel = ice_set_msglevel,
3987
+ .self_test = ice_self_test,
9503988 .get_link = ethtool_op_get_link,
3989
+ .get_eeprom_len = ice_get_eeprom_len,
3990
+ .get_eeprom = ice_get_eeprom,
3991
+ .get_coalesce = ice_get_coalesce,
3992
+ .set_coalesce = ice_set_coalesce,
9513993 .get_strings = ice_get_strings,
3994
+ .set_phys_id = ice_set_phys_id,
9523995 .get_ethtool_stats = ice_get_ethtool_stats,
3996
+ .get_priv_flags = ice_get_priv_flags,
3997
+ .set_priv_flags = ice_set_priv_flags,
9533998 .get_sset_count = ice_get_sset_count,
9543999 .get_rxnfc = ice_get_rxnfc,
4000
+ .set_rxnfc = ice_set_rxnfc,
9554001 .get_ringparam = ice_get_ringparam,
9564002 .set_ringparam = ice_set_ringparam,
9574003 .nway_reset = ice_nway_reset,
....@@ -961,8 +4007,48 @@
9614007 .get_rxfh_indir_size = ice_get_rxfh_indir_size,
9624008 .get_rxfh = ice_get_rxfh,
9634009 .set_rxfh = ice_set_rxfh,
4010
+ .get_channels = ice_get_channels,
4011
+ .set_channels = ice_set_channels,
4012
+ .get_ts_info = ethtool_op_get_ts_info,
4013
+ .get_per_queue_coalesce = ice_get_per_q_coalesce,
4014
+ .set_per_queue_coalesce = ice_set_per_q_coalesce,
4015
+ .get_fecparam = ice_get_fecparam,
4016
+ .set_fecparam = ice_set_fecparam,
4017
+ .get_module_info = ice_get_module_info,
4018
+ .get_module_eeprom = ice_get_module_eeprom,
9644019 };
9654020
4021
+static const struct ethtool_ops ice_ethtool_safe_mode_ops = {
4022
+ .get_link_ksettings = ice_get_link_ksettings,
4023
+ .set_link_ksettings = ice_set_link_ksettings,
4024
+ .get_drvinfo = ice_get_drvinfo,
4025
+ .get_regs_len = ice_get_regs_len,
4026
+ .get_regs = ice_get_regs,
4027
+ .get_wol = ice_get_wol,
4028
+ .set_wol = ice_set_wol,
4029
+ .get_msglevel = ice_get_msglevel,
4030
+ .set_msglevel = ice_set_msglevel,
4031
+ .get_link = ethtool_op_get_link,
4032
+ .get_eeprom_len = ice_get_eeprom_len,
4033
+ .get_eeprom = ice_get_eeprom,
4034
+ .get_strings = ice_get_strings,
4035
+ .get_ethtool_stats = ice_get_ethtool_stats,
4036
+ .get_sset_count = ice_get_sset_count,
4037
+ .get_ringparam = ice_get_ringparam,
4038
+ .set_ringparam = ice_set_ringparam,
4039
+ .nway_reset = ice_nway_reset,
4040
+ .get_channels = ice_get_channels,
4041
+};
4042
+
4043
+/**
4044
+ * ice_set_ethtool_safe_mode_ops - setup safe mode ethtool ops
4045
+ * @netdev: network interface device structure
4046
+ */
4047
+void ice_set_ethtool_safe_mode_ops(struct net_device *netdev)
4048
+{
4049
+ netdev->ethtool_ops = &ice_ethtool_safe_mode_ops;
4050
+}
4051
+
9664052 /**
9674053 * ice_set_ethtool_ops - setup netdev ethtool ops
9684054 * @netdev: network interface device structure