hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
....@@ -5,34 +5,239 @@
55
66 #include "i40e.h"
77 #include "i40e_diag.h"
8
+#include "i40e_txrx_common.h"
89
10
+/* ethtool statistics helpers */
11
+
12
+/**
13
+ * struct i40e_stats - definition for an ethtool statistic
14
+ * @stat_string: statistic name to display in ethtool -S output
15
+ * @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64)
16
+ * @stat_offset: offsetof() the stat from a base pointer
17
+ *
18
+ * This structure defines a statistic to be added to the ethtool stats buffer.
19
+ * It defines a statistic as offset from a common base pointer. Stats should
20
+ * be defined in constant arrays using the I40E_STAT macro, with every element
21
+ * of the array using the same _type for calculating the sizeof_stat and
22
+ * stat_offset.
23
+ *
24
+ * The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or
25
+ * sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from
26
+ * the i40e_add_ethtool_stat() helper function.
27
+ *
28
+ * The @stat_string is interpreted as a format string, allowing formatted
29
+ * values to be inserted while looping over multiple structures for a given
30
+ * statistics array. Thus, every statistic string in an array should have the
31
+ * same type and number of format specifiers, to be formatted by variadic
32
+ * arguments to the i40e_add_stat_string() helper function.
33
+ **/
934 struct i40e_stats {
10
- /* The stat_string is expected to be a format string formatted using
11
- * vsnprintf by i40e_add_stat_strings. Every member of a stats array
12
- * should use the same format specifiers as they will be formatted
13
- * using the same variadic arguments.
14
- */
1535 char stat_string[ETH_GSTRING_LEN];
1636 int sizeof_stat;
1737 int stat_offset;
1838 };
1939
40
+/* Helper macro to define an i40e_stat structure with proper size and type.
41
+ * Use this when defining constant statistics arrays. Note that @_type expects
42
+ * only a type name and is used multiple times.
43
+ */
2044 #define I40E_STAT(_type, _name, _stat) { \
2145 .stat_string = _name, \
22
- .sizeof_stat = FIELD_SIZEOF(_type, _stat), \
46
+ .sizeof_stat = sizeof_field(_type, _stat), \
2347 .stat_offset = offsetof(_type, _stat) \
2448 }
2549
50
+/* Helper macro for defining some statistics directly copied from the netdev
51
+ * stats structure.
52
+ */
2653 #define I40E_NETDEV_STAT(_net_stat) \
2754 I40E_STAT(struct rtnl_link_stats64, #_net_stat, _net_stat)
55
+
56
+/* Helper macro for defining some statistics related to queues */
57
+#define I40E_QUEUE_STAT(_name, _stat) \
58
+ I40E_STAT(struct i40e_ring, _name, _stat)
59
+
60
+/* Stats associated with a Tx or Rx ring */
61
+static const struct i40e_stats i40e_gstrings_queue_stats[] = {
62
+ I40E_QUEUE_STAT("%s-%u.packets", stats.packets),
63
+ I40E_QUEUE_STAT("%s-%u.bytes", stats.bytes),
64
+};
65
+
66
+/**
67
+ * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
68
+ * @data: location to store the stat value
69
+ * @pointer: basis for where to copy from
70
+ * @stat: the stat definition
71
+ *
72
+ * Copies the stat data defined by the pointer and stat structure pair into
73
+ * the memory supplied as data. Used to implement i40e_add_ethtool_stats and
74
+ * i40e_add_queue_stats. If the pointer is null, data will be zero'd.
75
+ */
76
+static void
77
+i40e_add_one_ethtool_stat(u64 *data, void *pointer,
78
+ const struct i40e_stats *stat)
79
+{
80
+ char *p;
81
+
82
+ if (!pointer) {
83
+ /* ensure that the ethtool data buffer is zero'd for any stats
84
+ * which don't have a valid pointer.
85
+ */
86
+ *data = 0;
87
+ return;
88
+ }
89
+
90
+ p = (char *)pointer + stat->stat_offset;
91
+ switch (stat->sizeof_stat) {
92
+ case sizeof(u64):
93
+ *data = *((u64 *)p);
94
+ break;
95
+ case sizeof(u32):
96
+ *data = *((u32 *)p);
97
+ break;
98
+ case sizeof(u16):
99
+ *data = *((u16 *)p);
100
+ break;
101
+ case sizeof(u8):
102
+ *data = *((u8 *)p);
103
+ break;
104
+ default:
105
+ WARN_ONCE(1, "unexpected stat size for %s",
106
+ stat->stat_string);
107
+ *data = 0;
108
+ }
109
+}
110
+
111
+/**
112
+ * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
113
+ * @data: ethtool stats buffer
114
+ * @pointer: location to copy stats from
115
+ * @stats: array of stats to copy
116
+ * @size: the size of the stats definition
117
+ *
118
+ * Copy the stats defined by the stats array using the pointer as a base into
119
+ * the data buffer supplied by ethtool. Updates the data pointer to point to
120
+ * the next empty location for successive calls to __i40e_add_ethtool_stats.
121
+ * If pointer is null, set the data values to zero and update the pointer to
122
+ * skip these stats.
123
+ **/
124
+static void
125
+__i40e_add_ethtool_stats(u64 **data, void *pointer,
126
+ const struct i40e_stats stats[],
127
+ const unsigned int size)
128
+{
129
+ unsigned int i;
130
+
131
+ for (i = 0; i < size; i++)
132
+ i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
133
+}
134
+
135
+/**
136
+ * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
137
+ * @data: ethtool stats buffer
138
+ * @pointer: location where stats are stored
139
+ * @stats: static const array of stat definitions
140
+ *
141
+ * Macro to ease the use of __i40e_add_ethtool_stats by taking a static
142
+ * constant stats array and passing the ARRAY_SIZE(). This avoids typos by
143
+ * ensuring that we pass the size associated with the given stats array.
144
+ *
145
+ * The parameter @stats is evaluated twice, so parameters with side effects
146
+ * should be avoided.
147
+ **/
148
+#define i40e_add_ethtool_stats(data, pointer, stats) \
149
+ __i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
150
+
151
+/**
152
+ * i40e_add_queue_stats - copy queue statistics into supplied buffer
153
+ * @data: ethtool stats buffer
154
+ * @ring: the ring to copy
155
+ *
156
+ * Queue statistics must be copied while protected by
157
+ * u64_stats_fetch_begin_irq, so we can't directly use i40e_add_ethtool_stats.
158
+ * Assumes that queue stats are defined in i40e_gstrings_queue_stats. If the
159
+ * ring pointer is null, zero out the queue stat values and update the data
160
+ * pointer. Otherwise safely copy the stats from the ring into the supplied
161
+ * buffer and update the data pointer when finished.
162
+ *
163
+ * This function expects to be called while under rcu_read_lock().
164
+ **/
165
+static void
166
+i40e_add_queue_stats(u64 **data, struct i40e_ring *ring)
167
+{
168
+ const unsigned int size = ARRAY_SIZE(i40e_gstrings_queue_stats);
169
+ const struct i40e_stats *stats = i40e_gstrings_queue_stats;
170
+ unsigned int start;
171
+ unsigned int i;
172
+
173
+ /* To avoid invalid statistics values, ensure that we keep retrying
174
+ * the copy until we get a consistent value according to
175
+ * u64_stats_fetch_retry_irq. But first, make sure our ring is
176
+ * non-null before attempting to access its syncp.
177
+ */
178
+ do {
179
+ start = !ring ? 0 : u64_stats_fetch_begin_irq(&ring->syncp);
180
+ for (i = 0; i < size; i++) {
181
+ i40e_add_one_ethtool_stat(&(*data)[i], ring,
182
+ &stats[i]);
183
+ }
184
+ } while (ring && u64_stats_fetch_retry_irq(&ring->syncp, start));
185
+
186
+ /* Once we successfully copy the stats in, update the data pointer */
187
+ *data += size;
188
+}
189
+
190
+/**
191
+ * __i40e_add_stat_strings - copy stat strings into ethtool buffer
192
+ * @p: ethtool supplied buffer
193
+ * @stats: stat definitions array
194
+ * @size: size of the stats array
195
+ *
196
+ * Format and copy the strings described by stats into the buffer pointed at
197
+ * by p.
198
+ **/
199
+static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
200
+ const unsigned int size, ...)
201
+{
202
+ unsigned int i;
203
+
204
+ for (i = 0; i < size; i++) {
205
+ va_list args;
206
+
207
+ va_start(args, size);
208
+ vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
209
+ *p += ETH_GSTRING_LEN;
210
+ va_end(args);
211
+ }
212
+}
213
+
214
+/**
215
+ * 40e_add_stat_strings - copy stat strings into ethtool buffer
216
+ * @p: ethtool supplied buffer
217
+ * @stats: stat definitions array
218
+ *
219
+ * Format and copy the strings described by the const static stats value into
220
+ * the buffer pointed at by p.
221
+ *
222
+ * The parameter @stats is evaluated twice, so parameters with side effects
223
+ * should be avoided. Additionally, stats must be an array such that
224
+ * ARRAY_SIZE can be called on it.
225
+ **/
226
+#define i40e_add_stat_strings(p, stats, ...) \
227
+ __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
228
+
28229 #define I40E_PF_STAT(_name, _stat) \
29230 I40E_STAT(struct i40e_pf, _name, _stat)
30231 #define I40E_VSI_STAT(_name, _stat) \
31232 I40E_STAT(struct i40e_vsi, _name, _stat)
32233 #define I40E_VEB_STAT(_name, _stat) \
33234 I40E_STAT(struct i40e_veb, _name, _stat)
235
+#define I40E_VEB_TC_STAT(_name, _stat) \
236
+ I40E_STAT(struct i40e_cp_veb_tc_stats, _name, _stat)
34237 #define I40E_PFC_STAT(_name, _stat) \
35238 I40E_STAT(struct i40e_pfc_stats, _name, _stat)
239
+#define I40E_QUEUE_STAT(_name, _stat) \
240
+ I40E_STAT(struct i40e_ring, _name, _stat)
36241
37242 static const struct i40e_stats i40e_gstrings_net_stats[] = {
38243 I40E_NETDEV_STAT(rx_packets),
....@@ -63,11 +268,18 @@
63268 I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol),
64269 };
65270
271
+struct i40e_cp_veb_tc_stats {
272
+ u64 tc_rx_packets;
273
+ u64 tc_rx_bytes;
274
+ u64 tc_tx_packets;
275
+ u64 tc_tx_bytes;
276
+};
277
+
66278 static const struct i40e_stats i40e_gstrings_veb_tc_stats[] = {
67
- I40E_VEB_STAT("veb.tc_%u_tx_packets", tc_stats.tc_tx_packets),
68
- I40E_VEB_STAT("veb.tc_%u_tx_bytes", tc_stats.tc_tx_bytes),
69
- I40E_VEB_STAT("veb.tc_%u_rx_packets", tc_stats.tc_rx_packets),
70
- I40E_VEB_STAT("veb.tc_%u_rx_bytes", tc_stats.tc_rx_bytes),
279
+ I40E_VEB_TC_STAT("veb.tc_%u_tx_packets", tc_tx_packets),
280
+ I40E_VEB_TC_STAT("veb.tc_%u_tx_bytes", tc_tx_bytes),
281
+ I40E_VEB_TC_STAT("veb.tc_%u_rx_packets", tc_rx_packets),
282
+ I40E_VEB_TC_STAT("veb.tc_%u_rx_bytes", tc_rx_bytes),
71283 };
72284
73285 static const struct i40e_stats i40e_gstrings_misc_stats[] = {
....@@ -171,20 +383,11 @@
171383 I40E_PFC_STAT("port.rx_priority_%u_xon_2_xoff", priority_xon_2_xoff),
172384 };
173385
174
-/* We use num_tx_queues here as a proxy for the maximum number of queues
175
- * available because we always allocate queues symmetrically.
176
- */
177
-#define I40E_MAX_NUM_QUEUES(n) ((n)->num_tx_queues)
178
-#define I40E_QUEUE_STATS_LEN(n) \
179
- (I40E_MAX_NUM_QUEUES(n) \
180
- * 2 /* Tx and Rx together */ \
181
- * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
182
-#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
183386 #define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
387
+
184388 #define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
185
-#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
186
- I40E_MISC_STATS_LEN + \
187
- I40E_QUEUE_STATS_LEN((n)))
389
+
390
+#define I40E_VSI_STATS_LEN (I40E_NETDEV_STATS_LEN + I40E_MISC_STATS_LEN)
188391
189392 #define I40E_PFC_STATS_LEN (ARRAY_SIZE(i40e_gstrings_pfc_stats) * \
190393 I40E_MAX_USER_PRIORITY)
....@@ -193,10 +396,15 @@
193396 (ARRAY_SIZE(i40e_gstrings_veb_tc_stats) * \
194397 I40E_MAX_TRAFFIC_CLASS))
195398
196
-#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
399
+#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
400
+
401
+#define I40E_PF_STATS_LEN (I40E_GLOBAL_STATS_LEN + \
197402 I40E_PFC_STATS_LEN + \
198403 I40E_VEB_STATS_LEN + \
199
- I40E_VSI_STATS_LEN((n)))
404
+ I40E_VSI_STATS_LEN)
405
+
406
+/* Length of stats for a single queue */
407
+#define I40E_QUEUE_STATS_LEN ARRAY_SIZE(i40e_gstrings_queue_stats)
200408
201409 enum i40e_ethtool_test_id {
202410 I40E_ETH_TEST_REG = 0,
....@@ -229,6 +437,8 @@
229437 static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
230438 /* NOTE: MFP setting cannot be changed */
231439 I40E_PRIV_FLAG("MFP", I40E_FLAG_MFP_ENABLED, 1),
440
+ I40E_PRIV_FLAG("total-port-shutdown",
441
+ I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED, 1),
232442 I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0),
233443 I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
234444 I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
....@@ -239,6 +449,8 @@
239449 I40E_PRIV_FLAG("disable-source-pruning",
240450 I40E_FLAG_SOURCE_PRUNING_DISABLED, 0),
241451 I40E_PRIV_FLAG("disable-fw-lldp", I40E_FLAG_DISABLE_FW_LLDP, 0),
452
+ I40E_PRIV_FLAG("rs-fec", I40E_FLAG_RS_FEC, 0),
453
+ I40E_PRIV_FLAG("base-r-fec", I40E_FLAG_BASE_R_FEC, 0),
242454 };
243455
244456 #define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
....@@ -307,6 +519,20 @@
307519 ethtool_link_ksettings_add_link_mode(ks, advertising,
308520 10000baseT_Full);
309521 }
522
+ if (phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T) {
523
+ ethtool_link_ksettings_add_link_mode(ks, supported,
524
+ 2500baseT_Full);
525
+ if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB)
526
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
527
+ 2500baseT_Full);
528
+ }
529
+ if (phy_types & I40E_CAP_PHY_TYPE_5GBASE_T) {
530
+ ethtool_link_ksettings_add_link_mode(ks, supported,
531
+ 5000baseT_Full);
532
+ if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB)
533
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
534
+ 5000baseT_Full);
535
+ }
310536 if (phy_types & I40E_CAP_PHY_TYPE_XLAUI ||
311537 phy_types & I40E_CAP_PHY_TYPE_XLPPI ||
312538 phy_types & I40E_CAP_PHY_TYPE_40GBASE_AOC)
....@@ -334,17 +560,23 @@
334560 ethtool_link_ksettings_add_link_mode(ks, advertising,
335561 1000baseT_Full);
336562 }
337
- if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_SR4)
563
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_SR4) {
338564 ethtool_link_ksettings_add_link_mode(ks, supported,
339565 40000baseSR4_Full);
340
- if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_LR4)
341
- ethtool_link_ksettings_add_link_mode(ks, supported,
342
- 40000baseLR4_Full);
343
- if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) {
566
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
567
+ 40000baseSR4_Full);
568
+ }
569
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_LR4) {
344570 ethtool_link_ksettings_add_link_mode(ks, supported,
345571 40000baseLR4_Full);
346572 ethtool_link_ksettings_add_link_mode(ks, advertising,
347573 40000baseLR4_Full);
574
+ }
575
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) {
576
+ ethtool_link_ksettings_add_link_mode(ks, supported,
577
+ 40000baseKR4_Full);
578
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
579
+ 40000baseKR4_Full);
348580 }
349581 if (phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2) {
350582 ethtool_link_ksettings_add_link_mode(ks, supported,
....@@ -407,6 +639,24 @@
407639 ethtool_link_ksettings_add_link_mode(ks, advertising,
408640 25000baseCR_Full);
409641 }
642
+ if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
643
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
644
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
645
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR ||
646
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_AOC ||
647
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_ACC) {
648
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
649
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
650
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
651
+ if (hw_link_info->requested_speeds & I40E_LINK_SPEED_25GB) {
652
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
653
+ FEC_NONE);
654
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
655
+ FEC_RS);
656
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
657
+ FEC_BASER);
658
+ }
659
+ }
410660 /* need to add new 10G PHY types */
411661 if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
412662 phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU) {
....@@ -449,13 +699,15 @@
449699 phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
450700 phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
451701 phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2 ||
452
- phy_types & I40E_CAP_PHY_TYPE_10GBASE_T ||
453702 phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
454703 phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR ||
455704 phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4 ||
456705 phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR ||
457706 phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
458707 phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
708
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_T ||
709
+ phy_types & I40E_CAP_PHY_TYPE_5GBASE_T ||
710
+ phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T ||
459711 phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL ||
460712 phy_types & I40E_CAP_PHY_TYPE_1000BASE_T ||
461713 phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
....@@ -466,6 +718,36 @@
466718 Autoneg);
467719 ethtool_link_ksettings_add_link_mode(ks, advertising,
468720 Autoneg);
721
+ }
722
+}
723
+
724
+/**
725
+ * i40e_get_settings_link_up_fec - Get the FEC mode encoding from mask
726
+ * @req_fec_info: mask request FEC info
727
+ * @ks: ethtool ksettings to fill in
728
+ **/
729
+static void i40e_get_settings_link_up_fec(u8 req_fec_info,
730
+ struct ethtool_link_ksettings *ks)
731
+{
732
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_NONE);
733
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
734
+ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
735
+
736
+ if ((I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) &&
737
+ (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info)) {
738
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
739
+ FEC_NONE);
740
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
741
+ FEC_BASER);
742
+ ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
743
+ } else if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) {
744
+ ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
745
+ } else if (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info) {
746
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
747
+ FEC_BASER);
748
+ } else {
749
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
750
+ FEC_NONE);
469751 }
470752 }
471753
....@@ -501,13 +783,19 @@
501783 case I40E_PHY_TYPE_40GBASE_AOC:
502784 ethtool_link_ksettings_add_link_mode(ks, supported,
503785 40000baseCR4_Full);
786
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
787
+ 40000baseCR4_Full);
504788 break;
505789 case I40E_PHY_TYPE_40GBASE_SR4:
506790 ethtool_link_ksettings_add_link_mode(ks, supported,
507791 40000baseSR4_Full);
792
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
793
+ 40000baseSR4_Full);
508794 break;
509795 case I40E_PHY_TYPE_40GBASE_LR4:
510796 ethtool_link_ksettings_add_link_mode(ks, supported,
797
+ 40000baseLR4_Full);
798
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
511799 40000baseLR4_Full);
512800 break;
513801 case I40E_PHY_TYPE_25GBASE_SR:
....@@ -522,6 +810,7 @@
522810 25000baseSR_Full);
523811 ethtool_link_ksettings_add_link_mode(ks, advertising,
524812 25000baseSR_Full);
813
+ i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
525814 ethtool_link_ksettings_add_link_mode(ks, supported,
526815 10000baseSR_Full);
527816 ethtool_link_ksettings_add_link_mode(ks, advertising,
....@@ -552,11 +841,17 @@
552841 10000baseT_Full);
553842 break;
554843 case I40E_PHY_TYPE_10GBASE_T:
844
+ case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
845
+ case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
555846 case I40E_PHY_TYPE_1000BASE_T:
556847 case I40E_PHY_TYPE_100BASE_TX:
557848 ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
558849 ethtool_link_ksettings_add_link_mode(ks, supported,
559850 10000baseT_Full);
851
+ ethtool_link_ksettings_add_link_mode(ks, supported,
852
+ 5000baseT_Full);
853
+ ethtool_link_ksettings_add_link_mode(ks, supported,
854
+ 2500baseT_Full);
560855 ethtool_link_ksettings_add_link_mode(ks, supported,
561856 1000baseT_Full);
562857 ethtool_link_ksettings_add_link_mode(ks, supported,
....@@ -565,6 +860,12 @@
565860 if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
566861 ethtool_link_ksettings_add_link_mode(ks, advertising,
567862 10000baseT_Full);
863
+ if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB)
864
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
865
+ 5000baseT_Full);
866
+ if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB)
867
+ ethtool_link_ksettings_add_link_mode(ks, advertising,
868
+ 2500baseT_Full);
568869 if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
569870 ethtool_link_ksettings_add_link_mode(ks, advertising,
570871 1000baseT_Full);
....@@ -599,6 +900,7 @@
599900 if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
600901 ethtool_link_ksettings_add_link_mode(ks, advertising,
601902 10000baseT_Full);
903
+ i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
602904 break;
603905 case I40E_PHY_TYPE_SGMII:
604906 ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
....@@ -639,6 +941,7 @@
639941 40000baseKR4_Full);
640942 ethtool_link_ksettings_add_link_mode(ks, advertising,
641943 25000baseKR_Full);
944
+ i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
642945 ethtool_link_ksettings_add_link_mode(ks, advertising,
643946 20000baseKR2_Full);
644947 ethtool_link_ksettings_add_link_mode(ks, advertising,
....@@ -656,6 +959,8 @@
656959 25000baseCR_Full);
657960 ethtool_link_ksettings_add_link_mode(ks, advertising,
658961 25000baseCR_Full);
962
+ i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
963
+
659964 break;
660965 case I40E_PHY_TYPE_25GBASE_AOC:
661966 case I40E_PHY_TYPE_25GBASE_ACC:
....@@ -663,9 +968,10 @@
663968 ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg);
664969 ethtool_link_ksettings_add_link_mode(ks, supported,
665970 25000baseCR_Full);
666
-
667971 ethtool_link_ksettings_add_link_mode(ks, advertising,
668972 25000baseCR_Full);
973
+ i40e_get_settings_link_up_fec(hw_link_info->req_fec_info, ks);
974
+
669975 ethtool_link_ksettings_add_link_mode(ks, supported,
670976 10000baseCR_Full);
671977 ethtool_link_ksettings_add_link_mode(ks, advertising,
....@@ -700,6 +1006,12 @@
7001006 case I40E_LINK_SPEED_10GB:
7011007 ks->base.speed = SPEED_10000;
7021008 break;
1009
+ case I40E_LINK_SPEED_5GB:
1010
+ ks->base.speed = SPEED_5000;
1011
+ break;
1012
+ case I40E_LINK_SPEED_2_5GB:
1013
+ ks->base.speed = SPEED_2500;
1014
+ break;
7031015 case I40E_LINK_SPEED_1GB:
7041016 ks->base.speed = SPEED_1000;
7051017 break;
....@@ -707,6 +1019,7 @@
7071019 ks->base.speed = SPEED_100;
7081020 break;
7091021 default:
1022
+ ks->base.speed = SPEED_UNKNOWN;
7101023 break;
7111024 }
7121025 ks->base.duplex = DUPLEX_FULL;
....@@ -786,6 +1099,7 @@
7861099 break;
7871100 case I40E_MEDIA_TYPE_FIBER:
7881101 ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
1102
+ ethtool_link_ksettings_add_link_mode(ks, advertising, FIBRE);
7891103 ks->base.port = PORT_FIBRE;
7901104 break;
7911105 case I40E_MEDIA_TYPE_UNKNOWN:
....@@ -984,6 +1298,12 @@
9841298 10000baseLR_Full))
9851299 config.link_speed |= I40E_LINK_SPEED_10GB;
9861300 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
1301
+ 2500baseT_Full))
1302
+ config.link_speed |= I40E_LINK_SPEED_2_5GB;
1303
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
1304
+ 5000baseT_Full))
1305
+ config.link_speed |= I40E_LINK_SPEED_5GB;
1306
+ if (ethtool_link_ksettings_test_link_mode(ks, advertising,
9871307 20000baseKR2_Full))
9881308 config.link_speed |= I40E_LINK_SPEED_20GB;
9891309 if (ethtool_link_ksettings_test_link_mode(ks, advertising,
....@@ -1059,6 +1379,154 @@
10591379 clear_bit(__I40E_CONFIG_BUSY, pf->state);
10601380
10611381 return err;
1382
+}
1383
+
1384
+static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg)
1385
+{
1386
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
1387
+ struct i40e_aq_get_phy_abilities_resp abilities;
1388
+ struct i40e_pf *pf = np->vsi->back;
1389
+ struct i40e_hw *hw = &pf->hw;
1390
+ i40e_status status = 0;
1391
+ u32 flags = 0;
1392
+ int err = 0;
1393
+
1394
+ flags = READ_ONCE(pf->flags);
1395
+ i40e_set_fec_in_flags(fec_cfg, &flags);
1396
+
1397
+ /* Get the current phy config */
1398
+ memset(&abilities, 0, sizeof(abilities));
1399
+ status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
1400
+ NULL);
1401
+ if (status) {
1402
+ err = -EAGAIN;
1403
+ goto done;
1404
+ }
1405
+
1406
+ if (abilities.fec_cfg_curr_mod_ext_info != fec_cfg) {
1407
+ struct i40e_aq_set_phy_config config;
1408
+
1409
+ memset(&config, 0, sizeof(config));
1410
+ config.phy_type = abilities.phy_type;
1411
+ config.abilities = abilities.abilities |
1412
+ I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
1413
+ config.phy_type_ext = abilities.phy_type_ext;
1414
+ config.link_speed = abilities.link_speed;
1415
+ config.eee_capability = abilities.eee_capability;
1416
+ config.eeer = abilities.eeer_val;
1417
+ config.low_power_ctrl = abilities.d3_lpan;
1418
+ config.fec_config = fec_cfg & I40E_AQ_PHY_FEC_CONFIG_MASK;
1419
+ status = i40e_aq_set_phy_config(hw, &config, NULL);
1420
+ if (status) {
1421
+ netdev_info(netdev,
1422
+ "Set phy config failed, err %s aq_err %s\n",
1423
+ i40e_stat_str(hw, status),
1424
+ i40e_aq_str(hw, hw->aq.asq_last_status));
1425
+ err = -EAGAIN;
1426
+ goto done;
1427
+ }
1428
+ pf->flags = flags;
1429
+ status = i40e_update_link_info(hw);
1430
+ if (status)
1431
+ /* debug level message only due to relation to the link
1432
+ * itself rather than to the FEC settings
1433
+ * (e.g. no physical connection etc.)
1434
+ */
1435
+ netdev_dbg(netdev,
1436
+ "Updating link info failed with err %s aq_err %s\n",
1437
+ i40e_stat_str(hw, status),
1438
+ i40e_aq_str(hw, hw->aq.asq_last_status));
1439
+ }
1440
+
1441
+done:
1442
+ return err;
1443
+}
1444
+
1445
+static int i40e_get_fec_param(struct net_device *netdev,
1446
+ struct ethtool_fecparam *fecparam)
1447
+{
1448
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
1449
+ struct i40e_aq_get_phy_abilities_resp abilities;
1450
+ struct i40e_pf *pf = np->vsi->back;
1451
+ struct i40e_hw *hw = &pf->hw;
1452
+ i40e_status status = 0;
1453
+ int err = 0;
1454
+ u8 fec_cfg;
1455
+
1456
+ /* Get the current phy config */
1457
+ memset(&abilities, 0, sizeof(abilities));
1458
+ status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
1459
+ NULL);
1460
+ if (status) {
1461
+ err = -EAGAIN;
1462
+ goto done;
1463
+ }
1464
+
1465
+ fecparam->fec = 0;
1466
+ fec_cfg = abilities.fec_cfg_curr_mod_ext_info;
1467
+ if (fec_cfg & I40E_AQ_SET_FEC_AUTO)
1468
+ fecparam->fec |= ETHTOOL_FEC_AUTO;
1469
+ else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_RS |
1470
+ I40E_AQ_SET_FEC_ABILITY_RS))
1471
+ fecparam->fec |= ETHTOOL_FEC_RS;
1472
+ else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_KR |
1473
+ I40E_AQ_SET_FEC_ABILITY_KR))
1474
+ fecparam->fec |= ETHTOOL_FEC_BASER;
1475
+ if (fec_cfg == 0)
1476
+ fecparam->fec |= ETHTOOL_FEC_OFF;
1477
+
1478
+ if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_KR_ENA)
1479
+ fecparam->active_fec = ETHTOOL_FEC_BASER;
1480
+ else if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_RS_ENA)
1481
+ fecparam->active_fec = ETHTOOL_FEC_RS;
1482
+ else
1483
+ fecparam->active_fec = ETHTOOL_FEC_OFF;
1484
+done:
1485
+ return err;
1486
+}
1487
+
1488
+static int i40e_set_fec_param(struct net_device *netdev,
1489
+ struct ethtool_fecparam *fecparam)
1490
+{
1491
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
1492
+ struct i40e_pf *pf = np->vsi->back;
1493
+ struct i40e_hw *hw = &pf->hw;
1494
+ u8 fec_cfg = 0;
1495
+
1496
+ if (hw->device_id != I40E_DEV_ID_25G_SFP28 &&
1497
+ hw->device_id != I40E_DEV_ID_25G_B &&
1498
+ hw->device_id != I40E_DEV_ID_KX_X722)
1499
+ return -EPERM;
1500
+
1501
+ if (hw->mac.type == I40E_MAC_X722 &&
1502
+ !(hw->flags & I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE)) {
1503
+ netdev_err(netdev, "Setting FEC encoding not supported by firmware. Please update the NVM image.\n");
1504
+ return -EOPNOTSUPP;
1505
+ }
1506
+
1507
+ switch (fecparam->fec) {
1508
+ case ETHTOOL_FEC_AUTO:
1509
+ fec_cfg = I40E_AQ_SET_FEC_AUTO;
1510
+ break;
1511
+ case ETHTOOL_FEC_RS:
1512
+ fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
1513
+ I40E_AQ_SET_FEC_ABILITY_RS);
1514
+ break;
1515
+ case ETHTOOL_FEC_BASER:
1516
+ fec_cfg = (I40E_AQ_SET_FEC_REQUEST_KR |
1517
+ I40E_AQ_SET_FEC_ABILITY_KR);
1518
+ break;
1519
+ case ETHTOOL_FEC_OFF:
1520
+ case ETHTOOL_FEC_NONE:
1521
+ fec_cfg = 0;
1522
+ break;
1523
+ default:
1524
+ dev_warn(&pf->pdev->dev, "Unsupported FEC mode: %d",
1525
+ fecparam->fec);
1526
+ return -EINVAL;
1527
+ }
1528
+
1529
+ return i40e_set_fec_cfg(netdev, fec_cfg);
10621530 }
10631531
10641532 static int i40e_nway_reset(struct net_device *netdev)
....@@ -1176,7 +1644,7 @@
11761644 else if (!pause->rx_pause && !pause->tx_pause)
11771645 hw->fc.requested_mode = I40E_FC_NONE;
11781646 else
1179
- return -EINVAL;
1647
+ return -EINVAL;
11801648
11811649 /* Tell the OS link is going down, the link will go back up when fw
11821650 * says it is ready asynchronously
....@@ -1438,8 +1906,6 @@
14381906 struct i40e_pf *pf = vsi->back;
14391907
14401908 strlcpy(drvinfo->driver, i40e_driver_name, sizeof(drvinfo->driver));
1441
- strlcpy(drvinfo->version, i40e_driver_version_str,
1442
- sizeof(drvinfo->version));
14431909 strlcpy(drvinfo->fw_version, i40e_nvm_version_str(&pf->hw),
14441910 sizeof(drvinfo->fw_version));
14451911 strlcpy(drvinfo->bus_info, pci_name(pf->pdev),
....@@ -1512,6 +1978,13 @@
15121978 (new_rx_count == vsi->rx_rings[0]->count))
15131979 return 0;
15141980
1981
+ /* If there is a AF_XDP page pool attached to any of Rx rings,
1982
+ * disallow changing the number of descriptors -- regardless
1983
+ * if the netdev is running or not.
1984
+ */
1985
+ if (i40e_xsk_any_rx_ring_enabled(vsi))
1986
+ return -EBUSY;
1987
+
15151988 while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
15161989 timeout--;
15171990 if (!timeout)
....@@ -1527,6 +2000,8 @@
15272000 if (i40e_enabled_xdp_vsi(vsi))
15282001 vsi->xdp_rings[i]->count = new_tx_count;
15292002 }
2003
+ vsi->num_tx_desc = new_tx_count;
2004
+ vsi->num_rx_desc = new_rx_count;
15302005 goto done;
15312006 }
15322007
....@@ -1663,6 +2138,8 @@
16632138 rx_rings = NULL;
16642139 }
16652140
2141
+ vsi->num_tx_desc = new_tx_count;
2142
+ vsi->num_rx_desc = new_rx_count;
16662143 i40e_up(vsi);
16672144
16682145 free_tx:
....@@ -1701,11 +2178,30 @@
17012178 struct i40e_netdev_priv *np = netdev_priv(netdev);
17022179 struct i40e_vsi *vsi = np->vsi;
17032180 struct i40e_pf *pf = vsi->back;
2181
+ int stats_len;
17042182
17052183 if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1)
1706
- return I40E_PF_STATS_LEN(netdev);
2184
+ stats_len = I40E_PF_STATS_LEN;
17072185 else
1708
- return I40E_VSI_STATS_LEN(netdev);
2186
+ stats_len = I40E_VSI_STATS_LEN;
2187
+
2188
+ /* The number of stats reported for a given net_device must remain
2189
+ * constant throughout the life of that device.
2190
+ *
2191
+ * This is because the API for obtaining the size, strings, and stats
2192
+ * is spread out over three separate ethtool ioctls. There is no safe
2193
+ * way to lock the number of stats across these calls, so we must
2194
+ * assume that they will never change.
2195
+ *
2196
+ * Due to this, we report the maximum number of queues, even if not
2197
+ * every queue is currently configured. Since we always allocate
2198
+ * queues in pairs, we'll just use netdev->num_tx_queues * 2. This
2199
+ * works because the num_tx_queues is set at device creation and never
2200
+ * changes.
2201
+ */
2202
+ stats_len += I40E_QUEUE_STATS_LEN * 2 * netdev->num_tx_queues;
2203
+
2204
+ return stats_len;
17092205 }
17102206
17112207 static int i40e_get_sset_count(struct net_device *netdev, int sset)
....@@ -1728,87 +2224,27 @@
17282224 }
17292225
17302226 /**
1731
- * i40e_add_one_ethtool_stat - copy the stat into the supplied buffer
1732
- * @data: location to store the stat value
1733
- * @pointer: basis for where to copy from
1734
- * @stat: the stat definition
2227
+ * i40e_get_veb_tc_stats - copy VEB TC statistics to formatted structure
2228
+ * @tc: the TC statistics in VEB structure (veb->tc_stats)
2229
+ * @i: the index of traffic class in (veb->tc_stats) structure to copy
17352230 *
1736
- * Copies the stat data defined by the pointer and stat structure pair into
1737
- * the memory supplied as data. Used to implement i40e_add_ethtool_stats.
1738
- * If the pointer is null, data will be zero'd.
1739
- */
1740
-static inline void
1741
-i40e_add_one_ethtool_stat(u64 *data, void *pointer,
1742
- const struct i40e_stats *stat)
1743
-{
1744
- char *p;
1745
-
1746
- if (!pointer) {
1747
- /* ensure that the ethtool data buffer is zero'd for any stats
1748
- * which don't have a valid pointer.
1749
- */
1750
- *data = 0;
1751
- return;
1752
- }
1753
-
1754
- p = (char *)pointer + stat->stat_offset;
1755
- switch (stat->sizeof_stat) {
1756
- case sizeof(u64):
1757
- *data = *((u64 *)p);
1758
- break;
1759
- case sizeof(u32):
1760
- *data = *((u32 *)p);
1761
- break;
1762
- case sizeof(u16):
1763
- *data = *((u16 *)p);
1764
- break;
1765
- case sizeof(u8):
1766
- *data = *((u8 *)p);
1767
- break;
1768
- default:
1769
- WARN_ONCE(1, "unexpected stat size for %s",
1770
- stat->stat_string);
1771
- *data = 0;
1772
- }
1773
-}
1774
-
1775
-/**
1776
- * __i40e_add_ethtool_stats - copy stats into the ethtool supplied buffer
1777
- * @data: ethtool stats buffer
1778
- * @pointer: location to copy stats from
1779
- * @stats: array of stats to copy
1780
- * @size: the size of the stats definition
1781
- *
1782
- * Copy the stats defined by the stats array using the pointer as a base into
1783
- * the data buffer supplied by ethtool. Updates the data pointer to point to
1784
- * the next empty location for successive calls to __i40e_add_ethtool_stats.
1785
- * If pointer is null, set the data values to zero and update the pointer to
1786
- * skip these stats.
2231
+ * Copy VEB TC statistics from structure of arrays (veb->tc_stats) to
2232
+ * one dimensional structure i40e_cp_veb_tc_stats.
2233
+ * Produce formatted i40e_cp_veb_tc_stats structure of the VEB TC
2234
+ * statistics for the given TC.
17872235 **/
1788
-static inline void
1789
-__i40e_add_ethtool_stats(u64 **data, void *pointer,
1790
- const struct i40e_stats stats[],
1791
- const unsigned int size)
2236
+static struct i40e_cp_veb_tc_stats
2237
+i40e_get_veb_tc_stats(struct i40e_veb_tc_stats *tc, unsigned int i)
17922238 {
1793
- unsigned int i;
2239
+ struct i40e_cp_veb_tc_stats veb_tc = {
2240
+ .tc_rx_packets = tc->tc_rx_packets[i],
2241
+ .tc_rx_bytes = tc->tc_rx_bytes[i],
2242
+ .tc_tx_packets = tc->tc_tx_packets[i],
2243
+ .tc_tx_bytes = tc->tc_tx_bytes[i],
2244
+ };
17942245
1795
- for (i = 0; i < size; i++)
1796
- i40e_add_one_ethtool_stat((*data)++, pointer, &stats[i]);
2246
+ return veb_tc;
17972247 }
1798
-
1799
-/**
1800
- * i40e_add_ethtool_stats - copy stats into ethtool supplied buffer
1801
- * @data: ethtool stats buffer
1802
- * @pointer: location where stats are stored
1803
- * @stats: static const array of stat definitions
1804
- *
1805
- * Macro to ease the use of __i40e_add_ethtool_stats by taking a static
1806
- * constant stats array and passing the ARRAY_SIZE(). This avoids typos by
1807
- * ensuring that we pass the size associated with the given stats array.
1808
- * Assumes that stats is an array.
1809
- **/
1810
-#define i40e_add_ethtool_stats(data, pointer, stats) \
1811
- __i40e_add_ethtool_stats(data, pointer, stats, ARRAY_SIZE(stats))
18122248
18132249 /**
18142250 * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure
....@@ -1853,12 +2289,10 @@
18532289 struct ethtool_stats *stats, u64 *data)
18542290 {
18552291 struct i40e_netdev_priv *np = netdev_priv(netdev);
1856
- struct i40e_ring *tx_ring, *rx_ring;
18572292 struct i40e_vsi *vsi = np->vsi;
18582293 struct i40e_pf *pf = vsi->back;
1859
- struct i40e_veb *veb = pf->veb[pf->lan_veb];
2294
+ struct i40e_veb *veb = NULL;
18602295 unsigned int i;
1861
- unsigned int start;
18622296 bool veb_stats;
18632297 u64 *p = data;
18642298
....@@ -1870,43 +2304,23 @@
18702304 i40e_add_ethtool_stats(&data, vsi, i40e_gstrings_misc_stats);
18712305
18722306 rcu_read_lock();
1873
- for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev) ; i++) {
1874
- tx_ring = READ_ONCE(vsi->tx_rings[i]);
1875
-
1876
- if (!tx_ring) {
1877
- /* Bump the stat counter to skip these stats, and make
1878
- * sure the memory is zero'd
1879
- */
1880
- *(data++) = 0;
1881
- *(data++) = 0;
1882
- *(data++) = 0;
1883
- *(data++) = 0;
1884
- continue;
1885
- }
1886
-
1887
- /* process Tx ring statistics */
1888
- do {
1889
- start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
1890
- data[0] = tx_ring->stats.packets;
1891
- data[1] = tx_ring->stats.bytes;
1892
- } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
1893
- data += 2;
1894
-
1895
- /* Rx ring is the 2nd half of the queue pair */
1896
- rx_ring = &tx_ring[1];
1897
- do {
1898
- start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
1899
- data[0] = rx_ring->stats.packets;
1900
- data[1] = rx_ring->stats.bytes;
1901
- } while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
1902
- data += 2;
2307
+ for (i = 0; i < netdev->num_tx_queues; i++) {
2308
+ i40e_add_queue_stats(&data, READ_ONCE(vsi->tx_rings[i]));
2309
+ i40e_add_queue_stats(&data, READ_ONCE(vsi->rx_rings[i]));
19032310 }
19042311 rcu_read_unlock();
2312
+
19052313 if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
19062314 goto check_data_pointer;
19072315
19082316 veb_stats = ((pf->lan_veb != I40E_NO_VEB) &&
2317
+ (pf->lan_veb < I40E_MAX_VEB) &&
19092318 (pf->flags & I40E_FLAG_VEB_STATS_ENABLED));
2319
+
2320
+ if (veb_stats) {
2321
+ veb = pf->veb[pf->lan_veb];
2322
+ i40e_update_veb_stats(veb);
2323
+ }
19102324
19112325 /* If veb stats aren't enabled, pass NULL instead of the veb so that
19122326 * we initialize stats to zero and update the data pointer
....@@ -1916,8 +2330,16 @@
19162330 i40e_gstrings_veb_stats);
19172331
19182332 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1919
- i40e_add_ethtool_stats(&data, veb_stats ? veb : NULL,
1920
- i40e_gstrings_veb_tc_stats);
2333
+ if (veb_stats) {
2334
+ struct i40e_cp_veb_tc_stats veb_tc =
2335
+ i40e_get_veb_tc_stats(&veb->tc_stats, i);
2336
+
2337
+ i40e_add_ethtool_stats(&data, &veb_tc,
2338
+ i40e_gstrings_veb_tc_stats);
2339
+ } else {
2340
+ i40e_add_ethtool_stats(&data, NULL,
2341
+ i40e_gstrings_veb_tc_stats);
2342
+ }
19212343
19222344 i40e_add_ethtool_stats(&data, pf, i40e_gstrings_stats);
19232345
....@@ -1931,42 +2353,6 @@
19312353 WARN_ONCE(data - p != i40e_get_stats_count(netdev),
19322354 "ethtool stats count mismatch!");
19332355 }
1934
-
1935
-/**
1936
- * __i40e_add_stat_strings - copy stat strings into ethtool buffer
1937
- * @p: ethtool supplied buffer
1938
- * @stats: stat definitions array
1939
- * @size: size of the stats array
1940
- *
1941
- * Format and copy the strings described by stats into the buffer pointed at
1942
- * by p.
1943
- **/
1944
-static void __i40e_add_stat_strings(u8 **p, const struct i40e_stats stats[],
1945
- const unsigned int size, ...)
1946
-{
1947
- unsigned int i;
1948
-
1949
- for (i = 0; i < size; i++) {
1950
- va_list args;
1951
-
1952
- va_start(args, size);
1953
- vsnprintf(*p, ETH_GSTRING_LEN, stats[i].stat_string, args);
1954
- *p += ETH_GSTRING_LEN;
1955
- va_end(args);
1956
- }
1957
-}
1958
-
1959
-/**
1960
- * 40e_add_stat_strings - copy stat strings into ethtool buffer
1961
- * @p: ethtool supplied buffer
1962
- * @stats: stat definitions array
1963
- *
1964
- * Format and copy the strings described by the const static stats value into
1965
- * the buffer pointed at by p. Assumes that stats can have ARRAY_SIZE called
1966
- * for it.
1967
- **/
1968
-#define i40e_add_stat_strings(p, stats, ...) \
1969
- __i40e_add_stat_strings(p, stats, ARRAY_SIZE(stats), ## __VA_ARGS__)
19702356
19712357 /**
19722358 * i40e_get_stat_strings - copy stat strings into supplied buffer
....@@ -1990,18 +2376,15 @@
19902376
19912377 i40e_add_stat_strings(&data, i40e_gstrings_misc_stats);
19922378
1993
- for (i = 0; i < I40E_MAX_NUM_QUEUES(netdev); i++) {
1994
- snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
1995
- data += ETH_GSTRING_LEN;
1996
- snprintf(data, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i);
1997
- data += ETH_GSTRING_LEN;
1998
- snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_packets", i);
1999
- data += ETH_GSTRING_LEN;
2000
- snprintf(data, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
2001
- data += ETH_GSTRING_LEN;
2379
+ for (i = 0; i < netdev->num_tx_queues; i++) {
2380
+ i40e_add_stat_strings(&data, i40e_gstrings_queue_stats,
2381
+ "tx", i);
2382
+ i40e_add_stat_strings(&data, i40e_gstrings_queue_stats,
2383
+ "rx", i);
20022384 }
2385
+
20032386 if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
2004
- return;
2387
+ goto check_data_pointer;
20052388
20062389 i40e_add_stat_strings(&data, i40e_gstrings_veb_stats);
20072390
....@@ -2013,6 +2396,7 @@
20132396 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
20142397 i40e_add_stat_strings(&data, i40e_gstrings_pfc_stats, i);
20152398
2399
+check_data_pointer:
20162400 WARN_ONCE(data - p != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
20172401 "stat strings count mismatch!");
20182402 }
....@@ -2099,7 +2483,7 @@
20992483 return 0;
21002484 }
21012485
2102
-static int i40e_link_test(struct net_device *netdev, u64 *data)
2486
+static u64 i40e_link_test(struct net_device *netdev, u64 *data)
21032487 {
21042488 struct i40e_netdev_priv *np = netdev_priv(netdev);
21052489 struct i40e_pf *pf = np->vsi->back;
....@@ -2122,7 +2506,7 @@
21222506 return *data;
21232507 }
21242508
2125
-static int i40e_reg_test(struct net_device *netdev, u64 *data)
2509
+static u64 i40e_reg_test(struct net_device *netdev, u64 *data)
21262510 {
21272511 struct i40e_netdev_priv *np = netdev_priv(netdev);
21282512 struct i40e_pf *pf = np->vsi->back;
....@@ -2133,7 +2517,7 @@
21332517 return *data;
21342518 }
21352519
2136
-static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
2520
+static u64 i40e_eeprom_test(struct net_device *netdev, u64 *data)
21372521 {
21382522 struct i40e_netdev_priv *np = netdev_priv(netdev);
21392523 struct i40e_pf *pf = np->vsi->back;
....@@ -2147,7 +2531,7 @@
21472531 return *data;
21482532 }
21492533
2150
-static int i40e_intr_test(struct net_device *netdev, u64 *data)
2534
+static u64 i40e_intr_test(struct net_device *netdev, u64 *data)
21512535 {
21522536 struct i40e_netdev_priv *np = netdev_priv(netdev);
21532537 struct i40e_pf *pf = np->vsi->back;
....@@ -2195,15 +2579,16 @@
21952579
21962580 set_bit(__I40E_TESTING, pf->state);
21972581
2582
+ if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) ||
2583
+ test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) {
2584
+ dev_warn(&pf->pdev->dev,
2585
+ "Cannot start offline testing when PF is in reset state.\n");
2586
+ goto skip_ol_tests;
2587
+ }
2588
+
21982589 if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) {
21992590 dev_warn(&pf->pdev->dev,
22002591 "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n");
2201
- data[I40E_ETH_TEST_REG] = 1;
2202
- data[I40E_ETH_TEST_EEPROM] = 1;
2203
- data[I40E_ETH_TEST_INTR] = 1;
2204
- data[I40E_ETH_TEST_LINK] = 1;
2205
- eth_test->flags |= ETH_TEST_FL_FAILED;
2206
- clear_bit(__I40E_TESTING, pf->state);
22072592 goto skip_ol_tests;
22082593 }
22092594
....@@ -2250,9 +2635,17 @@
22502635 data[I40E_ETH_TEST_INTR] = 0;
22512636 }
22522637
2253
-skip_ol_tests:
2254
-
22552638 netif_info(pf, drv, netdev, "testing finished\n");
2639
+ return;
2640
+
2641
+skip_ol_tests:
2642
+ data[I40E_ETH_TEST_REG] = 1;
2643
+ data[I40E_ETH_TEST_EEPROM] = 1;
2644
+ data[I40E_ETH_TEST_INTR] = 1;
2645
+ data[I40E_ETH_TEST_LINK] = 1;
2646
+ eth_test->flags |= ETH_TEST_FL_FAILED;
2647
+ clear_bit(__I40E_TESTING, pf->state);
2648
+ netif_info(pf, drv, netdev, "testing failed\n");
22562649 }
22572650
22582651 static void i40e_get_wol(struct net_device *netdev,
....@@ -2302,7 +2695,7 @@
23022695 return -EOPNOTSUPP;
23032696
23042697 /* only magic packet is supported */
2305
- if (wol->wolopts && (wol->wolopts != WAKE_MAGIC))
2698
+ if (wol->wolopts & ~WAKE_MAGIC)
23062699 return -EOPNOTSUPP;
23072700
23082701 /* is this a new value? */
....@@ -2363,10 +2756,10 @@
23632756 default:
23642757 break;
23652758 }
2366
- if (ret)
2367
- return -ENOENT;
2368
- else
2369
- return 0;
2759
+ if (ret)
2760
+ return -ENOENT;
2761
+ else
2762
+ return 0;
23702763 }
23712764
23722765 /* NOTE: i40e hardware uses a conversion factor of 2 for Interrupt
....@@ -2690,10 +3083,17 @@
26903083
26913084 if (cmd->flow_type == TCP_V4_FLOW ||
26923085 cmd->flow_type == UDP_V4_FLOW) {
2693
- if (i_set & I40E_L3_SRC_MASK)
2694
- cmd->data |= RXH_IP_SRC;
2695
- if (i_set & I40E_L3_DST_MASK)
2696
- cmd->data |= RXH_IP_DST;
3086
+ if (hw->mac.type == I40E_MAC_X722) {
3087
+ if (i_set & I40E_X722_L3_SRC_MASK)
3088
+ cmd->data |= RXH_IP_SRC;
3089
+ if (i_set & I40E_X722_L3_DST_MASK)
3090
+ cmd->data |= RXH_IP_DST;
3091
+ } else {
3092
+ if (i_set & I40E_L3_SRC_MASK)
3093
+ cmd->data |= RXH_IP_SRC;
3094
+ if (i_set & I40E_L3_DST_MASK)
3095
+ cmd->data |= RXH_IP_DST;
3096
+ }
26973097 } else if (cmd->flow_type == TCP_V6_FLOW ||
26983098 cmd->flow_type == UDP_V6_FLOW) {
26993099 if (i_set & I40E_L3_V6_SRC_MASK)
....@@ -3000,12 +3400,15 @@
30003400
30013401 /**
30023402 * i40e_get_rss_hash_bits - Read RSS Hash bits from register
3403
+ * @hw: hw structure
30033404 * @nfc: pointer to user request
30043405 * @i_setc: bits currently set
30053406 *
30063407 * Returns value of bits to be set per user request
30073408 **/
3008
-static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
3409
+static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
3410
+ struct ethtool_rxnfc *nfc,
3411
+ u64 i_setc)
30093412 {
30103413 u64 i_set = i_setc;
30113414 u64 src_l3 = 0, dst_l3 = 0;
....@@ -3024,8 +3427,13 @@
30243427 dst_l3 = I40E_L3_V6_DST_MASK;
30253428 } else if (nfc->flow_type == TCP_V4_FLOW ||
30263429 nfc->flow_type == UDP_V4_FLOW) {
3027
- src_l3 = I40E_L3_SRC_MASK;
3028
- dst_l3 = I40E_L3_DST_MASK;
3430
+ if (hw->mac.type == I40E_MAC_X722) {
3431
+ src_l3 = I40E_X722_L3_SRC_MASK;
3432
+ dst_l3 = I40E_X722_L3_DST_MASK;
3433
+ } else {
3434
+ src_l3 = I40E_L3_SRC_MASK;
3435
+ dst_l3 = I40E_L3_DST_MASK;
3436
+ }
30293437 } else {
30303438 /* Any other flow type are not supported here */
30313439 return i_set;
....@@ -3043,6 +3451,7 @@
30433451 return i_set;
30443452 }
30453453
3454
+#define FLOW_PCTYPES_SIZE 64
30463455 /**
30473456 * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
30483457 * @pf: pointer to the physical function struct
....@@ -3055,8 +3464,10 @@
30553464 struct i40e_hw *hw = &pf->hw;
30563465 u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
30573466 ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
3058
- u8 flow_pctype = 0;
3467
+ DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
30593468 u64 i_set, i_setc;
3469
+
3470
+ bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
30603471
30613472 if (pf->flags & I40E_FLAG_MFP_ENABLED) {
30623473 dev_err(&pf->pdev->dev,
....@@ -3073,36 +3484,35 @@
30733484
30743485 switch (nfc->flow_type) {
30753486 case TCP_V4_FLOW:
3076
- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
3487
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
30773488 if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
3078
- hena |=
3079
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
3489
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
3490
+ flow_pctypes);
30803491 break;
30813492 case TCP_V6_FLOW:
3082
- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
3493
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
30833494 if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
3084
- hena |=
3085
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
3086
- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
3087
- hena |=
3088
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
3495
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
3496
+ flow_pctypes);
30893497 break;
30903498 case UDP_V4_FLOW:
3091
- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
3092
- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
3093
- hena |=
3094
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
3095
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
3096
-
3499
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
3500
+ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
3501
+ set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
3502
+ flow_pctypes);
3503
+ set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
3504
+ flow_pctypes);
3505
+ }
30973506 hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
30983507 break;
30993508 case UDP_V6_FLOW:
3100
- flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
3101
- if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
3102
- hena |=
3103
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
3104
- BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
3105
-
3509
+ set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
3510
+ if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
3511
+ set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
3512
+ flow_pctypes);
3513
+ set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
3514
+ flow_pctypes);
3515
+ }
31063516 hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
31073517 break;
31083518 case AH_ESP_V4_FLOW:
....@@ -3135,17 +3545,20 @@
31353545 return -EINVAL;
31363546 }
31373547
3138
- if (flow_pctype) {
3139
- i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
3140
- flow_pctype)) |
3141
- ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
3142
- flow_pctype)) << 32);
3143
- i_set = i40e_get_rss_hash_bits(nfc, i_setc);
3144
- i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
3145
- (u32)i_set);
3146
- i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
3147
- (u32)(i_set >> 32));
3148
- hena |= BIT_ULL(flow_pctype);
3548
+ if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
3549
+ u8 flow_id;
3550
+
3551
+ for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
3552
+ i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
3553
+ ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
3554
+ i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
3555
+
3556
+ i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
3557
+ (u32)i_set);
3558
+ i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
3559
+ (u32)(i_set >> 32));
3560
+ hena |= BIT_ULL(flow_id);
3561
+ }
31493562 }
31503563
31513564 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
....@@ -3759,7 +4172,7 @@
37594172 switch (fsp->flow_type & ~FLOW_EXT) {
37604173 case SCTP_V4_FLOW:
37614174 new_mask &= ~I40E_VERIFY_TAG_MASK;
3762
- /* Fall through */
4175
+ fallthrough;
37634176 case TCP_V4_FLOW:
37644177 case UDP_V4_FLOW:
37654178 tcp_ip4_spec = &fsp->m_u.tcp_ip4_spec;
....@@ -3821,11 +4234,7 @@
38214234 return -EOPNOTSUPP;
38224235
38234236 /* First 4 bytes of L4 header */
3824
- if (usr_ip4_spec->l4_4_bytes == htonl(0xFFFFFFFF))
3825
- new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
3826
- else if (!usr_ip4_spec->l4_4_bytes)
3827
- new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
3828
- else
4237
+ if (usr_ip4_spec->l4_4_bytes)
38294238 return -EOPNOTSUPP;
38304239
38314240 /* Filtering on Type of Service is not supported. */
....@@ -4528,9 +4937,12 @@
45284937 static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
45294938 {
45304939 struct i40e_netdev_priv *np = netdev_priv(dev);
4940
+ u64 orig_flags, new_flags, changed_flags;
4941
+ enum i40e_admin_queue_err adq_err;
45314942 struct i40e_vsi *vsi = np->vsi;
45324943 struct i40e_pf *pf = vsi->back;
4533
- u64 orig_flags, new_flags, changed_flags;
4944
+ u32 reset_needed = 0;
4945
+ i40e_status status;
45344946 u32 i, j;
45354947
45364948 orig_flags = READ_ONCE(pf->flags);
....@@ -4574,6 +4986,12 @@
45744986 flags_complete:
45754987 changed_flags = orig_flags ^ new_flags;
45764988
4989
+ if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP)
4990
+ reset_needed = I40E_PF_RESET_AND_REBUILD_FLAG;
4991
+ if (changed_flags & (I40E_FLAG_VEB_STATS_ENABLED |
4992
+ I40E_FLAG_LEGACY_RX | I40E_FLAG_SOURCE_PRUNING_DISABLED))
4993
+ reset_needed = BIT(__I40E_PF_RESET_REQUESTED);
4994
+
45774995 /* Before we finalize any flag changes, we need to perform some
45784996 * checks to ensure that the changes are supported and safe.
45794997 */
....@@ -4584,26 +5002,37 @@
45845002 return -EOPNOTSUPP;
45855003
45865004 /* If the driver detected FW LLDP was disabled on init, this flag could
4587
- * be set, however we do not support _changing_ the flag if NPAR is
4588
- * enabled or FW API version < 1.7. There are situations where older
4589
- * FW versions/NPAR enabled PFs could disable LLDP, however we _must_
4590
- * not allow the user to enable/disable LLDP with this flag on
4591
- * unsupported FW versions.
5005
+ * be set, however we do not support _changing_ the flag:
5006
+ * - on XL710 if NPAR is enabled or FW API version < 1.7
5007
+ * - on X722 with FW API version < 1.6
5008
+ * There are situations where older FW versions/NPAR enabled PFs could
5009
+ * disable LLDP, however we _must_ not allow the user to enable/disable
5010
+ * LLDP with this flag on unsupported FW versions.
45925011 */
45935012 if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
4594
- if (!(pf->hw_features & I40E_HW_STOPPABLE_FW_LLDP)) {
5013
+ if (!(pf->hw.flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE)) {
45955014 dev_warn(&pf->pdev->dev,
45965015 "Device does not support changing FW LLDP\n");
45975016 return -EOPNOTSUPP;
45985017 }
45995018 }
46005019
4601
- /* Now that we've checked to ensure that the new flags are valid, load
4602
- * them into place. Since we only modify flags either (a) during
4603
- * initialization or (b) while holding the RTNL lock, we don't need
4604
- * anything fancy here.
4605
- */
4606
- pf->flags = new_flags;
5020
+ if (changed_flags & I40E_FLAG_RS_FEC &&
5021
+ pf->hw.device_id != I40E_DEV_ID_25G_SFP28 &&
5022
+ pf->hw.device_id != I40E_DEV_ID_25G_B) {
5023
+ dev_warn(&pf->pdev->dev,
5024
+ "Device does not support changing FEC configuration\n");
5025
+ return -EOPNOTSUPP;
5026
+ }
5027
+
5028
+ if (changed_flags & I40E_FLAG_BASE_R_FEC &&
5029
+ pf->hw.device_id != I40E_DEV_ID_25G_SFP28 &&
5030
+ pf->hw.device_id != I40E_DEV_ID_25G_B &&
5031
+ pf->hw.device_id != I40E_DEV_ID_KX_X722) {
5032
+ dev_warn(&pf->pdev->dev,
5033
+ "Device does not support changing FEC configuration\n");
5034
+ return -EOPNOTSUPP;
5035
+ }
46075036
46085037 /* Process any additional changes needed as a result of flag changes.
46095038 * The changed_flags value reflects the list of bits that were
....@@ -4612,7 +5041,7 @@
46125041
46135042 /* Flush current ATR settings if ATR was disabled */
46145043 if ((changed_flags & I40E_FLAG_FD_ATR_ENABLED) &&
4615
- !(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) {
5044
+ !(new_flags & I40E_FLAG_FD_ATR_ENABLED)) {
46165045 set_bit(__I40E_FD_ATR_AUTO_DISABLED, pf->state);
46175046 set_bit(__I40E_FD_FLUSH_REQUESTED, pf->state);
46185047 }
....@@ -4621,7 +5050,7 @@
46215050 u16 sw_flags = 0, valid_flags = 0;
46225051 int ret;
46235052
4624
- if (!(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
5053
+ if (!(new_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
46255054 sw_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
46265055 valid_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
46275056 ret = i40e_aq_set_switch_config(&pf->hw, sw_flags, valid_flags,
....@@ -4636,17 +5065,42 @@
46365065 }
46375066 }
46385067
4639
- if ((changed_flags & pf->flags &
5068
+ if ((changed_flags & I40E_FLAG_RS_FEC) ||
5069
+ (changed_flags & I40E_FLAG_BASE_R_FEC)) {
5070
+ u8 fec_cfg = 0;
5071
+
5072
+ if (new_flags & I40E_FLAG_RS_FEC &&
5073
+ new_flags & I40E_FLAG_BASE_R_FEC) {
5074
+ fec_cfg = I40E_AQ_SET_FEC_AUTO;
5075
+ } else if (new_flags & I40E_FLAG_RS_FEC) {
5076
+ fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
5077
+ I40E_AQ_SET_FEC_ABILITY_RS);
5078
+ } else if (new_flags & I40E_FLAG_BASE_R_FEC) {
5079
+ fec_cfg = (I40E_AQ_SET_FEC_REQUEST_KR |
5080
+ I40E_AQ_SET_FEC_ABILITY_KR);
5081
+ }
5082
+ if (i40e_set_fec_cfg(dev, fec_cfg))
5083
+ dev_warn(&pf->pdev->dev, "Cannot change FEC config\n");
5084
+ }
5085
+
5086
+ if ((changed_flags & I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
5087
+ (orig_flags & I40E_FLAG_TOTAL_PORT_SHUTDOWN_ENABLED)) {
5088
+ dev_err(&pf->pdev->dev,
5089
+ "Setting link-down-on-close not supported on this port (because total-port-shutdown is enabled)\n");
5090
+ return -EOPNOTSUPP;
5091
+ }
5092
+
5093
+ if ((changed_flags & new_flags &
46405094 I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
4641
- (pf->flags & I40E_FLAG_MFP_ENABLED))
5095
+ (new_flags & I40E_FLAG_MFP_ENABLED))
46425096 dev_warn(&pf->pdev->dev,
46435097 "Turning on link-down-on-close flag may affect other partitions\n");
46445098
46455099 if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
4646
- if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
5100
+ if (new_flags & I40E_FLAG_DISABLE_FW_LLDP) {
46475101 struct i40e_dcbx_config *dcbcfg;
46485102
4649
- i40e_aq_stop_lldp(&pf->hw, true, NULL);
5103
+ i40e_aq_stop_lldp(&pf->hw, true, false, NULL);
46505104 i40e_aq_set_dcb_parameters(&pf->hw, true, NULL);
46515105 /* reset local_dcbx_config to default */
46525106 dcbcfg = &pf->hw.local_dcbx_config;
....@@ -4661,18 +5115,48 @@
46615115 dcbcfg->pfc.willing = 1;
46625116 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
46635117 } else {
4664
- i40e_aq_start_lldp(&pf->hw, NULL);
5118
+ status = i40e_aq_start_lldp(&pf->hw, false, NULL);
5119
+ if (status) {
5120
+ adq_err = pf->hw.aq.asq_last_status;
5121
+ switch (adq_err) {
5122
+ case I40E_AQ_RC_EEXIST:
5123
+ dev_warn(&pf->pdev->dev,
5124
+ "FW LLDP agent is already running\n");
5125
+ reset_needed = 0;
5126
+ break;
5127
+ case I40E_AQ_RC_EPERM:
5128
+ dev_warn(&pf->pdev->dev,
5129
+ "Device configuration forbids SW from starting the LLDP agent.\n");
5130
+ return -EINVAL;
5131
+ case I40E_AQ_RC_EAGAIN:
5132
+ dev_warn(&pf->pdev->dev,
5133
+ "Stop FW LLDP agent command is still being processed, please try again in a second.\n");
5134
+ return -EBUSY;
5135
+ default:
5136
+ dev_warn(&pf->pdev->dev,
5137
+ "Starting FW LLDP agent failed: error: %s, %s\n",
5138
+ i40e_stat_str(&pf->hw,
5139
+ status),
5140
+ i40e_aq_str(&pf->hw,
5141
+ adq_err));
5142
+ return -EINVAL;
5143
+ }
5144
+ }
46655145 }
46665146 }
5147
+
5148
+ /* Now that we've checked to ensure that the new flags are valid, load
5149
+ * them into place. Since we only modify flags either (a) during
5150
+ * initialization or (b) while holding the RTNL lock, we don't need
5151
+ * anything fancy here.
5152
+ */
5153
+ pf->flags = new_flags;
46675154
46685155 /* Issue reset to cause things to take effect, as additional bits
46695156 * are added we will need to create a mask of bits requiring reset
46705157 */
4671
- if (changed_flags & (I40E_FLAG_VEB_STATS_ENABLED |
4672
- I40E_FLAG_LEGACY_RX |
4673
- I40E_FLAG_SOURCE_PRUNING_DISABLED |
4674
- I40E_FLAG_DISABLE_FW_LLDP))
4675
- i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true);
5158
+ if (reset_needed)
5159
+ i40e_do_reset(pf, reset_needed, true);
46765160
46775161 return 0;
46785162 }
....@@ -4716,7 +5200,7 @@
47165200 case I40E_MODULE_TYPE_SFP:
47175201 status = i40e_aq_get_phy_register(hw,
47185202 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
4719
- I40E_I2C_EEPROM_DEV_ADDR,
5203
+ I40E_I2C_EEPROM_DEV_ADDR, true,
47205204 I40E_MODULE_SFF_8472_COMP,
47215205 &sff8472_comp, NULL);
47225206 if (status)
....@@ -4724,7 +5208,7 @@
47245208
47255209 status = i40e_aq_get_phy_register(hw,
47265210 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
4727
- I40E_I2C_EEPROM_DEV_ADDR,
5211
+ I40E_I2C_EEPROM_DEV_ADDR, true,
47285212 I40E_MODULE_SFF_8472_SWAP,
47295213 &sff8472_swap, NULL);
47305214 if (status)
....@@ -4741,6 +5225,12 @@
47415225 /* Module is not SFF-8472 compliant */
47425226 modinfo->type = ETH_MODULE_SFF_8079;
47435227 modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
5228
+ } else if (!(sff8472_swap & I40E_MODULE_SFF_DDM_IMPLEMENTED)) {
5229
+ /* Module is SFF-8472 compliant but doesn't implement
5230
+ * Digital Diagnostic Monitoring (DDM).
5231
+ */
5232
+ modinfo->type = ETH_MODULE_SFF_8079;
5233
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
47445234 } else {
47455235 modinfo->type = ETH_MODULE_SFF_8472;
47465236 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
....@@ -4750,7 +5240,7 @@
47505240 /* Read from memory page 0. */
47515241 status = i40e_aq_get_phy_register(hw,
47525242 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
4753
- 0,
5243
+ 0, true,
47545244 I40E_MODULE_REVISION_ADDR,
47555245 &sff8636_rev, NULL);
47565246 if (status)
....@@ -4821,7 +5311,7 @@
48215311
48225312 status = i40e_aq_get_phy_register(hw,
48235313 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
4824
- addr, offset, &value, NULL);
5314
+ addr, true, offset, &value, NULL);
48255315 if (status)
48265316 return -EIO;
48275317 data[i] = value;
....@@ -4829,7 +5319,29 @@
48295319 return 0;
48305320 }
48315321
5322
+static int i40e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
5323
+{
5324
+ return -EOPNOTSUPP;
5325
+}
5326
+
5327
+static int i40e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
5328
+{
5329
+ return -EOPNOTSUPP;
5330
+}
5331
+
5332
+static const struct ethtool_ops i40e_ethtool_recovery_mode_ops = {
5333
+ .get_drvinfo = i40e_get_drvinfo,
5334
+ .set_eeprom = i40e_set_eeprom,
5335
+ .get_eeprom_len = i40e_get_eeprom_len,
5336
+ .get_eeprom = i40e_get_eeprom,
5337
+};
5338
+
48325339 static const struct ethtool_ops i40e_ethtool_ops = {
5340
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
5341
+ ETHTOOL_COALESCE_MAX_FRAMES_IRQ |
5342
+ ETHTOOL_COALESCE_USE_ADAPTIVE |
5343
+ ETHTOOL_COALESCE_RX_USECS_HIGH |
5344
+ ETHTOOL_COALESCE_TX_USECS_HIGH,
48335345 .get_drvinfo = i40e_get_drvinfo,
48345346 .get_regs_len = i40e_get_regs_len,
48355347 .get_regs = i40e_get_regs,
....@@ -4850,6 +5362,8 @@
48505362 .set_rxnfc = i40e_set_rxnfc,
48515363 .self_test = i40e_diag_test,
48525364 .get_strings = i40e_get_strings,
5365
+ .get_eee = i40e_get_eee,
5366
+ .set_eee = i40e_set_eee,
48535367 .set_phys_id = i40e_set_phys_id,
48545368 .get_sset_count = i40e_get_sset_count,
48555369 .get_ethtool_stats = i40e_get_ethtool_stats,
....@@ -4870,9 +5384,18 @@
48705384 .set_per_queue_coalesce = i40e_set_per_queue_coalesce,
48715385 .get_link_ksettings = i40e_get_link_ksettings,
48725386 .set_link_ksettings = i40e_set_link_ksettings,
5387
+ .get_fecparam = i40e_get_fec_param,
5388
+ .set_fecparam = i40e_set_fec_param,
5389
+ .flash_device = i40e_ddp_flash,
48735390 };
48745391
48755392 void i40e_set_ethtool_ops(struct net_device *netdev)
48765393 {
4877
- netdev->ethtool_ops = &i40e_ethtool_ops;
5394
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
5395
+ struct i40e_pf *pf = np->vsi->back;
5396
+
5397
+ if (!test_bit(__I40E_RECOVERY_MODE, pf->state))
5398
+ netdev->ethtool_ops = &i40e_ethtool_ops;
5399
+ else
5400
+ netdev->ethtool_ops = &i40e_ethtool_recovery_mode_ops;
48785401 }