1/* Broadcom NetXtreme-C/E network driver.
2 *
3 * Copyright (c) 2014-2016 Broadcom Corporation
4 * Copyright (c) 2016-2017 Broadcom Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
9 */
10
11#include <linux/bitops.h>
12#include <linux/ctype.h>
13#include <linux/stringify.h>
14#include <linux/ethtool.h>
15#include <linux/ethtool_netlink.h>
16#include <linux/linkmode.h>
17#include <linux/interrupt.h>
18#include <linux/pci.h>
19#include <linux/etherdevice.h>
20#include <linux/crc32.h>
21#include <linux/firmware.h>
22#include <linux/utsname.h>
23#include <linux/time.h>
24#include <linux/ptp_clock_kernel.h>
25#include <linux/net_tstamp.h>
26#include <linux/timecounter.h>
27#include <net/netlink.h>
28#include "bnxt_hsi.h"
29#include "bnxt.h"
30#include "bnxt_hwrm.h"
31#include "bnxt_ulp.h"
32#include "bnxt_xdp.h"
33#include "bnxt_ptp.h"
34#include "bnxt_ethtool.h"
35#include "bnxt_nvm_defs.h" /* NVRAM content constant and structure defs */
36#include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */
37#include "bnxt_coredump.h"
38
39#define BNXT_NVM_ERR_MSG(dev, extack, msg) \
40 do { \
41 if (extack) \
42 NL_SET_ERR_MSG_MOD(extack, msg); \
43 netdev_err(dev, "%s\n", msg); \
44 } while (0)
45
46static u32 bnxt_get_msglevel(struct net_device *dev)
47{
48 struct bnxt *bp = netdev_priv(dev);
49
50 return bp->msg_enable;
51}
52
53static void bnxt_set_msglevel(struct net_device *dev, u32 value)
54{
55 struct bnxt *bp = netdev_priv(dev);
56
57 bp->msg_enable = value;
58}
59
60static int bnxt_get_coalesce(struct net_device *dev,
61 struct ethtool_coalesce *coal,
62 struct kernel_ethtool_coalesce *kernel_coal,
63 struct netlink_ext_ack *extack)
64{
65 struct bnxt *bp = netdev_priv(dev);
66 struct bnxt_coal *hw_coal;
67 u16 mult;
68
69 memset(coal, 0, sizeof(*coal));
70
71 coal->use_adaptive_rx_coalesce = bp->flags & BNXT_FLAG_DIM;
72
73 hw_coal = &bp->rx_coal;
74 mult = hw_coal->bufs_per_record;
75 coal->rx_coalesce_usecs = hw_coal->coal_ticks;
76 coal->rx_max_coalesced_frames = hw_coal->coal_bufs / mult;
77 coal->rx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
78 coal->rx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;
79 if (hw_coal->flags &
80 RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET)
81 kernel_coal->use_cqe_mode_rx = true;
82
83 hw_coal = &bp->tx_coal;
84 mult = hw_coal->bufs_per_record;
85 coal->tx_coalesce_usecs = hw_coal->coal_ticks;
86 coal->tx_max_coalesced_frames = hw_coal->coal_bufs / mult;
87 coal->tx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
88 coal->tx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;
89 if (hw_coal->flags &
90 RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET)
91 kernel_coal->use_cqe_mode_tx = true;
92
93 coal->stats_block_coalesce_usecs = bp->stats_coal_ticks;
94
95 return 0;
96}
97
98static int bnxt_set_coalesce(struct net_device *dev,
99 struct ethtool_coalesce *coal,
100 struct kernel_ethtool_coalesce *kernel_coal,
101 struct netlink_ext_ack *extack)
102{
103 struct bnxt *bp = netdev_priv(dev);
104 bool update_stats = false;
105 struct bnxt_coal *hw_coal;
106 int rc = 0;
107 u16 mult;
108
109 if (coal->use_adaptive_rx_coalesce) {
110 bp->flags |= BNXT_FLAG_DIM;
111 } else {
112 if (bp->flags & BNXT_FLAG_DIM) {
113 bp->flags &= ~(BNXT_FLAG_DIM);
114 goto reset_coalesce;
115 }
116 }
117
118 if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) &&
119 !(bp->coal_cap.cmpl_params &
120 RING_AGGINT_QCAPS_RESP_CMPL_PARAMS_TIMER_RESET))
121 return -EOPNOTSUPP;
122
123 hw_coal = &bp->rx_coal;
124 mult = hw_coal->bufs_per_record;
125 hw_coal->coal_ticks = coal->rx_coalesce_usecs;
126 hw_coal->coal_bufs = coal->rx_max_coalesced_frames * mult;
127 hw_coal->coal_ticks_irq = coal->rx_coalesce_usecs_irq;
128 hw_coal->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * mult;
129 hw_coal->flags &=
130 ~RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
131 if (kernel_coal->use_cqe_mode_rx)
132 hw_coal->flags |=
133 RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
134
135 hw_coal = &bp->tx_coal;
136 mult = hw_coal->bufs_per_record;
137 hw_coal->coal_ticks = coal->tx_coalesce_usecs;
138 hw_coal->coal_bufs = coal->tx_max_coalesced_frames * mult;
139 hw_coal->coal_ticks_irq = coal->tx_coalesce_usecs_irq;
140 hw_coal->coal_bufs_irq = coal->tx_max_coalesced_frames_irq * mult;
141 hw_coal->flags &=
142 ~RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
143 if (kernel_coal->use_cqe_mode_tx)
144 hw_coal->flags |=
145 RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
146
147 if (bp->stats_coal_ticks != coal->stats_block_coalesce_usecs) {
148 u32 stats_ticks = coal->stats_block_coalesce_usecs;
149
150 /* Allow 0, which means disable. */
151 if (stats_ticks)
152 stats_ticks = clamp_t(u32, stats_ticks,
153 BNXT_MIN_STATS_COAL_TICKS,
154 BNXT_MAX_STATS_COAL_TICKS);
155 stats_ticks = rounddown(stats_ticks, BNXT_MIN_STATS_COAL_TICKS);
156 bp->stats_coal_ticks = stats_ticks;
157 if (bp->stats_coal_ticks)
158 bp->current_interval =
159 bp->stats_coal_ticks * HZ / 1000000;
160 else
161 bp->current_interval = BNXT_TIMER_INTERVAL;
162 update_stats = true;
163 }
164
165reset_coalesce:
166 if (test_bit(BNXT_STATE_OPEN, &bp->state)) {
167 if (update_stats) {
168 bnxt_close_nic(bp, true, false);
169 rc = bnxt_open_nic(bp, true, false);
170 } else {
171 rc = bnxt_hwrm_set_coal(bp);
172 }
173 }
174
175 return rc;
176}
177
178static const char * const bnxt_ring_rx_stats_str[] = {
179 "rx_ucast_packets",
180 "rx_mcast_packets",
181 "rx_bcast_packets",
182 "rx_discards",
183 "rx_errors",
184 "rx_ucast_bytes",
185 "rx_mcast_bytes",
186 "rx_bcast_bytes",
187};
188
189static const char * const bnxt_ring_tx_stats_str[] = {
190 "tx_ucast_packets",
191 "tx_mcast_packets",
192 "tx_bcast_packets",
193 "tx_errors",
194 "tx_discards",
195 "tx_ucast_bytes",
196 "tx_mcast_bytes",
197 "tx_bcast_bytes",
198};
199
200static const char * const bnxt_ring_tpa_stats_str[] = {
201 "tpa_packets",
202 "tpa_bytes",
203 "tpa_events",
204 "tpa_aborts",
205};
206
207static const char * const bnxt_ring_tpa2_stats_str[] = {
208 "rx_tpa_eligible_pkt",
209 "rx_tpa_eligible_bytes",
210 "rx_tpa_pkt",
211 "rx_tpa_bytes",
212 "rx_tpa_errors",
213 "rx_tpa_events",
214};
215
216static const char * const bnxt_rx_sw_stats_str[] = {
217 "rx_l4_csum_errors",
218 "rx_resets",
219 "rx_buf_errors",
220};
221
222static const char * const bnxt_cmn_sw_stats_str[] = {
223 "missed_irqs",
224};
225
226#define BNXT_RX_STATS_ENTRY(counter) \
227 { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) }
228
229#define BNXT_TX_STATS_ENTRY(counter) \
230 { BNXT_TX_STATS_OFFSET(counter), __stringify(counter) }
231
232#define BNXT_RX_STATS_EXT_ENTRY(counter) \
233 { BNXT_RX_STATS_EXT_OFFSET(counter), __stringify(counter) }
234
235#define BNXT_TX_STATS_EXT_ENTRY(counter) \
236 { BNXT_TX_STATS_EXT_OFFSET(counter), __stringify(counter) }
237
238#define BNXT_RX_STATS_EXT_PFC_ENTRY(n) \
239 BNXT_RX_STATS_EXT_ENTRY(pfc_pri##n##_rx_duration_us), \
240 BNXT_RX_STATS_EXT_ENTRY(pfc_pri##n##_rx_transitions)
241
242#define BNXT_TX_STATS_EXT_PFC_ENTRY(n) \
243 BNXT_TX_STATS_EXT_ENTRY(pfc_pri##n##_tx_duration_us), \
244 BNXT_TX_STATS_EXT_ENTRY(pfc_pri##n##_tx_transitions)
245
246#define BNXT_RX_STATS_EXT_PFC_ENTRIES \
247 BNXT_RX_STATS_EXT_PFC_ENTRY(0), \
248 BNXT_RX_STATS_EXT_PFC_ENTRY(1), \
249 BNXT_RX_STATS_EXT_PFC_ENTRY(2), \
250 BNXT_RX_STATS_EXT_PFC_ENTRY(3), \
251 BNXT_RX_STATS_EXT_PFC_ENTRY(4), \
252 BNXT_RX_STATS_EXT_PFC_ENTRY(5), \
253 BNXT_RX_STATS_EXT_PFC_ENTRY(6), \
254 BNXT_RX_STATS_EXT_PFC_ENTRY(7)
255
256#define BNXT_TX_STATS_EXT_PFC_ENTRIES \
257 BNXT_TX_STATS_EXT_PFC_ENTRY(0), \
258 BNXT_TX_STATS_EXT_PFC_ENTRY(1), \
259 BNXT_TX_STATS_EXT_PFC_ENTRY(2), \
260 BNXT_TX_STATS_EXT_PFC_ENTRY(3), \
261 BNXT_TX_STATS_EXT_PFC_ENTRY(4), \
262 BNXT_TX_STATS_EXT_PFC_ENTRY(5), \
263 BNXT_TX_STATS_EXT_PFC_ENTRY(6), \
264 BNXT_TX_STATS_EXT_PFC_ENTRY(7)
265
266#define BNXT_RX_STATS_EXT_COS_ENTRY(n) \
267 BNXT_RX_STATS_EXT_ENTRY(rx_bytes_cos##n), \
268 BNXT_RX_STATS_EXT_ENTRY(rx_packets_cos##n)
269
270#define BNXT_TX_STATS_EXT_COS_ENTRY(n) \
271 BNXT_TX_STATS_EXT_ENTRY(tx_bytes_cos##n), \
272 BNXT_TX_STATS_EXT_ENTRY(tx_packets_cos##n)
273
274#define BNXT_RX_STATS_EXT_COS_ENTRIES \
275 BNXT_RX_STATS_EXT_COS_ENTRY(0), \
276 BNXT_RX_STATS_EXT_COS_ENTRY(1), \
277 BNXT_RX_STATS_EXT_COS_ENTRY(2), \
278 BNXT_RX_STATS_EXT_COS_ENTRY(3), \
279 BNXT_RX_STATS_EXT_COS_ENTRY(4), \
280 BNXT_RX_STATS_EXT_COS_ENTRY(5), \
281 BNXT_RX_STATS_EXT_COS_ENTRY(6), \
282 BNXT_RX_STATS_EXT_COS_ENTRY(7) \
283
284#define BNXT_TX_STATS_EXT_COS_ENTRIES \
285 BNXT_TX_STATS_EXT_COS_ENTRY(0), \
286 BNXT_TX_STATS_EXT_COS_ENTRY(1), \
287 BNXT_TX_STATS_EXT_COS_ENTRY(2), \
288 BNXT_TX_STATS_EXT_COS_ENTRY(3), \
289 BNXT_TX_STATS_EXT_COS_ENTRY(4), \
290 BNXT_TX_STATS_EXT_COS_ENTRY(5), \
291 BNXT_TX_STATS_EXT_COS_ENTRY(6), \
292 BNXT_TX_STATS_EXT_COS_ENTRY(7) \
293
294#define BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(n) \
295 BNXT_RX_STATS_EXT_ENTRY(rx_discard_bytes_cos##n), \
296 BNXT_RX_STATS_EXT_ENTRY(rx_discard_packets_cos##n)
297
298#define BNXT_RX_STATS_EXT_DISCARD_COS_ENTRIES \
299 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(0), \
300 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(1), \
301 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(2), \
302 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(3), \
303 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(4), \
304 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(5), \
305 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(6), \
306 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRY(7)
307
308#define BNXT_RX_STATS_PRI_ENTRY(counter, n) \
309 { BNXT_RX_STATS_EXT_OFFSET(counter##_cos0), \
310 __stringify(counter##_pri##n) }
311
312#define BNXT_TX_STATS_PRI_ENTRY(counter, n) \
313 { BNXT_TX_STATS_EXT_OFFSET(counter##_cos0), \
314 __stringify(counter##_pri##n) }
315
316#define BNXT_RX_STATS_PRI_ENTRIES(counter) \
317 BNXT_RX_STATS_PRI_ENTRY(counter, 0), \
318 BNXT_RX_STATS_PRI_ENTRY(counter, 1), \
319 BNXT_RX_STATS_PRI_ENTRY(counter, 2), \
320 BNXT_RX_STATS_PRI_ENTRY(counter, 3), \
321 BNXT_RX_STATS_PRI_ENTRY(counter, 4), \
322 BNXT_RX_STATS_PRI_ENTRY(counter, 5), \
323 BNXT_RX_STATS_PRI_ENTRY(counter, 6), \
324 BNXT_RX_STATS_PRI_ENTRY(counter, 7)
325
326#define BNXT_TX_STATS_PRI_ENTRIES(counter) \
327 BNXT_TX_STATS_PRI_ENTRY(counter, 0), \
328 BNXT_TX_STATS_PRI_ENTRY(counter, 1), \
329 BNXT_TX_STATS_PRI_ENTRY(counter, 2), \
330 BNXT_TX_STATS_PRI_ENTRY(counter, 3), \
331 BNXT_TX_STATS_PRI_ENTRY(counter, 4), \
332 BNXT_TX_STATS_PRI_ENTRY(counter, 5), \
333 BNXT_TX_STATS_PRI_ENTRY(counter, 6), \
334 BNXT_TX_STATS_PRI_ENTRY(counter, 7)
335
336enum {
337 RX_TOTAL_DISCARDS,
338 TX_TOTAL_DISCARDS,
339 RX_NETPOLL_DISCARDS,
340};
341
342static const char *const bnxt_ring_err_stats_arr[] = {
343 "rx_total_l4_csum_errors",
344 "rx_total_resets",
345 "rx_total_buf_errors",
346 "rx_total_oom_discards",
347 "rx_total_netpoll_discards",
348 "rx_total_ring_discards",
349 "tx_total_resets",
350 "tx_total_ring_discards",
351 "total_missed_irqs",
352};
353
354#define NUM_RING_RX_SW_STATS ARRAY_SIZE(bnxt_rx_sw_stats_str)
355#define NUM_RING_CMN_SW_STATS ARRAY_SIZE(bnxt_cmn_sw_stats_str)
356#define NUM_RING_RX_HW_STATS ARRAY_SIZE(bnxt_ring_rx_stats_str)
357#define NUM_RING_TX_HW_STATS ARRAY_SIZE(bnxt_ring_tx_stats_str)
358
359static const struct {
360 long offset;
361 char string[ETH_GSTRING_LEN];
362} bnxt_port_stats_arr[] = {
363 BNXT_RX_STATS_ENTRY(rx_64b_frames),
364 BNXT_RX_STATS_ENTRY(rx_65b_127b_frames),
365 BNXT_RX_STATS_ENTRY(rx_128b_255b_frames),
366 BNXT_RX_STATS_ENTRY(rx_256b_511b_frames),
367 BNXT_RX_STATS_ENTRY(rx_512b_1023b_frames),
368 BNXT_RX_STATS_ENTRY(rx_1024b_1518b_frames),
369 BNXT_RX_STATS_ENTRY(rx_good_vlan_frames),
370 BNXT_RX_STATS_ENTRY(rx_1519b_2047b_frames),
371 BNXT_RX_STATS_ENTRY(rx_2048b_4095b_frames),
372 BNXT_RX_STATS_ENTRY(rx_4096b_9216b_frames),
373 BNXT_RX_STATS_ENTRY(rx_9217b_16383b_frames),
374 BNXT_RX_STATS_ENTRY(rx_total_frames),
375 BNXT_RX_STATS_ENTRY(rx_ucast_frames),
376 BNXT_RX_STATS_ENTRY(rx_mcast_frames),
377 BNXT_RX_STATS_ENTRY(rx_bcast_frames),
378 BNXT_RX_STATS_ENTRY(rx_fcs_err_frames),
379 BNXT_RX_STATS_ENTRY(rx_ctrl_frames),
380 BNXT_RX_STATS_ENTRY(rx_pause_frames),
381 BNXT_RX_STATS_ENTRY(rx_pfc_frames),
382 BNXT_RX_STATS_ENTRY(rx_align_err_frames),
383 BNXT_RX_STATS_ENTRY(rx_ovrsz_frames),
384 BNXT_RX_STATS_ENTRY(rx_jbr_frames),
385 BNXT_RX_STATS_ENTRY(rx_mtu_err_frames),
386 BNXT_RX_STATS_ENTRY(rx_tagged_frames),
387 BNXT_RX_STATS_ENTRY(rx_double_tagged_frames),
388 BNXT_RX_STATS_ENTRY(rx_good_frames),
389 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri0),
390 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri1),
391 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri2),
392 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri3),
393 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri4),
394 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri5),
395 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri6),
396 BNXT_RX_STATS_ENTRY(rx_pfc_ena_frames_pri7),
397 BNXT_RX_STATS_ENTRY(rx_undrsz_frames),
398 BNXT_RX_STATS_ENTRY(rx_eee_lpi_events),
399 BNXT_RX_STATS_ENTRY(rx_eee_lpi_duration),
400 BNXT_RX_STATS_ENTRY(rx_bytes),
401 BNXT_RX_STATS_ENTRY(rx_runt_bytes),
402 BNXT_RX_STATS_ENTRY(rx_runt_frames),
403 BNXT_RX_STATS_ENTRY(rx_stat_discard),
404 BNXT_RX_STATS_ENTRY(rx_stat_err),
405
406 BNXT_TX_STATS_ENTRY(tx_64b_frames),
407 BNXT_TX_STATS_ENTRY(tx_65b_127b_frames),
408 BNXT_TX_STATS_ENTRY(tx_128b_255b_frames),
409 BNXT_TX_STATS_ENTRY(tx_256b_511b_frames),
410 BNXT_TX_STATS_ENTRY(tx_512b_1023b_frames),
411 BNXT_TX_STATS_ENTRY(tx_1024b_1518b_frames),
412 BNXT_TX_STATS_ENTRY(tx_good_vlan_frames),
413 BNXT_TX_STATS_ENTRY(tx_1519b_2047b_frames),
414 BNXT_TX_STATS_ENTRY(tx_2048b_4095b_frames),
415 BNXT_TX_STATS_ENTRY(tx_4096b_9216b_frames),
416 BNXT_TX_STATS_ENTRY(tx_9217b_16383b_frames),
417 BNXT_TX_STATS_ENTRY(tx_good_frames),
418 BNXT_TX_STATS_ENTRY(tx_total_frames),
419 BNXT_TX_STATS_ENTRY(tx_ucast_frames),
420 BNXT_TX_STATS_ENTRY(tx_mcast_frames),
421 BNXT_TX_STATS_ENTRY(tx_bcast_frames),
422 BNXT_TX_STATS_ENTRY(tx_pause_frames),
423 BNXT_TX_STATS_ENTRY(tx_pfc_frames),
424 BNXT_TX_STATS_ENTRY(tx_jabber_frames),
425 BNXT_TX_STATS_ENTRY(tx_fcs_err_frames),
426 BNXT_TX_STATS_ENTRY(tx_err),
427 BNXT_TX_STATS_ENTRY(tx_fifo_underruns),
428 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri0),
429 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri1),
430 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri2),
431 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri3),
432 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri4),
433 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri5),
434 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri6),
435 BNXT_TX_STATS_ENTRY(tx_pfc_ena_frames_pri7),
436 BNXT_TX_STATS_ENTRY(tx_eee_lpi_events),
437 BNXT_TX_STATS_ENTRY(tx_eee_lpi_duration),
438 BNXT_TX_STATS_ENTRY(tx_total_collisions),
439 BNXT_TX_STATS_ENTRY(tx_bytes),
440 BNXT_TX_STATS_ENTRY(tx_xthol_frames),
441 BNXT_TX_STATS_ENTRY(tx_stat_discard),
442 BNXT_TX_STATS_ENTRY(tx_stat_error),
443};
444
445static const struct {
446 long offset;
447 char string[ETH_GSTRING_LEN];
448} bnxt_port_stats_ext_arr[] = {
449 BNXT_RX_STATS_EXT_ENTRY(link_down_events),
450 BNXT_RX_STATS_EXT_ENTRY(continuous_pause_events),
451 BNXT_RX_STATS_EXT_ENTRY(resume_pause_events),
452 BNXT_RX_STATS_EXT_ENTRY(continuous_roce_pause_events),
453 BNXT_RX_STATS_EXT_ENTRY(resume_roce_pause_events),
454 BNXT_RX_STATS_EXT_COS_ENTRIES,
455 BNXT_RX_STATS_EXT_PFC_ENTRIES,
456 BNXT_RX_STATS_EXT_ENTRY(rx_bits),
457 BNXT_RX_STATS_EXT_ENTRY(rx_buffer_passed_threshold),
458 BNXT_RX_STATS_EXT_ENTRY(rx_pcs_symbol_err),
459 BNXT_RX_STATS_EXT_ENTRY(rx_corrected_bits),
460 BNXT_RX_STATS_EXT_DISCARD_COS_ENTRIES,
461 BNXT_RX_STATS_EXT_ENTRY(rx_fec_corrected_blocks),
462 BNXT_RX_STATS_EXT_ENTRY(rx_fec_uncorrectable_blocks),
463 BNXT_RX_STATS_EXT_ENTRY(rx_filter_miss),
464};
465
466static const struct {
467 long offset;
468 char string[ETH_GSTRING_LEN];
469} bnxt_tx_port_stats_ext_arr[] = {
470 BNXT_TX_STATS_EXT_COS_ENTRIES,
471 BNXT_TX_STATS_EXT_PFC_ENTRIES,
472};
473
474static const struct {
475 long base_off;
476 char string[ETH_GSTRING_LEN];
477} bnxt_rx_bytes_pri_arr[] = {
478 BNXT_RX_STATS_PRI_ENTRIES(rx_bytes),
479};
480
481static const struct {
482 long base_off;
483 char string[ETH_GSTRING_LEN];
484} bnxt_rx_pkts_pri_arr[] = {
485 BNXT_RX_STATS_PRI_ENTRIES(rx_packets),
486};
487
488static const struct {
489 long base_off;
490 char string[ETH_GSTRING_LEN];
491} bnxt_tx_bytes_pri_arr[] = {
492 BNXT_TX_STATS_PRI_ENTRIES(tx_bytes),
493};
494
495static const struct {
496 long base_off;
497 char string[ETH_GSTRING_LEN];
498} bnxt_tx_pkts_pri_arr[] = {
499 BNXT_TX_STATS_PRI_ENTRIES(tx_packets),
500};
501
502#define BNXT_NUM_RING_ERR_STATS ARRAY_SIZE(bnxt_ring_err_stats_arr)
503#define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr)
504#define BNXT_NUM_STATS_PRI \
505 (ARRAY_SIZE(bnxt_rx_bytes_pri_arr) + \
506 ARRAY_SIZE(bnxt_rx_pkts_pri_arr) + \
507 ARRAY_SIZE(bnxt_tx_bytes_pri_arr) + \
508 ARRAY_SIZE(bnxt_tx_pkts_pri_arr))
509
510static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp)
511{
512 if (BNXT_SUPPORTS_TPA(bp)) {
513 if (bp->max_tpa_v2) {
514 if (BNXT_CHIP_P5(bp))
515 return BNXT_NUM_TPA_RING_STATS_P5;
516 return BNXT_NUM_TPA_RING_STATS_P7;
517 }
518 return BNXT_NUM_TPA_RING_STATS;
519 }
520 return 0;
521}
522
523static int bnxt_get_num_ring_stats(struct bnxt *bp)
524{
525 int rx, tx, cmn;
526
527 rx = NUM_RING_RX_HW_STATS + NUM_RING_RX_SW_STATS +
528 bnxt_get_num_tpa_ring_stats(bp);
529 tx = NUM_RING_TX_HW_STATS;
530 cmn = NUM_RING_CMN_SW_STATS;
531 return rx * bp->rx_nr_rings +
532 tx * (bp->tx_nr_rings_xdp + bp->tx_nr_rings_per_tc) +
533 cmn * bp->cp_nr_rings;
534}
535
536static int bnxt_get_num_stats(struct bnxt *bp)
537{
538 int num_stats = bnxt_get_num_ring_stats(bp);
539 int len;
540
541 num_stats += BNXT_NUM_RING_ERR_STATS;
542
543 if (bp->flags & BNXT_FLAG_PORT_STATS)
544 num_stats += BNXT_NUM_PORT_STATS;
545
546 if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
547 len = min_t(int, bp->fw_rx_stats_ext_size,
548 ARRAY_SIZE(bnxt_port_stats_ext_arr));
549 num_stats += len;
550 len = min_t(int, bp->fw_tx_stats_ext_size,
551 ARRAY_SIZE(bnxt_tx_port_stats_ext_arr));
552 num_stats += len;
553 if (bp->pri2cos_valid)
554 num_stats += BNXT_NUM_STATS_PRI;
555 }
556
557 return num_stats;
558}
559
560static int bnxt_get_sset_count(struct net_device *dev, int sset)
561{
562 struct bnxt *bp = netdev_priv(dev);
563
564 switch (sset) {
565 case ETH_SS_STATS:
566 return bnxt_get_num_stats(bp);
567 case ETH_SS_TEST:
568 if (!bp->num_tests)
569 return -EOPNOTSUPP;
570 return bp->num_tests;
571 default:
572 return -EOPNOTSUPP;
573 }
574}
575
576static bool is_rx_ring(struct bnxt *bp, int ring_num)
577{
578 return ring_num < bp->rx_nr_rings;
579}
580
581static bool is_tx_ring(struct bnxt *bp, int ring_num)
582{
583 int tx_base = 0;
584
585 if (!(bp->flags & BNXT_FLAG_SHARED_RINGS))
586 tx_base = bp->rx_nr_rings;
587
588 if (ring_num >= tx_base && ring_num < (tx_base + bp->tx_nr_rings))
589 return true;
590 return false;
591}
592
593static void bnxt_get_ethtool_stats(struct net_device *dev,
594 struct ethtool_stats *stats, u64 *buf)
595{
596 struct bnxt_total_ring_err_stats ring_err_stats = {0};
597 struct bnxt *bp = netdev_priv(dev);
598 u64 *curr, *prev;
599 u32 tpa_stats;
600 u32 i, j = 0;
601
602 if (!bp->bnapi) {
603 j += bnxt_get_num_ring_stats(bp);
604 goto skip_ring_stats;
605 }
606
607 tpa_stats = bnxt_get_num_tpa_ring_stats(bp);
608 for (i = 0; i < bp->cp_nr_rings; i++) {
609 struct bnxt_napi *bnapi = bp->bnapi[i];
610 struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
611 u64 *sw_stats = cpr->stats.sw_stats;
612 u64 *sw;
613 int k;
614
615 if (is_rx_ring(bp, ring_num: i)) {
616 for (k = 0; k < NUM_RING_RX_HW_STATS; j++, k++)
617 buf[j] = sw_stats[k];
618 }
619 if (is_tx_ring(bp, ring_num: i)) {
620 k = NUM_RING_RX_HW_STATS;
621 for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
622 j++, k++)
623 buf[j] = sw_stats[k];
624 }
625 if (!tpa_stats || !is_rx_ring(bp, ring_num: i))
626 goto skip_tpa_ring_stats;
627
628 k = NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS;
629 for (; k < NUM_RING_RX_HW_STATS + NUM_RING_TX_HW_STATS +
630 tpa_stats; j++, k++)
631 buf[j] = sw_stats[k];
632
633skip_tpa_ring_stats:
634 sw = (u64 *)&cpr->sw_stats.rx;
635 if (is_rx_ring(bp, ring_num: i)) {
636 for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++)
637 buf[j] = sw[k];
638 }
639
640 sw = (u64 *)&cpr->sw_stats.cmn;
641 for (k = 0; k < NUM_RING_CMN_SW_STATS; j++, k++)
642 buf[j] = sw[k];
643 }
644
645 bnxt_get_ring_err_stats(bp, stats: &ring_err_stats);
646
647skip_ring_stats:
648 curr = &ring_err_stats.rx_total_l4_csum_errors;
649 prev = &bp->ring_err_stats_prev.rx_total_l4_csum_errors;
650 for (i = 0; i < BNXT_NUM_RING_ERR_STATS; i++, j++, curr++, prev++)
651 buf[j] = *curr + *prev;
652
653 if (bp->flags & BNXT_FLAG_PORT_STATS) {
654 u64 *port_stats = bp->port_stats.sw_stats;
655
656 for (i = 0; i < BNXT_NUM_PORT_STATS; i++, j++)
657 buf[j] = *(port_stats + bnxt_port_stats_arr[i].offset);
658 }
659 if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
660 u64 *rx_port_stats_ext = bp->rx_port_stats_ext.sw_stats;
661 u64 *tx_port_stats_ext = bp->tx_port_stats_ext.sw_stats;
662 u32 len;
663
664 len = min_t(u32, bp->fw_rx_stats_ext_size,
665 ARRAY_SIZE(bnxt_port_stats_ext_arr));
666 for (i = 0; i < len; i++, j++) {
667 buf[j] = *(rx_port_stats_ext +
668 bnxt_port_stats_ext_arr[i].offset);
669 }
670 len = min_t(u32, bp->fw_tx_stats_ext_size,
671 ARRAY_SIZE(bnxt_tx_port_stats_ext_arr));
672 for (i = 0; i < len; i++, j++) {
673 buf[j] = *(tx_port_stats_ext +
674 bnxt_tx_port_stats_ext_arr[i].offset);
675 }
676 if (bp->pri2cos_valid) {
677 for (i = 0; i < 8; i++, j++) {
678 long n = bnxt_rx_bytes_pri_arr[i].base_off +
679 bp->pri2cos_idx[i];
680
681 buf[j] = *(rx_port_stats_ext + n);
682 }
683 for (i = 0; i < 8; i++, j++) {
684 long n = bnxt_rx_pkts_pri_arr[i].base_off +
685 bp->pri2cos_idx[i];
686
687 buf[j] = *(rx_port_stats_ext + n);
688 }
689 for (i = 0; i < 8; i++, j++) {
690 long n = bnxt_tx_bytes_pri_arr[i].base_off +
691 bp->pri2cos_idx[i];
692
693 buf[j] = *(tx_port_stats_ext + n);
694 }
695 for (i = 0; i < 8; i++, j++) {
696 long n = bnxt_tx_pkts_pri_arr[i].base_off +
697 bp->pri2cos_idx[i];
698
699 buf[j] = *(tx_port_stats_ext + n);
700 }
701 }
702 }
703}
704
705static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
706{
707 struct bnxt *bp = netdev_priv(dev);
708 static const char * const *str;
709 u32 i, j, num_str;
710
711 switch (stringset) {
712 case ETH_SS_STATS:
713 for (i = 0; i < bp->cp_nr_rings; i++) {
714 if (is_rx_ring(bp, ring_num: i)) {
715 num_str = NUM_RING_RX_HW_STATS;
716 for (j = 0; j < num_str; j++) {
717 sprintf(buf, fmt: "[%d]: %s", i,
718 bnxt_ring_rx_stats_str[j]);
719 buf += ETH_GSTRING_LEN;
720 }
721 }
722 if (is_tx_ring(bp, ring_num: i)) {
723 num_str = NUM_RING_TX_HW_STATS;
724 for (j = 0; j < num_str; j++) {
725 sprintf(buf, fmt: "[%d]: %s", i,
726 bnxt_ring_tx_stats_str[j]);
727 buf += ETH_GSTRING_LEN;
728 }
729 }
730 num_str = bnxt_get_num_tpa_ring_stats(bp);
731 if (!num_str || !is_rx_ring(bp, ring_num: i))
732 goto skip_tpa_stats;
733
734 if (bp->max_tpa_v2)
735 str = bnxt_ring_tpa2_stats_str;
736 else
737 str = bnxt_ring_tpa_stats_str;
738
739 for (j = 0; j < num_str; j++) {
740 sprintf(buf, fmt: "[%d]: %s", i, str[j]);
741 buf += ETH_GSTRING_LEN;
742 }
743skip_tpa_stats:
744 if (is_rx_ring(bp, ring_num: i)) {
745 num_str = NUM_RING_RX_SW_STATS;
746 for (j = 0; j < num_str; j++) {
747 sprintf(buf, fmt: "[%d]: %s", i,
748 bnxt_rx_sw_stats_str[j]);
749 buf += ETH_GSTRING_LEN;
750 }
751 }
752 num_str = NUM_RING_CMN_SW_STATS;
753 for (j = 0; j < num_str; j++) {
754 sprintf(buf, fmt: "[%d]: %s", i,
755 bnxt_cmn_sw_stats_str[j]);
756 buf += ETH_GSTRING_LEN;
757 }
758 }
759 for (i = 0; i < BNXT_NUM_RING_ERR_STATS; i++) {
760 strscpy(buf, bnxt_ring_err_stats_arr[i], ETH_GSTRING_LEN);
761 buf += ETH_GSTRING_LEN;
762 }
763
764 if (bp->flags & BNXT_FLAG_PORT_STATS) {
765 for (i = 0; i < BNXT_NUM_PORT_STATS; i++) {
766 strcpy(p: buf, q: bnxt_port_stats_arr[i].string);
767 buf += ETH_GSTRING_LEN;
768 }
769 }
770 if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
771 u32 len;
772
773 len = min_t(u32, bp->fw_rx_stats_ext_size,
774 ARRAY_SIZE(bnxt_port_stats_ext_arr));
775 for (i = 0; i < len; i++) {
776 strcpy(p: buf, q: bnxt_port_stats_ext_arr[i].string);
777 buf += ETH_GSTRING_LEN;
778 }
779 len = min_t(u32, bp->fw_tx_stats_ext_size,
780 ARRAY_SIZE(bnxt_tx_port_stats_ext_arr));
781 for (i = 0; i < len; i++) {
782 strcpy(p: buf,
783 q: bnxt_tx_port_stats_ext_arr[i].string);
784 buf += ETH_GSTRING_LEN;
785 }
786 if (bp->pri2cos_valid) {
787 for (i = 0; i < 8; i++) {
788 strcpy(p: buf,
789 q: bnxt_rx_bytes_pri_arr[i].string);
790 buf += ETH_GSTRING_LEN;
791 }
792 for (i = 0; i < 8; i++) {
793 strcpy(p: buf,
794 q: bnxt_rx_pkts_pri_arr[i].string);
795 buf += ETH_GSTRING_LEN;
796 }
797 for (i = 0; i < 8; i++) {
798 strcpy(p: buf,
799 q: bnxt_tx_bytes_pri_arr[i].string);
800 buf += ETH_GSTRING_LEN;
801 }
802 for (i = 0; i < 8; i++) {
803 strcpy(p: buf,
804 q: bnxt_tx_pkts_pri_arr[i].string);
805 buf += ETH_GSTRING_LEN;
806 }
807 }
808 }
809 break;
810 case ETH_SS_TEST:
811 if (bp->num_tests)
812 memcpy(buf, bp->test_info->string,
813 bp->num_tests * ETH_GSTRING_LEN);
814 break;
815 default:
816 netdev_err(dev: bp->dev, format: "bnxt_get_strings invalid request %x\n",
817 stringset);
818 break;
819 }
820}
821
822static void bnxt_get_ringparam(struct net_device *dev,
823 struct ethtool_ringparam *ering,
824 struct kernel_ethtool_ringparam *kernel_ering,
825 struct netlink_ext_ack *extack)
826{
827 struct bnxt *bp = netdev_priv(dev);
828
829 if (bp->flags & BNXT_FLAG_AGG_RINGS) {
830 ering->rx_max_pending = BNXT_MAX_RX_DESC_CNT_JUM_ENA;
831 ering->rx_jumbo_max_pending = BNXT_MAX_RX_JUM_DESC_CNT;
832 kernel_ering->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_ENABLED;
833 } else {
834 ering->rx_max_pending = BNXT_MAX_RX_DESC_CNT;
835 ering->rx_jumbo_max_pending = 0;
836 kernel_ering->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_DISABLED;
837 }
838 ering->tx_max_pending = BNXT_MAX_TX_DESC_CNT;
839
840 ering->rx_pending = bp->rx_ring_size;
841 ering->rx_jumbo_pending = bp->rx_agg_ring_size;
842 ering->tx_pending = bp->tx_ring_size;
843}
844
845static int bnxt_set_ringparam(struct net_device *dev,
846 struct ethtool_ringparam *ering,
847 struct kernel_ethtool_ringparam *kernel_ering,
848 struct netlink_ext_ack *extack)
849{
850 struct bnxt *bp = netdev_priv(dev);
851
852 if ((ering->rx_pending > BNXT_MAX_RX_DESC_CNT) ||
853 (ering->tx_pending > BNXT_MAX_TX_DESC_CNT) ||
854 (ering->tx_pending < BNXT_MIN_TX_DESC_CNT))
855 return -EINVAL;
856
857 if (netif_running(dev))
858 bnxt_close_nic(bp, false, false);
859
860 bp->rx_ring_size = ering->rx_pending;
861 bp->tx_ring_size = ering->tx_pending;
862 bnxt_set_ring_params(bp);
863
864 if (netif_running(dev))
865 return bnxt_open_nic(bp, false, false);
866
867 return 0;
868}
869
870static void bnxt_get_channels(struct net_device *dev,
871 struct ethtool_channels *channel)
872{
873 struct bnxt *bp = netdev_priv(dev);
874 struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
875 int max_rx_rings, max_tx_rings, tcs;
876 int max_tx_sch_inputs, tx_grps;
877
878 /* Get the most up-to-date max_tx_sch_inputs. */
879 if (netif_running(dev) && BNXT_NEW_RM(bp))
880 bnxt_hwrm_func_resc_qcaps(bp, all: false);
881 max_tx_sch_inputs = hw_resc->max_tx_sch_inputs;
882
883 bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
884 if (max_tx_sch_inputs)
885 max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs);
886
887 tcs = bp->num_tc;
888 tx_grps = max(tcs, 1);
889 if (bp->tx_nr_rings_xdp)
890 tx_grps++;
891 max_tx_rings /= tx_grps;
892 channel->max_combined = min_t(int, max_rx_rings, max_tx_rings);
893
894 if (bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false)) {
895 max_rx_rings = 0;
896 max_tx_rings = 0;
897 }
898 if (max_tx_sch_inputs)
899 max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs);
900
901 if (tcs > 1)
902 max_tx_rings /= tcs;
903
904 channel->max_rx = max_rx_rings;
905 channel->max_tx = max_tx_rings;
906 channel->max_other = 0;
907 if (bp->flags & BNXT_FLAG_SHARED_RINGS) {
908 channel->combined_count = bp->rx_nr_rings;
909 if (BNXT_CHIP_TYPE_NITRO_A0(bp))
910 channel->combined_count--;
911 } else {
912 if (!BNXT_CHIP_TYPE_NITRO_A0(bp)) {
913 channel->rx_count = bp->rx_nr_rings;
914 channel->tx_count = bp->tx_nr_rings_per_tc;
915 }
916 }
917}
918
919static int bnxt_set_channels(struct net_device *dev,
920 struct ethtool_channels *channel)
921{
922 struct bnxt *bp = netdev_priv(dev);
923 int req_tx_rings, req_rx_rings, tcs;
924 bool sh = false;
925 int tx_xdp = 0;
926 int rc = 0;
927 int tx_cp;
928
929 if (channel->other_count)
930 return -EINVAL;
931
932 if (!channel->combined_count &&
933 (!channel->rx_count || !channel->tx_count))
934 return -EINVAL;
935
936 if (channel->combined_count &&
937 (channel->rx_count || channel->tx_count))
938 return -EINVAL;
939
940 if (BNXT_CHIP_TYPE_NITRO_A0(bp) && (channel->rx_count ||
941 channel->tx_count))
942 return -EINVAL;
943
944 if (channel->combined_count)
945 sh = true;
946
947 tcs = bp->num_tc;
948
949 req_tx_rings = sh ? channel->combined_count : channel->tx_count;
950 req_rx_rings = sh ? channel->combined_count : channel->rx_count;
951 if (bp->tx_nr_rings_xdp) {
952 if (!sh) {
953 netdev_err(dev, format: "Only combined mode supported when XDP is enabled.\n");
954 return -EINVAL;
955 }
956 tx_xdp = req_rx_rings;
957 }
958 rc = bnxt_check_rings(bp, tx: req_tx_rings, rx: req_rx_rings, sh, tcs, tx_xdp);
959 if (rc) {
960 netdev_warn(dev, format: "Unable to allocate the requested rings\n");
961 return rc;
962 }
963
964 if (bnxt_get_nr_rss_ctxs(bp, rx_rings: req_rx_rings) !=
965 bnxt_get_nr_rss_ctxs(bp, rx_rings: bp->rx_nr_rings) &&
966 netif_is_rxfh_configured(dev)) {
967 netdev_warn(dev, format: "RSS table size change required, RSS table entries must be default to proceed\n");
968 return -EINVAL;
969 }
970
971 bnxt_clear_usr_fltrs(bp, all: true);
972 if (netif_running(dev)) {
973 if (BNXT_PF(bp)) {
974 /* TODO CHIMP_FW: Send message to all VF's
975 * before PF unload
976 */
977 }
978 bnxt_close_nic(bp, true, false);
979 }
980
981 if (sh) {
982 bp->flags |= BNXT_FLAG_SHARED_RINGS;
983 bp->rx_nr_rings = channel->combined_count;
984 bp->tx_nr_rings_per_tc = channel->combined_count;
985 } else {
986 bp->flags &= ~BNXT_FLAG_SHARED_RINGS;
987 bp->rx_nr_rings = channel->rx_count;
988 bp->tx_nr_rings_per_tc = channel->tx_count;
989 }
990 bp->tx_nr_rings_xdp = tx_xdp;
991 bp->tx_nr_rings = bp->tx_nr_rings_per_tc + tx_xdp;
992 if (tcs > 1)
993 bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs + tx_xdp;
994
995 tx_cp = bnxt_num_tx_to_cp(bp, tx: bp->tx_nr_rings);
996 bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
997 tx_cp + bp->rx_nr_rings;
998
999 /* After changing number of rx channels, update NTUPLE feature. */
1000 netdev_update_features(dev);
1001 if (netif_running(dev)) {
1002 rc = bnxt_open_nic(bp, true, false);
1003 if ((!rc) && BNXT_PF(bp)) {
1004 /* TODO CHIMP_FW: Send message to all VF's
1005 * to renable
1006 */
1007 }
1008 } else {
1009 rc = bnxt_reserve_rings(bp, irq_re_init: true);
1010 }
1011
1012 return rc;
1013}
1014
1015static u32 bnxt_get_all_fltr_ids_rcu(struct bnxt *bp, struct hlist_head tbl[],
1016 int tbl_size, u32 *ids, u32 start,
1017 u32 id_cnt)
1018{
1019 int i, j = start;
1020
1021 if (j >= id_cnt)
1022 return j;
1023 for (i = 0; i < tbl_size; i++) {
1024 struct hlist_head *head;
1025 struct bnxt_filter_base *fltr;
1026
1027 head = &tbl[i];
1028 hlist_for_each_entry_rcu(fltr, head, hash) {
1029 if (!fltr->flags ||
1030 test_bit(BNXT_FLTR_FW_DELETED, &fltr->state))
1031 continue;
1032 ids[j++] = fltr->sw_id;
1033 if (j == id_cnt)
1034 return j;
1035 }
1036 }
1037 return j;
1038}
1039
1040static struct bnxt_filter_base *bnxt_get_one_fltr_rcu(struct bnxt *bp,
1041 struct hlist_head tbl[],
1042 int tbl_size, u32 id)
1043{
1044 int i;
1045
1046 for (i = 0; i < tbl_size; i++) {
1047 struct hlist_head *head;
1048 struct bnxt_filter_base *fltr;
1049
1050 head = &tbl[i];
1051 hlist_for_each_entry_rcu(fltr, head, hash) {
1052 if (fltr->flags && fltr->sw_id == id)
1053 return fltr;
1054 }
1055 }
1056 return NULL;
1057}
1058
1059static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd,
1060 u32 *rule_locs)
1061{
1062 u32 count;
1063
1064 cmd->data = bp->ntp_fltr_count;
1065 rcu_read_lock();
1066 count = bnxt_get_all_fltr_ids_rcu(bp, tbl: bp->l2_fltr_hash_tbl,
1067 BNXT_L2_FLTR_HASH_SIZE, ids: rule_locs, start: 0,
1068 id_cnt: cmd->rule_cnt);
1069 cmd->rule_cnt = bnxt_get_all_fltr_ids_rcu(bp, tbl: bp->ntp_fltr_hash_tbl,
1070 BNXT_NTP_FLTR_HASH_SIZE,
1071 ids: rule_locs, start: count,
1072 id_cnt: cmd->rule_cnt);
1073 rcu_read_unlock();
1074
1075 return 0;
1076}
1077
1078static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
1079{
1080 struct ethtool_rx_flow_spec *fs =
1081 (struct ethtool_rx_flow_spec *)&cmd->fs;
1082 struct bnxt_filter_base *fltr_base;
1083 struct bnxt_ntuple_filter *fltr;
1084 struct bnxt_flow_masks *fmasks;
1085 struct flow_keys *fkeys;
1086 int rc = -EINVAL;
1087
1088 if (fs->location >= bp->max_fltr)
1089 return rc;
1090
1091 rcu_read_lock();
1092 fltr_base = bnxt_get_one_fltr_rcu(bp, tbl: bp->l2_fltr_hash_tbl,
1093 BNXT_L2_FLTR_HASH_SIZE,
1094 id: fs->location);
1095 if (fltr_base) {
1096 struct ethhdr *h_ether = &fs->h_u.ether_spec;
1097 struct ethhdr *m_ether = &fs->m_u.ether_spec;
1098 struct bnxt_l2_filter *l2_fltr;
1099 struct bnxt_l2_key *l2_key;
1100
1101 l2_fltr = container_of(fltr_base, struct bnxt_l2_filter, base);
1102 l2_key = &l2_fltr->l2_key;
1103 fs->flow_type = ETHER_FLOW;
1104 ether_addr_copy(dst: h_ether->h_dest, src: l2_key->dst_mac_addr);
1105 eth_broadcast_addr(addr: m_ether->h_dest);
1106 if (l2_key->vlan) {
1107 struct ethtool_flow_ext *m_ext = &fs->m_ext;
1108 struct ethtool_flow_ext *h_ext = &fs->h_ext;
1109
1110 fs->flow_type |= FLOW_EXT;
1111 m_ext->vlan_tci = htons(0xfff);
1112 h_ext->vlan_tci = htons(l2_key->vlan);
1113 }
1114 if (fltr_base->flags & BNXT_ACT_RING_DST)
1115 fs->ring_cookie = fltr_base->rxq;
1116 if (fltr_base->flags & BNXT_ACT_FUNC_DST)
1117 fs->ring_cookie = (u64)(fltr_base->vf_idx + 1) <<
1118 ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
1119 rcu_read_unlock();
1120 return 0;
1121 }
1122 fltr_base = bnxt_get_one_fltr_rcu(bp, tbl: bp->ntp_fltr_hash_tbl,
1123 BNXT_NTP_FLTR_HASH_SIZE,
1124 id: fs->location);
1125 if (!fltr_base) {
1126 rcu_read_unlock();
1127 return rc;
1128 }
1129 fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
1130
1131 fkeys = &fltr->fkeys;
1132 fmasks = &fltr->fmasks;
1133 if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
1134 if (fkeys->basic.ip_proto == IPPROTO_ICMP ||
1135 fkeys->basic.ip_proto == IPPROTO_RAW) {
1136 fs->flow_type = IP_USER_FLOW;
1137 fs->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
1138 if (fkeys->basic.ip_proto == IPPROTO_ICMP)
1139 fs->h_u.usr_ip4_spec.proto = IPPROTO_ICMP;
1140 else
1141 fs->h_u.usr_ip4_spec.proto = IPPROTO_RAW;
1142 fs->m_u.usr_ip4_spec.proto = BNXT_IP_PROTO_FULL_MASK;
1143 } else if (fkeys->basic.ip_proto == IPPROTO_TCP) {
1144 fs->flow_type = TCP_V4_FLOW;
1145 } else if (fkeys->basic.ip_proto == IPPROTO_UDP) {
1146 fs->flow_type = UDP_V4_FLOW;
1147 } else {
1148 goto fltr_err;
1149 }
1150
1151 fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
1152 fs->m_u.tcp_ip4_spec.ip4src = fmasks->addrs.v4addrs.src;
1153 fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
1154 fs->m_u.tcp_ip4_spec.ip4dst = fmasks->addrs.v4addrs.dst;
1155 if (fs->flow_type == TCP_V4_FLOW ||
1156 fs->flow_type == UDP_V4_FLOW) {
1157 fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
1158 fs->m_u.tcp_ip4_spec.psrc = fmasks->ports.src;
1159 fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
1160 fs->m_u.tcp_ip4_spec.pdst = fmasks->ports.dst;
1161 }
1162 } else {
1163 if (fkeys->basic.ip_proto == IPPROTO_ICMPV6 ||
1164 fkeys->basic.ip_proto == IPPROTO_RAW) {
1165 fs->flow_type = IPV6_USER_FLOW;
1166 if (fkeys->basic.ip_proto == IPPROTO_ICMPV6)
1167 fs->h_u.usr_ip6_spec.l4_proto = IPPROTO_ICMPV6;
1168 else
1169 fs->h_u.usr_ip6_spec.l4_proto = IPPROTO_RAW;
1170 fs->m_u.usr_ip6_spec.l4_proto = BNXT_IP_PROTO_FULL_MASK;
1171 } else if (fkeys->basic.ip_proto == IPPROTO_TCP) {
1172 fs->flow_type = TCP_V6_FLOW;
1173 } else if (fkeys->basic.ip_proto == IPPROTO_UDP) {
1174 fs->flow_type = UDP_V6_FLOW;
1175 } else {
1176 goto fltr_err;
1177 }
1178
1179 *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] =
1180 fkeys->addrs.v6addrs.src;
1181 *(struct in6_addr *)&fs->m_u.tcp_ip6_spec.ip6src[0] =
1182 fmasks->addrs.v6addrs.src;
1183 *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] =
1184 fkeys->addrs.v6addrs.dst;
1185 *(struct in6_addr *)&fs->m_u.tcp_ip6_spec.ip6dst[0] =
1186 fmasks->addrs.v6addrs.dst;
1187 if (fs->flow_type == TCP_V6_FLOW ||
1188 fs->flow_type == UDP_V6_FLOW) {
1189 fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src;
1190 fs->m_u.tcp_ip6_spec.psrc = fmasks->ports.src;
1191 fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst;
1192 fs->m_u.tcp_ip6_spec.pdst = fmasks->ports.dst;
1193 }
1194 }
1195
1196 if (fltr->base.flags & BNXT_ACT_DROP)
1197 fs->ring_cookie = RX_CLS_FLOW_DISC;
1198 else
1199 fs->ring_cookie = fltr->base.rxq;
1200 rc = 0;
1201
1202fltr_err:
1203 rcu_read_unlock();
1204
1205 return rc;
1206}
1207
1208static int bnxt_add_l2_cls_rule(struct bnxt *bp,
1209 struct ethtool_rx_flow_spec *fs)
1210{
1211 u32 ring = ethtool_get_flow_spec_ring(ring_cookie: fs->ring_cookie);
1212 u8 vf = ethtool_get_flow_spec_ring_vf(ring_cookie: fs->ring_cookie);
1213 struct ethhdr *h_ether = &fs->h_u.ether_spec;
1214 struct ethhdr *m_ether = &fs->m_u.ether_spec;
1215 struct bnxt_l2_filter *fltr;
1216 struct bnxt_l2_key key;
1217 u16 vnic_id;
1218 u8 flags;
1219 int rc;
1220
1221 if (BNXT_CHIP_P5_PLUS(bp))
1222 return -EOPNOTSUPP;
1223
1224 if (!is_broadcast_ether_addr(addr: m_ether->h_dest))
1225 return -EINVAL;
1226 ether_addr_copy(dst: key.dst_mac_addr, src: h_ether->h_dest);
1227 key.vlan = 0;
1228 if (fs->flow_type & FLOW_EXT) {
1229 struct ethtool_flow_ext *m_ext = &fs->m_ext;
1230 struct ethtool_flow_ext *h_ext = &fs->h_ext;
1231
1232 if (m_ext->vlan_tci != htons(0xfff) || !h_ext->vlan_tci)
1233 return -EINVAL;
1234 key.vlan = ntohs(h_ext->vlan_tci);
1235 }
1236
1237 if (vf) {
1238 flags = BNXT_ACT_FUNC_DST;
1239 vnic_id = 0xffff;
1240 vf--;
1241 } else {
1242 flags = BNXT_ACT_RING_DST;
1243 vnic_id = bp->vnic_info[ring + 1].fw_vnic_id;
1244 }
1245 fltr = bnxt_alloc_new_l2_filter(bp, key: &key, flags);
1246 if (IS_ERR(ptr: fltr))
1247 return PTR_ERR(ptr: fltr);
1248
1249 fltr->base.fw_vnic_id = vnic_id;
1250 fltr->base.rxq = ring;
1251 fltr->base.vf_idx = vf;
1252 rc = bnxt_hwrm_l2_filter_alloc(bp, fltr);
1253 if (rc)
1254 bnxt_del_l2_filter(bp, fltr);
1255 else
1256 fs->location = fltr->base.sw_id;
1257 return rc;
1258}
1259
1260static bool bnxt_verify_ntuple_ip4_flow(struct ethtool_usrip4_spec *ip_spec,
1261 struct ethtool_usrip4_spec *ip_mask)
1262{
1263 if (ip_mask->l4_4_bytes || ip_mask->tos ||
1264 ip_spec->ip_ver != ETH_RX_NFC_IP4 ||
1265 ip_mask->proto != BNXT_IP_PROTO_FULL_MASK ||
1266 (ip_spec->proto != IPPROTO_RAW && ip_spec->proto != IPPROTO_ICMP))
1267 return false;
1268 return true;
1269}
1270
1271static bool bnxt_verify_ntuple_ip6_flow(struct ethtool_usrip6_spec *ip_spec,
1272 struct ethtool_usrip6_spec *ip_mask)
1273{
1274 if (ip_mask->l4_4_bytes || ip_mask->tclass ||
1275 ip_mask->l4_proto != BNXT_IP_PROTO_FULL_MASK ||
1276 (ip_spec->l4_proto != IPPROTO_RAW &&
1277 ip_spec->l4_proto != IPPROTO_ICMPV6))
1278 return false;
1279 return true;
1280}
1281
1282static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
1283 struct ethtool_rx_flow_spec *fs)
1284{
1285 u8 vf = ethtool_get_flow_spec_ring_vf(ring_cookie: fs->ring_cookie);
1286 u32 ring = ethtool_get_flow_spec_ring(ring_cookie: fs->ring_cookie);
1287 struct bnxt_ntuple_filter *new_fltr, *fltr;
1288 struct bnxt_l2_filter *l2_fltr;
1289 struct bnxt_flow_masks *fmasks;
1290 u32 flow_type = fs->flow_type;
1291 struct flow_keys *fkeys;
1292 u32 idx;
1293 int rc;
1294
1295 if (!bp->vnic_info)
1296 return -EAGAIN;
1297
1298 if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf)
1299 return -EOPNOTSUPP;
1300
1301 if (flow_type == IP_USER_FLOW) {
1302 if (!bnxt_verify_ntuple_ip4_flow(ip_spec: &fs->h_u.usr_ip4_spec,
1303 ip_mask: &fs->m_u.usr_ip4_spec))
1304 return -EOPNOTSUPP;
1305 }
1306
1307 if (flow_type == IPV6_USER_FLOW) {
1308 if (!bnxt_verify_ntuple_ip6_flow(ip_spec: &fs->h_u.usr_ip6_spec,
1309 ip_mask: &fs->m_u.usr_ip6_spec))
1310 return -EOPNOTSUPP;
1311 }
1312
1313 new_fltr = kzalloc(size: sizeof(*new_fltr), GFP_KERNEL);
1314 if (!new_fltr)
1315 return -ENOMEM;
1316
1317 l2_fltr = bp->vnic_info[BNXT_VNIC_DEFAULT].l2_filters[0];
1318 atomic_inc(v: &l2_fltr->refcnt);
1319 new_fltr->l2_fltr = l2_fltr;
1320 fmasks = &new_fltr->fmasks;
1321 fkeys = &new_fltr->fkeys;
1322
1323 rc = -EOPNOTSUPP;
1324 switch (flow_type) {
1325 case IP_USER_FLOW: {
1326 struct ethtool_usrip4_spec *ip_spec = &fs->h_u.usr_ip4_spec;
1327 struct ethtool_usrip4_spec *ip_mask = &fs->m_u.usr_ip4_spec;
1328
1329 fkeys->basic.ip_proto = ip_spec->proto;
1330 fkeys->basic.n_proto = htons(ETH_P_IP);
1331 fkeys->addrs.v4addrs.src = ip_spec->ip4src;
1332 fmasks->addrs.v4addrs.src = ip_mask->ip4src;
1333 fkeys->addrs.v4addrs.dst = ip_spec->ip4dst;
1334 fmasks->addrs.v4addrs.dst = ip_mask->ip4dst;
1335 break;
1336 }
1337 case TCP_V4_FLOW:
1338 case UDP_V4_FLOW: {
1339 struct ethtool_tcpip4_spec *ip_spec = &fs->h_u.tcp_ip4_spec;
1340 struct ethtool_tcpip4_spec *ip_mask = &fs->m_u.tcp_ip4_spec;
1341
1342 fkeys->basic.ip_proto = IPPROTO_TCP;
1343 if (flow_type == UDP_V4_FLOW)
1344 fkeys->basic.ip_proto = IPPROTO_UDP;
1345 fkeys->basic.n_proto = htons(ETH_P_IP);
1346 fkeys->addrs.v4addrs.src = ip_spec->ip4src;
1347 fmasks->addrs.v4addrs.src = ip_mask->ip4src;
1348 fkeys->addrs.v4addrs.dst = ip_spec->ip4dst;
1349 fmasks->addrs.v4addrs.dst = ip_mask->ip4dst;
1350 fkeys->ports.src = ip_spec->psrc;
1351 fmasks->ports.src = ip_mask->psrc;
1352 fkeys->ports.dst = ip_spec->pdst;
1353 fmasks->ports.dst = ip_mask->pdst;
1354 break;
1355 }
1356 case IPV6_USER_FLOW: {
1357 struct ethtool_usrip6_spec *ip_spec = &fs->h_u.usr_ip6_spec;
1358 struct ethtool_usrip6_spec *ip_mask = &fs->m_u.usr_ip6_spec;
1359
1360 fkeys->basic.ip_proto = ip_spec->l4_proto;
1361 fkeys->basic.n_proto = htons(ETH_P_IPV6);
1362 fkeys->addrs.v6addrs.src = *(struct in6_addr *)&ip_spec->ip6src;
1363 fmasks->addrs.v6addrs.src = *(struct in6_addr *)&ip_mask->ip6src;
1364 fkeys->addrs.v6addrs.dst = *(struct in6_addr *)&ip_spec->ip6dst;
1365 fmasks->addrs.v6addrs.dst = *(struct in6_addr *)&ip_mask->ip6dst;
1366 break;
1367 }
1368 case TCP_V6_FLOW:
1369 case UDP_V6_FLOW: {
1370 struct ethtool_tcpip6_spec *ip_spec = &fs->h_u.tcp_ip6_spec;
1371 struct ethtool_tcpip6_spec *ip_mask = &fs->m_u.tcp_ip6_spec;
1372
1373 fkeys->basic.ip_proto = IPPROTO_TCP;
1374 if (flow_type == UDP_V6_FLOW)
1375 fkeys->basic.ip_proto = IPPROTO_UDP;
1376 fkeys->basic.n_proto = htons(ETH_P_IPV6);
1377
1378 fkeys->addrs.v6addrs.src = *(struct in6_addr *)&ip_spec->ip6src;
1379 fmasks->addrs.v6addrs.src = *(struct in6_addr *)&ip_mask->ip6src;
1380 fkeys->addrs.v6addrs.dst = *(struct in6_addr *)&ip_spec->ip6dst;
1381 fmasks->addrs.v6addrs.dst = *(struct in6_addr *)&ip_mask->ip6dst;
1382 fkeys->ports.src = ip_spec->psrc;
1383 fmasks->ports.src = ip_mask->psrc;
1384 fkeys->ports.dst = ip_spec->pdst;
1385 fmasks->ports.dst = ip_mask->pdst;
1386 break;
1387 }
1388 default:
1389 rc = -EOPNOTSUPP;
1390 goto ntuple_err;
1391 }
1392 if (!memcmp(p: &BNXT_FLOW_MASK_NONE, q: fmasks, size: sizeof(*fmasks)))
1393 goto ntuple_err;
1394
1395 idx = bnxt_get_ntp_filter_idx(bp, fkeys, NULL);
1396 rcu_read_lock();
1397 fltr = bnxt_lookup_ntp_filter_from_idx(bp, fltr: new_fltr, idx);
1398 if (fltr) {
1399 rcu_read_unlock();
1400 rc = -EEXIST;
1401 goto ntuple_err;
1402 }
1403 rcu_read_unlock();
1404
1405 new_fltr->base.flags = BNXT_ACT_NO_AGING;
1406 if (fs->ring_cookie == RX_CLS_FLOW_DISC)
1407 new_fltr->base.flags |= BNXT_ACT_DROP;
1408 else
1409 new_fltr->base.rxq = ring;
1410 __set_bit(BNXT_FLTR_VALID, &new_fltr->base.state);
1411 rc = bnxt_insert_ntp_filter(bp, fltr: new_fltr, idx);
1412 if (!rc) {
1413 rc = bnxt_hwrm_cfa_ntuple_filter_alloc(bp, fltr: new_fltr);
1414 if (rc) {
1415 bnxt_del_ntp_filter(bp, fltr: new_fltr);
1416 return rc;
1417 }
1418 fs->location = new_fltr->base.sw_id;
1419 return 0;
1420 }
1421
1422ntuple_err:
1423 atomic_dec(v: &l2_fltr->refcnt);
1424 kfree(objp: new_fltr);
1425 return rc;
1426}
1427
1428static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
1429{
1430 struct ethtool_rx_flow_spec *fs = &cmd->fs;
1431 u32 ring, flow_type;
1432 int rc;
1433 u8 vf;
1434
1435 if (!netif_running(dev: bp->dev))
1436 return -EAGAIN;
1437 if (!(bp->flags & BNXT_FLAG_RFS))
1438 return -EPERM;
1439 if (fs->location != RX_CLS_LOC_ANY)
1440 return -EINVAL;
1441
1442 flow_type = fs->flow_type;
1443 if ((flow_type == IP_USER_FLOW ||
1444 flow_type == IPV6_USER_FLOW) &&
1445 !(bp->fw_cap & BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO))
1446 return -EOPNOTSUPP;
1447 if (flow_type & (FLOW_MAC_EXT | FLOW_RSS))
1448 return -EINVAL;
1449 flow_type &= ~FLOW_EXT;
1450
1451 if (fs->ring_cookie == RX_CLS_FLOW_DISC && flow_type != ETHER_FLOW)
1452 return bnxt_add_ntuple_cls_rule(bp, fs);
1453
1454 ring = ethtool_get_flow_spec_ring(ring_cookie: fs->ring_cookie);
1455 vf = ethtool_get_flow_spec_ring_vf(ring_cookie: fs->ring_cookie);
1456 if (BNXT_VF(bp) && vf)
1457 return -EINVAL;
1458 if (BNXT_PF(bp) && vf > bp->pf.active_vfs)
1459 return -EINVAL;
1460 if (!vf && ring >= bp->rx_nr_rings)
1461 return -EINVAL;
1462
1463 if (flow_type == ETHER_FLOW)
1464 rc = bnxt_add_l2_cls_rule(bp, fs);
1465 else
1466 rc = bnxt_add_ntuple_cls_rule(bp, fs);
1467 return rc;
1468}
1469
1470static int bnxt_srxclsrldel(struct bnxt *bp, struct ethtool_rxnfc *cmd)
1471{
1472 struct ethtool_rx_flow_spec *fs = &cmd->fs;
1473 struct bnxt_filter_base *fltr_base;
1474 struct bnxt_ntuple_filter *fltr;
1475 u32 id = fs->location;
1476
1477 rcu_read_lock();
1478 fltr_base = bnxt_get_one_fltr_rcu(bp, tbl: bp->l2_fltr_hash_tbl,
1479 BNXT_L2_FLTR_HASH_SIZE, id);
1480 if (fltr_base) {
1481 struct bnxt_l2_filter *l2_fltr;
1482
1483 l2_fltr = container_of(fltr_base, struct bnxt_l2_filter, base);
1484 rcu_read_unlock();
1485 bnxt_hwrm_l2_filter_free(bp, fltr: l2_fltr);
1486 bnxt_del_l2_filter(bp, fltr: l2_fltr);
1487 return 0;
1488 }
1489 fltr_base = bnxt_get_one_fltr_rcu(bp, tbl: bp->ntp_fltr_hash_tbl,
1490 BNXT_NTP_FLTR_HASH_SIZE, id);
1491 if (!fltr_base) {
1492 rcu_read_unlock();
1493 return -ENOENT;
1494 }
1495
1496 fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
1497 if (!(fltr->base.flags & BNXT_ACT_NO_AGING)) {
1498 rcu_read_unlock();
1499 return -EINVAL;
1500 }
1501 rcu_read_unlock();
1502 bnxt_hwrm_cfa_ntuple_filter_free(bp, fltr);
1503 bnxt_del_ntp_filter(bp, fltr);
1504 return 0;
1505}
1506
1507static u64 get_ethtool_ipv4_rss(struct bnxt *bp)
1508{
1509 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4)
1510 return RXH_IP_SRC | RXH_IP_DST;
1511 return 0;
1512}
1513
1514static u64 get_ethtool_ipv6_rss(struct bnxt *bp)
1515{
1516 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6)
1517 return RXH_IP_SRC | RXH_IP_DST;
1518 return 0;
1519}
1520
1521static int bnxt_grxfh(struct bnxt *bp, struct ethtool_rxnfc *cmd)
1522{
1523 cmd->data = 0;
1524 switch (cmd->flow_type) {
1525 case TCP_V4_FLOW:
1526 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4)
1527 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1528 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1529 cmd->data |= get_ethtool_ipv4_rss(bp);
1530 break;
1531 case UDP_V4_FLOW:
1532 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4)
1533 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1534 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1535 fallthrough;
1536 case AH_ESP_V4_FLOW:
1537 if (bp->rss_hash_cfg &
1538 (VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 |
1539 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4))
1540 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1541 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1542 fallthrough;
1543 case SCTP_V4_FLOW:
1544 case AH_V4_FLOW:
1545 case ESP_V4_FLOW:
1546 case IPV4_FLOW:
1547 cmd->data |= get_ethtool_ipv4_rss(bp);
1548 break;
1549
1550 case TCP_V6_FLOW:
1551 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6)
1552 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1553 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1554 cmd->data |= get_ethtool_ipv6_rss(bp);
1555 break;
1556 case UDP_V6_FLOW:
1557 if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6)
1558 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1559 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1560 fallthrough;
1561 case AH_ESP_V6_FLOW:
1562 if (bp->rss_hash_cfg &
1563 (VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 |
1564 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6))
1565 cmd->data |= RXH_IP_SRC | RXH_IP_DST |
1566 RXH_L4_B_0_1 | RXH_L4_B_2_3;
1567 fallthrough;
1568 case SCTP_V6_FLOW:
1569 case AH_V6_FLOW:
1570 case ESP_V6_FLOW:
1571 case IPV6_FLOW:
1572 cmd->data |= get_ethtool_ipv6_rss(bp);
1573 break;
1574 }
1575 return 0;
1576}
1577
1578#define RXH_4TUPLE (RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3)
1579#define RXH_2TUPLE (RXH_IP_SRC | RXH_IP_DST)
1580
1581static int bnxt_srxfh(struct bnxt *bp, struct ethtool_rxnfc *cmd)
1582{
1583 u32 rss_hash_cfg = bp->rss_hash_cfg;
1584 int tuple, rc = 0;
1585
1586 if (cmd->data == RXH_4TUPLE)
1587 tuple = 4;
1588 else if (cmd->data == RXH_2TUPLE)
1589 tuple = 2;
1590 else if (!cmd->data)
1591 tuple = 0;
1592 else
1593 return -EINVAL;
1594
1595 if (cmd->flow_type == TCP_V4_FLOW) {
1596 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4;
1597 if (tuple == 4)
1598 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4;
1599 } else if (cmd->flow_type == UDP_V4_FLOW) {
1600 if (tuple == 4 && !(bp->rss_cap & BNXT_RSS_CAP_UDP_RSS_CAP))
1601 return -EINVAL;
1602 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4;
1603 if (tuple == 4)
1604 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4;
1605 } else if (cmd->flow_type == TCP_V6_FLOW) {
1606 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
1607 if (tuple == 4)
1608 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
1609 } else if (cmd->flow_type == UDP_V6_FLOW) {
1610 if (tuple == 4 && !(bp->rss_cap & BNXT_RSS_CAP_UDP_RSS_CAP))
1611 return -EINVAL;
1612 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
1613 if (tuple == 4)
1614 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
1615 } else if (cmd->flow_type == AH_ESP_V4_FLOW) {
1616 if (tuple == 4 && (!(bp->rss_cap & BNXT_RSS_CAP_AH_V4_RSS_CAP) ||
1617 !(bp->rss_cap & BNXT_RSS_CAP_ESP_V4_RSS_CAP)))
1618 return -EINVAL;
1619 rss_hash_cfg &= ~(VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 |
1620 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4);
1621 if (tuple == 4)
1622 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV4 |
1623 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV4;
1624 } else if (cmd->flow_type == AH_ESP_V6_FLOW) {
1625 if (tuple == 4 && (!(bp->rss_cap & BNXT_RSS_CAP_AH_V6_RSS_CAP) ||
1626 !(bp->rss_cap & BNXT_RSS_CAP_ESP_V6_RSS_CAP)))
1627 return -EINVAL;
1628 rss_hash_cfg &= ~(VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 |
1629 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6);
1630 if (tuple == 4)
1631 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_AH_SPI_IPV6 |
1632 VNIC_RSS_CFG_REQ_HASH_TYPE_ESP_SPI_IPV6;
1633 } else if (tuple == 4) {
1634 return -EINVAL;
1635 }
1636
1637 switch (cmd->flow_type) {
1638 case TCP_V4_FLOW:
1639 case UDP_V4_FLOW:
1640 case SCTP_V4_FLOW:
1641 case AH_ESP_V4_FLOW:
1642 case AH_V4_FLOW:
1643 case ESP_V4_FLOW:
1644 case IPV4_FLOW:
1645 if (tuple == 2)
1646 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4;
1647 else if (!tuple)
1648 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4;
1649 break;
1650
1651 case TCP_V6_FLOW:
1652 case UDP_V6_FLOW:
1653 case SCTP_V6_FLOW:
1654 case AH_ESP_V6_FLOW:
1655 case AH_V6_FLOW:
1656 case ESP_V6_FLOW:
1657 case IPV6_FLOW:
1658 if (tuple == 2)
1659 rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6;
1660 else if (!tuple)
1661 rss_hash_cfg &= ~VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6;
1662 break;
1663 }
1664
1665 if (bp->rss_hash_cfg == rss_hash_cfg)
1666 return 0;
1667
1668 if (bp->rss_cap & BNXT_RSS_CAP_RSS_HASH_TYPE_DELTA)
1669 bp->rss_hash_delta = bp->rss_hash_cfg ^ rss_hash_cfg;
1670 bp->rss_hash_cfg = rss_hash_cfg;
1671 if (netif_running(dev: bp->dev)) {
1672 bnxt_close_nic(bp, false, false);
1673 rc = bnxt_open_nic(bp, false, false);
1674 }
1675 return rc;
1676}
1677
1678static int bnxt_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
1679 u32 *rule_locs)
1680{
1681 struct bnxt *bp = netdev_priv(dev);
1682 int rc = 0;
1683
1684 switch (cmd->cmd) {
1685 case ETHTOOL_GRXRINGS:
1686 cmd->data = bp->rx_nr_rings;
1687 break;
1688
1689 case ETHTOOL_GRXCLSRLCNT:
1690 cmd->rule_cnt = bp->ntp_fltr_count;
1691 cmd->data = bp->max_fltr | RX_CLS_LOC_SPECIAL;
1692 break;
1693
1694 case ETHTOOL_GRXCLSRLALL:
1695 rc = bnxt_grxclsrlall(bp, cmd, rule_locs: (u32 *)rule_locs);
1696 break;
1697
1698 case ETHTOOL_GRXCLSRULE:
1699 rc = bnxt_grxclsrule(bp, cmd);
1700 break;
1701
1702 case ETHTOOL_GRXFH:
1703 rc = bnxt_grxfh(bp, cmd);
1704 break;
1705
1706 default:
1707 rc = -EOPNOTSUPP;
1708 break;
1709 }
1710
1711 return rc;
1712}
1713
1714static int bnxt_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1715{
1716 struct bnxt *bp = netdev_priv(dev);
1717 int rc;
1718
1719 switch (cmd->cmd) {
1720 case ETHTOOL_SRXFH:
1721 rc = bnxt_srxfh(bp, cmd);
1722 break;
1723
1724 case ETHTOOL_SRXCLSRLINS:
1725 rc = bnxt_srxclsrlins(bp, cmd);
1726 break;
1727
1728 case ETHTOOL_SRXCLSRLDEL:
1729 rc = bnxt_srxclsrldel(bp, cmd);
1730 break;
1731
1732 default:
1733 rc = -EOPNOTSUPP;
1734 break;
1735 }
1736 return rc;
1737}
1738
1739u32 bnxt_get_rxfh_indir_size(struct net_device *dev)
1740{
1741 struct bnxt *bp = netdev_priv(dev);
1742
1743 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS)
1744 return bnxt_get_nr_rss_ctxs(bp, rx_rings: bp->rx_nr_rings) *
1745 BNXT_RSS_TABLE_ENTRIES_P5;
1746 return HW_HASH_INDEX_SIZE;
1747}
1748
1749static u32 bnxt_get_rxfh_key_size(struct net_device *dev)
1750{
1751 return HW_HASH_KEY_SIZE;
1752}
1753
1754static int bnxt_get_rxfh(struct net_device *dev,
1755 struct ethtool_rxfh_param *rxfh)
1756{
1757 struct bnxt *bp = netdev_priv(dev);
1758 struct bnxt_vnic_info *vnic;
1759 u32 i, tbl_size;
1760
1761 rxfh->hfunc = ETH_RSS_HASH_TOP;
1762
1763 if (!bp->vnic_info)
1764 return 0;
1765
1766 vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT];
1767 if (rxfh->indir && bp->rss_indir_tbl) {
1768 tbl_size = bnxt_get_rxfh_indir_size(dev);
1769 for (i = 0; i < tbl_size; i++)
1770 rxfh->indir[i] = bp->rss_indir_tbl[i];
1771 }
1772
1773 if (rxfh->key && vnic->rss_hash_key)
1774 memcpy(rxfh->key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);
1775
1776 return 0;
1777}
1778
1779static int bnxt_set_rxfh(struct net_device *dev,
1780 struct ethtool_rxfh_param *rxfh,
1781 struct netlink_ext_ack *extack)
1782{
1783 struct bnxt *bp = netdev_priv(dev);
1784 int rc = 0;
1785
1786 if (rxfh->hfunc && rxfh->hfunc != ETH_RSS_HASH_TOP)
1787 return -EOPNOTSUPP;
1788
1789 if (rxfh->key) {
1790 memcpy(bp->rss_hash_key, rxfh->key, HW_HASH_KEY_SIZE);
1791 bp->rss_hash_key_updated = true;
1792 }
1793
1794 if (rxfh->indir) {
1795 u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(dev);
1796
1797 for (i = 0; i < tbl_size; i++)
1798 bp->rss_indir_tbl[i] = rxfh->indir[i];
1799 pad = bp->rss_indir_tbl_entries - tbl_size;
1800 if (pad)
1801 memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
1802 }
1803 bnxt_clear_usr_fltrs(bp, all: false);
1804 if (netif_running(dev: bp->dev)) {
1805 bnxt_close_nic(bp, false, false);
1806 rc = bnxt_open_nic(bp, false, false);
1807 }
1808 return rc;
1809}
1810
1811static void bnxt_get_drvinfo(struct net_device *dev,
1812 struct ethtool_drvinfo *info)
1813{
1814 struct bnxt *bp = netdev_priv(dev);
1815
1816 strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
1817 strscpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version));
1818 strscpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
1819 info->n_stats = bnxt_get_num_stats(bp);
1820 info->testinfo_len = bp->num_tests;
1821 /* TODO CHIMP_FW: eeprom dump details */
1822 info->eedump_len = 0;
1823 /* TODO CHIMP FW: reg dump details */
1824 info->regdump_len = 0;
1825}
1826
1827static int bnxt_get_regs_len(struct net_device *dev)
1828{
1829 struct bnxt *bp = netdev_priv(dev);
1830 int reg_len;
1831
1832 if (!BNXT_PF(bp))
1833 return -EOPNOTSUPP;
1834
1835 reg_len = BNXT_PXP_REG_LEN;
1836
1837 if (bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED)
1838 reg_len += sizeof(struct pcie_ctx_hw_stats);
1839
1840 return reg_len;
1841}
1842
1843static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
1844 void *_p)
1845{
1846 struct pcie_ctx_hw_stats *hw_pcie_stats;
1847 struct hwrm_pcie_qstats_input *req;
1848 struct bnxt *bp = netdev_priv(dev);
1849 dma_addr_t hw_pcie_stats_addr;
1850 int rc;
1851
1852 regs->version = 0;
1853 bnxt_dbg_hwrm_rd_reg(bp, reg_off: 0, BNXT_PXP_REG_LEN / 4, reg_buf: _p);
1854
1855 if (!(bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED))
1856 return;
1857
1858 if (hwrm_req_init(bp, req, HWRM_PCIE_QSTATS))
1859 return;
1860
1861 hw_pcie_stats = hwrm_req_dma_slice(bp, req, size: sizeof(*hw_pcie_stats),
1862 dma: &hw_pcie_stats_addr);
1863 if (!hw_pcie_stats) {
1864 hwrm_req_drop(bp, req);
1865 return;
1866 }
1867
1868 regs->version = 1;
1869 hwrm_req_hold(bp, req); /* hold on to slice */
1870 req->pcie_stat_size = cpu_to_le16(sizeof(*hw_pcie_stats));
1871 req->pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
1872 rc = hwrm_req_send(bp, req);
1873 if (!rc) {
1874 __le64 *src = (__le64 *)hw_pcie_stats;
1875 u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
1876 int i;
1877
1878 for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
1879 dst[i] = le64_to_cpu(src[i]);
1880 }
1881 hwrm_req_drop(bp, req);
1882}
1883
1884static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1885{
1886 struct bnxt *bp = netdev_priv(dev);
1887
1888 wol->supported = 0;
1889 wol->wolopts = 0;
1890 memset(&wol->sopass, 0, sizeof(wol->sopass));
1891 if (bp->flags & BNXT_FLAG_WOL_CAP) {
1892 wol->supported = WAKE_MAGIC;
1893 if (bp->wol)
1894 wol->wolopts = WAKE_MAGIC;
1895 }
1896}
1897
1898static int bnxt_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
1899{
1900 struct bnxt *bp = netdev_priv(dev);
1901
1902 if (wol->wolopts & ~WAKE_MAGIC)
1903 return -EINVAL;
1904
1905 if (wol->wolopts & WAKE_MAGIC) {
1906 if (!(bp->flags & BNXT_FLAG_WOL_CAP))
1907 return -EINVAL;
1908 if (!bp->wol) {
1909 if (bnxt_hwrm_alloc_wol_fltr(bp))
1910 return -EBUSY;
1911 bp->wol = 1;
1912 }
1913 } else {
1914 if (bp->wol) {
1915 if (bnxt_hwrm_free_wol_fltr(bp))
1916 return -EBUSY;
1917 bp->wol = 0;
1918 }
1919 }
1920 return 0;
1921}
1922
1923/* TODO: support 25GB, 40GB, 50GB with different cable type */
1924void _bnxt_fw_to_linkmode(unsigned long *mode, u16 fw_speeds)
1925{
1926 linkmode_zero(dst: mode);
1927
1928 if (fw_speeds & BNXT_LINK_SPEED_MSK_100MB)
1929 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_100baseT_Full_BIT, addr: mode);
1930 if (fw_speeds & BNXT_LINK_SPEED_MSK_1GB)
1931 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_1000baseT_Full_BIT, addr: mode);
1932 if (fw_speeds & BNXT_LINK_SPEED_MSK_2_5GB)
1933 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_2500baseX_Full_BIT, addr: mode);
1934 if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
1935 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_10000baseT_Full_BIT, addr: mode);
1936 if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
1937 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, addr: mode);
1938}
1939
1940enum bnxt_media_type {
1941 BNXT_MEDIA_UNKNOWN = 0,
1942 BNXT_MEDIA_TP,
1943 BNXT_MEDIA_CR,
1944 BNXT_MEDIA_SR,
1945 BNXT_MEDIA_LR_ER_FR,
1946 BNXT_MEDIA_KR,
1947 BNXT_MEDIA_KX,
1948 BNXT_MEDIA_X,
1949 __BNXT_MEDIA_END,
1950};
1951
1952static const enum bnxt_media_type bnxt_phy_types[] = {
1953 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASECR] = BNXT_MEDIA_CR,
1954 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR4] = BNXT_MEDIA_KR,
1955 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASELR] = BNXT_MEDIA_LR_ER_FR,
1956 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASESR] = BNXT_MEDIA_SR,
1957 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR2] = BNXT_MEDIA_KR,
1958 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKX] = BNXT_MEDIA_KX,
1959 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASEKR] = BNXT_MEDIA_KR,
1960 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASET] = BNXT_MEDIA_TP,
1961 [PORT_PHY_QCFG_RESP_PHY_TYPE_BASETE] = BNXT_MEDIA_TP,
1962 [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_L] = BNXT_MEDIA_CR,
1963 [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_S] = BNXT_MEDIA_CR,
1964 [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASECR_CA_N] = BNXT_MEDIA_CR,
1965 [PORT_PHY_QCFG_RESP_PHY_TYPE_25G_BASESR] = BNXT_MEDIA_SR,
1966 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR4] = BNXT_MEDIA_CR,
1967 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR4] = BNXT_MEDIA_SR,
1968 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR4] = BNXT_MEDIA_LR_ER_FR,
1969 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER4] = BNXT_MEDIA_LR_ER_FR,
1970 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR10] = BNXT_MEDIA_SR,
1971 [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASECR4] = BNXT_MEDIA_CR,
1972 [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASESR4] = BNXT_MEDIA_SR,
1973 [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASELR4] = BNXT_MEDIA_LR_ER_FR,
1974 [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_BASEER4] = BNXT_MEDIA_LR_ER_FR,
1975 [PORT_PHY_QCFG_RESP_PHY_TYPE_40G_ACTIVE_CABLE] = BNXT_MEDIA_SR,
1976 [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASET] = BNXT_MEDIA_TP,
1977 [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASESX] = BNXT_MEDIA_X,
1978 [PORT_PHY_QCFG_RESP_PHY_TYPE_1G_BASECX] = BNXT_MEDIA_X,
1979 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR4] = BNXT_MEDIA_CR,
1980 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR4] = BNXT_MEDIA_SR,
1981 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR4] = BNXT_MEDIA_LR_ER_FR,
1982 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER4] = BNXT_MEDIA_LR_ER_FR,
1983 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASECR] = BNXT_MEDIA_CR,
1984 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASESR] = BNXT_MEDIA_SR,
1985 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASELR] = BNXT_MEDIA_LR_ER_FR,
1986 [PORT_PHY_QCFG_RESP_PHY_TYPE_50G_BASEER] = BNXT_MEDIA_LR_ER_FR,
1987 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR2] = BNXT_MEDIA_CR,
1988 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR2] = BNXT_MEDIA_SR,
1989 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR2] = BNXT_MEDIA_LR_ER_FR,
1990 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER2] = BNXT_MEDIA_LR_ER_FR,
1991 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR] = BNXT_MEDIA_CR,
1992 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR] = BNXT_MEDIA_SR,
1993 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR] = BNXT_MEDIA_LR_ER_FR,
1994 [PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER] = BNXT_MEDIA_LR_ER_FR,
1995 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR2] = BNXT_MEDIA_CR,
1996 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR2] = BNXT_MEDIA_SR,
1997 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR2] = BNXT_MEDIA_LR_ER_FR,
1998 [PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER2] = BNXT_MEDIA_LR_ER_FR,
1999 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR8] = BNXT_MEDIA_CR,
2000 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR8] = BNXT_MEDIA_SR,
2001 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR8] = BNXT_MEDIA_LR_ER_FR,
2002 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER8] = BNXT_MEDIA_LR_ER_FR,
2003 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR4] = BNXT_MEDIA_CR,
2004 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR4] = BNXT_MEDIA_SR,
2005 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR4] = BNXT_MEDIA_LR_ER_FR,
2006 [PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4] = BNXT_MEDIA_LR_ER_FR,
2007};
2008
2009static enum bnxt_media_type
2010bnxt_get_media(struct bnxt_link_info *link_info)
2011{
2012 switch (link_info->media_type) {
2013 case PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP:
2014 return BNXT_MEDIA_TP;
2015 case PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC:
2016 return BNXT_MEDIA_CR;
2017 default:
2018 if (link_info->phy_type < ARRAY_SIZE(bnxt_phy_types))
2019 return bnxt_phy_types[link_info->phy_type];
2020 return BNXT_MEDIA_UNKNOWN;
2021 }
2022}
2023
2024enum bnxt_link_speed_indices {
2025 BNXT_LINK_SPEED_UNKNOWN = 0,
2026 BNXT_LINK_SPEED_100MB_IDX,
2027 BNXT_LINK_SPEED_1GB_IDX,
2028 BNXT_LINK_SPEED_10GB_IDX,
2029 BNXT_LINK_SPEED_25GB_IDX,
2030 BNXT_LINK_SPEED_40GB_IDX,
2031 BNXT_LINK_SPEED_50GB_IDX,
2032 BNXT_LINK_SPEED_100GB_IDX,
2033 BNXT_LINK_SPEED_200GB_IDX,
2034 BNXT_LINK_SPEED_400GB_IDX,
2035 __BNXT_LINK_SPEED_END
2036};
2037
2038static enum bnxt_link_speed_indices bnxt_fw_speed_idx(u16 speed)
2039{
2040 switch (speed) {
2041 case BNXT_LINK_SPEED_100MB: return BNXT_LINK_SPEED_100MB_IDX;
2042 case BNXT_LINK_SPEED_1GB: return BNXT_LINK_SPEED_1GB_IDX;
2043 case BNXT_LINK_SPEED_10GB: return BNXT_LINK_SPEED_10GB_IDX;
2044 case BNXT_LINK_SPEED_25GB: return BNXT_LINK_SPEED_25GB_IDX;
2045 case BNXT_LINK_SPEED_40GB: return BNXT_LINK_SPEED_40GB_IDX;
2046 case BNXT_LINK_SPEED_50GB:
2047 case BNXT_LINK_SPEED_50GB_PAM4:
2048 return BNXT_LINK_SPEED_50GB_IDX;
2049 case BNXT_LINK_SPEED_100GB:
2050 case BNXT_LINK_SPEED_100GB_PAM4:
2051 case BNXT_LINK_SPEED_100GB_PAM4_112:
2052 return BNXT_LINK_SPEED_100GB_IDX;
2053 case BNXT_LINK_SPEED_200GB:
2054 case BNXT_LINK_SPEED_200GB_PAM4:
2055 case BNXT_LINK_SPEED_200GB_PAM4_112:
2056 return BNXT_LINK_SPEED_200GB_IDX;
2057 case BNXT_LINK_SPEED_400GB:
2058 case BNXT_LINK_SPEED_400GB_PAM4:
2059 case BNXT_LINK_SPEED_400GB_PAM4_112:
2060 return BNXT_LINK_SPEED_400GB_IDX;
2061 default: return BNXT_LINK_SPEED_UNKNOWN;
2062 }
2063}
2064
2065static const enum ethtool_link_mode_bit_indices
2066bnxt_link_modes[__BNXT_LINK_SPEED_END][BNXT_SIG_MODE_MAX][__BNXT_MEDIA_END] = {
2067 [BNXT_LINK_SPEED_100MB_IDX] = {
2068 {
2069 [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
2070 },
2071 },
2072 [BNXT_LINK_SPEED_1GB_IDX] = {
2073 {
2074 [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
2075 /* historically baseT, but DAC is more correctly baseX */
2076 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
2077 [BNXT_MEDIA_KX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2078 [BNXT_MEDIA_X] = ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
2079 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2080 },
2081 },
2082 [BNXT_LINK_SPEED_10GB_IDX] = {
2083 {
2084 [BNXT_MEDIA_TP] = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2085 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
2086 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
2087 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
2088 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2089 [BNXT_MEDIA_KX] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
2090 },
2091 },
2092 [BNXT_LINK_SPEED_25GB_IDX] = {
2093 {
2094 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2095 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2096 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2097 },
2098 },
2099 [BNXT_LINK_SPEED_40GB_IDX] = {
2100 {
2101 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2102 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2103 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2104 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2105 },
2106 },
2107 [BNXT_LINK_SPEED_50GB_IDX] = {
2108 [BNXT_SIG_MODE_NRZ] = {
2109 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2110 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2111 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2112 },
2113 [BNXT_SIG_MODE_PAM4] = {
2114 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
2115 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
2116 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
2117 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
2118 },
2119 },
2120 [BNXT_LINK_SPEED_100GB_IDX] = {
2121 [BNXT_SIG_MODE_NRZ] = {
2122 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2123 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2124 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2125 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2126 },
2127 [BNXT_SIG_MODE_PAM4] = {
2128 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
2129 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
2130 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
2131 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
2132 },
2133 [BNXT_SIG_MODE_PAM4_112] = {
2134 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR_Full_BIT,
2135 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
2136 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
2137 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
2138 },
2139 },
2140 [BNXT_LINK_SPEED_200GB_IDX] = {
2141 [BNXT_SIG_MODE_PAM4] = {
2142 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT,
2143 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
2144 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
2145 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
2146 },
2147 [BNXT_SIG_MODE_PAM4_112] = {
2148 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT,
2149 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
2150 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
2151 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
2152 },
2153 },
2154 [BNXT_LINK_SPEED_400GB_IDX] = {
2155 [BNXT_SIG_MODE_PAM4] = {
2156 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT,
2157 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
2158 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
2159 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
2160 },
2161 [BNXT_SIG_MODE_PAM4_112] = {
2162 [BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT,
2163 [BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
2164 [BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
2165 [BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
2166 },
2167 },
2168};
2169
2170#define BNXT_LINK_MODE_UNKNOWN -1
2171
2172static enum ethtool_link_mode_bit_indices
2173bnxt_get_link_mode(struct bnxt_link_info *link_info)
2174{
2175 enum ethtool_link_mode_bit_indices link_mode;
2176 enum bnxt_link_speed_indices speed;
2177 enum bnxt_media_type media;
2178 u8 sig_mode;
2179
2180 if (link_info->phy_link_status != BNXT_LINK_LINK)
2181 return BNXT_LINK_MODE_UNKNOWN;
2182
2183 media = bnxt_get_media(link_info);
2184 if (BNXT_AUTO_MODE(link_info->auto_mode)) {
2185 speed = bnxt_fw_speed_idx(speed: link_info->link_speed);
2186 sig_mode = link_info->active_fec_sig_mode &
2187 PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK;
2188 } else {
2189 speed = bnxt_fw_speed_idx(speed: link_info->req_link_speed);
2190 sig_mode = link_info->req_signal_mode;
2191 }
2192 if (sig_mode >= BNXT_SIG_MODE_MAX)
2193 return BNXT_LINK_MODE_UNKNOWN;
2194
2195 /* Note ETHTOOL_LINK_MODE_10baseT_Half_BIT == 0 is a legal Linux
2196 * link mode, but since no such devices exist, the zeroes in the
2197 * map can be conveniently used to represent unknown link modes.
2198 */
2199 link_mode = bnxt_link_modes[speed][sig_mode][media];
2200 if (!link_mode)
2201 return BNXT_LINK_MODE_UNKNOWN;
2202
2203 switch (link_mode) {
2204 case ETHTOOL_LINK_MODE_100baseT_Full_BIT:
2205 if (~link_info->duplex & BNXT_LINK_DUPLEX_FULL)
2206 link_mode = ETHTOOL_LINK_MODE_100baseT_Half_BIT;
2207 break;
2208 case ETHTOOL_LINK_MODE_1000baseT_Full_BIT:
2209 if (~link_info->duplex & BNXT_LINK_DUPLEX_FULL)
2210 link_mode = ETHTOOL_LINK_MODE_1000baseT_Half_BIT;
2211 break;
2212 default:
2213 break;
2214 }
2215
2216 return link_mode;
2217}
2218
2219static void bnxt_get_ethtool_modes(struct bnxt_link_info *link_info,
2220 struct ethtool_link_ksettings *lk_ksettings)
2221{
2222 struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
2223
2224 if (!(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE)) {
2225 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Pause_BIT,
2226 addr: lk_ksettings->link_modes.supported);
2227 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2228 addr: lk_ksettings->link_modes.supported);
2229 }
2230
2231 if (link_info->support_auto_speeds || link_info->support_auto_speeds2 ||
2232 link_info->support_pam4_auto_speeds)
2233 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT,
2234 addr: lk_ksettings->link_modes.supported);
2235
2236 if (~link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL)
2237 return;
2238
2239 if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_RX)
2240 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Pause_BIT,
2241 addr: lk_ksettings->link_modes.advertising);
2242 if (hweight8(link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) == 1)
2243 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2244 addr: lk_ksettings->link_modes.advertising);
2245 if (link_info->lp_pause & BNXT_LINK_PAUSE_RX)
2246 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Pause_BIT,
2247 addr: lk_ksettings->link_modes.lp_advertising);
2248 if (hweight8(link_info->lp_pause & BNXT_LINK_PAUSE_BOTH) == 1)
2249 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Asym_Pause_BIT,
2250 addr: lk_ksettings->link_modes.lp_advertising);
2251}
2252
2253static const u16 bnxt_nrz_speed_masks[] = {
2254 [BNXT_LINK_SPEED_100MB_IDX] = BNXT_LINK_SPEED_MSK_100MB,
2255 [BNXT_LINK_SPEED_1GB_IDX] = BNXT_LINK_SPEED_MSK_1GB,
2256 [BNXT_LINK_SPEED_10GB_IDX] = BNXT_LINK_SPEED_MSK_10GB,
2257 [BNXT_LINK_SPEED_25GB_IDX] = BNXT_LINK_SPEED_MSK_25GB,
2258 [BNXT_LINK_SPEED_40GB_IDX] = BNXT_LINK_SPEED_MSK_40GB,
2259 [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEED_MSK_50GB,
2260 [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEED_MSK_100GB,
2261 [__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */
2262};
2263
2264static const u16 bnxt_pam4_speed_masks[] = {
2265 [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_50GB,
2266 [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_100GB,
2267 [BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_200GB,
2268 [__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */
2269};
2270
2271static const u16 bnxt_nrz_speeds2_masks[] = {
2272 [BNXT_LINK_SPEED_1GB_IDX] = BNXT_LINK_SPEEDS2_MSK_1GB,
2273 [BNXT_LINK_SPEED_10GB_IDX] = BNXT_LINK_SPEEDS2_MSK_10GB,
2274 [BNXT_LINK_SPEED_25GB_IDX] = BNXT_LINK_SPEEDS2_MSK_25GB,
2275 [BNXT_LINK_SPEED_40GB_IDX] = BNXT_LINK_SPEEDS2_MSK_40GB,
2276 [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEEDS2_MSK_50GB,
2277 [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB,
2278 [__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */
2279};
2280
2281static const u16 bnxt_pam4_speeds2_masks[] = {
2282 [BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEEDS2_MSK_50GB_PAM4,
2283 [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB_PAM4,
2284 [BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_SPEEDS2_MSK_200GB_PAM4,
2285 [BNXT_LINK_SPEED_400GB_IDX] = BNXT_LINK_SPEEDS2_MSK_400GB_PAM4,
2286};
2287
2288static const u16 bnxt_pam4_112_speeds2_masks[] = {
2289 [BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB_PAM4_112,
2290 [BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_SPEEDS2_MSK_200GB_PAM4_112,
2291 [BNXT_LINK_SPEED_400GB_IDX] = BNXT_LINK_SPEEDS2_MSK_400GB_PAM4_112,
2292};
2293
2294static enum bnxt_link_speed_indices
2295bnxt_encoding_speed_idx(u8 sig_mode, u16 phy_flags, u16 speed_msk)
2296{
2297 const u16 *speeds;
2298 int idx, len;
2299
2300 switch (sig_mode) {
2301 case BNXT_SIG_MODE_NRZ:
2302 if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
2303 speeds = bnxt_nrz_speeds2_masks;
2304 len = ARRAY_SIZE(bnxt_nrz_speeds2_masks);
2305 } else {
2306 speeds = bnxt_nrz_speed_masks;
2307 len = ARRAY_SIZE(bnxt_nrz_speed_masks);
2308 }
2309 break;
2310 case BNXT_SIG_MODE_PAM4:
2311 if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
2312 speeds = bnxt_pam4_speeds2_masks;
2313 len = ARRAY_SIZE(bnxt_pam4_speeds2_masks);
2314 } else {
2315 speeds = bnxt_pam4_speed_masks;
2316 len = ARRAY_SIZE(bnxt_pam4_speed_masks);
2317 }
2318 break;
2319 case BNXT_SIG_MODE_PAM4_112:
2320 speeds = bnxt_pam4_112_speeds2_masks;
2321 len = ARRAY_SIZE(bnxt_pam4_112_speeds2_masks);
2322 break;
2323 default:
2324 return BNXT_LINK_SPEED_UNKNOWN;
2325 }
2326
2327 for (idx = 0; idx < len; idx++) {
2328 if (speeds[idx] == speed_msk)
2329 return idx;
2330 }
2331
2332 return BNXT_LINK_SPEED_UNKNOWN;
2333}
2334
2335#define BNXT_FW_SPEED_MSK_BITS 16
2336
2337static void
2338__bnxt_get_ethtool_speeds(unsigned long fw_mask, enum bnxt_media_type media,
2339 u8 sig_mode, u16 phy_flags, unsigned long *et_mask)
2340{
2341 enum ethtool_link_mode_bit_indices link_mode;
2342 enum bnxt_link_speed_indices speed;
2343 u8 bit;
2344
2345 for_each_set_bit(bit, &fw_mask, BNXT_FW_SPEED_MSK_BITS) {
2346 speed = bnxt_encoding_speed_idx(sig_mode, phy_flags, speed_msk: 1 << bit);
2347 if (!speed)
2348 continue;
2349
2350 link_mode = bnxt_link_modes[speed][sig_mode][media];
2351 if (!link_mode)
2352 continue;
2353
2354 linkmode_set_bit(nr: link_mode, addr: et_mask);
2355 }
2356}
2357
2358static void
2359bnxt_get_ethtool_speeds(unsigned long fw_mask, enum bnxt_media_type media,
2360 u8 sig_mode, u16 phy_flags, unsigned long *et_mask)
2361{
2362 if (media) {
2363 __bnxt_get_ethtool_speeds(fw_mask, media, sig_mode, phy_flags,
2364 et_mask);
2365 return;
2366 }
2367
2368 /* list speeds for all media if unknown */
2369 for (media = 1; media < __BNXT_MEDIA_END; media++)
2370 __bnxt_get_ethtool_speeds(fw_mask, media, sig_mode, phy_flags,
2371 et_mask);
2372}
2373
2374static void
2375bnxt_get_all_ethtool_support_speeds(struct bnxt_link_info *link_info,
2376 enum bnxt_media_type media,
2377 struct ethtool_link_ksettings *lk_ksettings)
2378{
2379 struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
2380 u16 sp_nrz, sp_pam4, sp_pam4_112 = 0;
2381 u16 phy_flags = bp->phy_flags;
2382
2383 if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
2384 sp_nrz = link_info->support_speeds2;
2385 sp_pam4 = link_info->support_speeds2;
2386 sp_pam4_112 = link_info->support_speeds2;
2387 } else {
2388 sp_nrz = link_info->support_speeds;
2389 sp_pam4 = link_info->support_pam4_speeds;
2390 }
2391 bnxt_get_ethtool_speeds(fw_mask: sp_nrz, media, BNXT_SIG_MODE_NRZ, phy_flags,
2392 et_mask: lk_ksettings->link_modes.supported);
2393 bnxt_get_ethtool_speeds(fw_mask: sp_pam4, media, BNXT_SIG_MODE_PAM4, phy_flags,
2394 et_mask: lk_ksettings->link_modes.supported);
2395 bnxt_get_ethtool_speeds(fw_mask: sp_pam4_112, media, BNXT_SIG_MODE_PAM4_112,
2396 phy_flags, et_mask: lk_ksettings->link_modes.supported);
2397}
2398
2399static void
2400bnxt_get_all_ethtool_adv_speeds(struct bnxt_link_info *link_info,
2401 enum bnxt_media_type media,
2402 struct ethtool_link_ksettings *lk_ksettings)
2403{
2404 struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
2405 u16 sp_nrz, sp_pam4, sp_pam4_112 = 0;
2406 u16 phy_flags = bp->phy_flags;
2407
2408 sp_nrz = link_info->advertising;
2409 if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
2410 sp_pam4 = link_info->advertising;
2411 sp_pam4_112 = link_info->advertising;
2412 } else {
2413 sp_pam4 = link_info->advertising_pam4;
2414 }
2415 bnxt_get_ethtool_speeds(fw_mask: sp_nrz, media, BNXT_SIG_MODE_NRZ, phy_flags,
2416 et_mask: lk_ksettings->link_modes.advertising);
2417 bnxt_get_ethtool_speeds(fw_mask: sp_pam4, media, BNXT_SIG_MODE_PAM4, phy_flags,
2418 et_mask: lk_ksettings->link_modes.advertising);
2419 bnxt_get_ethtool_speeds(fw_mask: sp_pam4_112, media, BNXT_SIG_MODE_PAM4_112,
2420 phy_flags, et_mask: lk_ksettings->link_modes.advertising);
2421}
2422
2423static void
2424bnxt_get_all_ethtool_lp_speeds(struct bnxt_link_info *link_info,
2425 enum bnxt_media_type media,
2426 struct ethtool_link_ksettings *lk_ksettings)
2427{
2428 struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
2429 u16 phy_flags = bp->phy_flags;
2430
2431 bnxt_get_ethtool_speeds(fw_mask: link_info->lp_auto_link_speeds, media,
2432 BNXT_SIG_MODE_NRZ, phy_flags,
2433 et_mask: lk_ksettings->link_modes.lp_advertising);
2434 bnxt_get_ethtool_speeds(fw_mask: link_info->lp_auto_pam4_link_speeds, media,
2435 BNXT_SIG_MODE_PAM4, phy_flags,
2436 et_mask: lk_ksettings->link_modes.lp_advertising);
2437}
2438
2439static void bnxt_update_speed(u32 *delta, bool installed_media, u16 *speeds,
2440 u16 speed_msk, const unsigned long *et_mask,
2441 enum ethtool_link_mode_bit_indices mode)
2442{
2443 bool mode_desired = linkmode_test_bit(nr: mode, addr: et_mask);
2444
2445 if (!mode)
2446 return;
2447
2448 /* enabled speeds for installed media should override */
2449 if (installed_media && mode_desired) {
2450 *speeds |= speed_msk;
2451 *delta |= speed_msk;
2452 return;
2453 }
2454
2455 /* many to one mapping, only allow one change per fw_speed bit */
2456 if (!(*delta & speed_msk) && (mode_desired == !(*speeds & speed_msk))) {
2457 *speeds ^= speed_msk;
2458 *delta |= speed_msk;
2459 }
2460}
2461
2462static void bnxt_set_ethtool_speeds(struct bnxt_link_info *link_info,
2463 const unsigned long *et_mask)
2464{
2465 struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
2466 u16 const *sp_msks, *sp_pam4_msks, *sp_pam4_112_msks;
2467 enum bnxt_media_type media = bnxt_get_media(link_info);
2468 u16 *adv, *adv_pam4, *adv_pam4_112 = NULL;
2469 u32 delta_pam4_112 = 0;
2470 u32 delta_pam4 = 0;
2471 u32 delta_nrz = 0;
2472 int i, m;
2473
2474 adv = &link_info->advertising;
2475 if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) {
2476 adv_pam4 = &link_info->advertising;
2477 adv_pam4_112 = &link_info->advertising;
2478 sp_msks = bnxt_nrz_speeds2_masks;
2479 sp_pam4_msks = bnxt_pam4_speeds2_masks;
2480 sp_pam4_112_msks = bnxt_pam4_112_speeds2_masks;
2481 } else {
2482 adv_pam4 = &link_info->advertising_pam4;
2483 sp_msks = bnxt_nrz_speed_masks;
2484 sp_pam4_msks = bnxt_pam4_speed_masks;
2485 }
2486 for (i = 1; i < __BNXT_LINK_SPEED_END; i++) {
2487 /* accept any legal media from user */
2488 for (m = 1; m < __BNXT_MEDIA_END; m++) {
2489 bnxt_update_speed(delta: &delta_nrz, installed_media: m == media,
2490 speeds: adv, speed_msk: sp_msks[i], et_mask,
2491 mode: bnxt_link_modes[i][BNXT_SIG_MODE_NRZ][m]);
2492 bnxt_update_speed(delta: &delta_pam4, installed_media: m == media,
2493 speeds: adv_pam4, speed_msk: sp_pam4_msks[i], et_mask,
2494 mode: bnxt_link_modes[i][BNXT_SIG_MODE_PAM4][m]);
2495 if (!adv_pam4_112)
2496 continue;
2497
2498 bnxt_update_speed(delta: &delta_pam4_112, installed_media: m == media,
2499 speeds: adv_pam4_112, speed_msk: sp_pam4_112_msks[i], et_mask,
2500 mode: bnxt_link_modes[i][BNXT_SIG_MODE_PAM4_112][m]);
2501 }
2502 }
2503}
2504
2505static void bnxt_fw_to_ethtool_advertised_fec(struct bnxt_link_info *link_info,
2506 struct ethtool_link_ksettings *lk_ksettings)
2507{
2508 u16 fec_cfg = link_info->fec_cfg;
2509
2510 if ((fec_cfg & BNXT_FEC_NONE) || !(fec_cfg & BNXT_FEC_AUTONEG)) {
2511 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_NONE_BIT,
2512 addr: lk_ksettings->link_modes.advertising);
2513 return;
2514 }
2515 if (fec_cfg & BNXT_FEC_ENC_BASE_R)
2516 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_BASER_BIT,
2517 addr: lk_ksettings->link_modes.advertising);
2518 if (fec_cfg & BNXT_FEC_ENC_RS)
2519 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_RS_BIT,
2520 addr: lk_ksettings->link_modes.advertising);
2521 if (fec_cfg & BNXT_FEC_ENC_LLRS)
2522 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
2523 addr: lk_ksettings->link_modes.advertising);
2524}
2525
2526static void bnxt_fw_to_ethtool_support_fec(struct bnxt_link_info *link_info,
2527 struct ethtool_link_ksettings *lk_ksettings)
2528{
2529 u16 fec_cfg = link_info->fec_cfg;
2530
2531 if (fec_cfg & BNXT_FEC_NONE) {
2532 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_NONE_BIT,
2533 addr: lk_ksettings->link_modes.supported);
2534 return;
2535 }
2536 if (fec_cfg & BNXT_FEC_ENC_BASE_R_CAP)
2537 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_BASER_BIT,
2538 addr: lk_ksettings->link_modes.supported);
2539 if (fec_cfg & BNXT_FEC_ENC_RS_CAP)
2540 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_RS_BIT,
2541 addr: lk_ksettings->link_modes.supported);
2542 if (fec_cfg & BNXT_FEC_ENC_LLRS_CAP)
2543 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
2544 addr: lk_ksettings->link_modes.supported);
2545}
2546
2547u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
2548{
2549 switch (fw_link_speed) {
2550 case BNXT_LINK_SPEED_100MB:
2551 return SPEED_100;
2552 case BNXT_LINK_SPEED_1GB:
2553 return SPEED_1000;
2554 case BNXT_LINK_SPEED_2_5GB:
2555 return SPEED_2500;
2556 case BNXT_LINK_SPEED_10GB:
2557 return SPEED_10000;
2558 case BNXT_LINK_SPEED_20GB:
2559 return SPEED_20000;
2560 case BNXT_LINK_SPEED_25GB:
2561 return SPEED_25000;
2562 case BNXT_LINK_SPEED_40GB:
2563 return SPEED_40000;
2564 case BNXT_LINK_SPEED_50GB:
2565 case BNXT_LINK_SPEED_50GB_PAM4:
2566 return SPEED_50000;
2567 case BNXT_LINK_SPEED_100GB:
2568 case BNXT_LINK_SPEED_100GB_PAM4:
2569 case BNXT_LINK_SPEED_100GB_PAM4_112:
2570 return SPEED_100000;
2571 case BNXT_LINK_SPEED_200GB:
2572 case BNXT_LINK_SPEED_200GB_PAM4:
2573 case BNXT_LINK_SPEED_200GB_PAM4_112:
2574 return SPEED_200000;
2575 case BNXT_LINK_SPEED_400GB:
2576 case BNXT_LINK_SPEED_400GB_PAM4:
2577 case BNXT_LINK_SPEED_400GB_PAM4_112:
2578 return SPEED_400000;
2579 default:
2580 return SPEED_UNKNOWN;
2581 }
2582}
2583
2584static void bnxt_get_default_speeds(struct ethtool_link_ksettings *lk_ksettings,
2585 struct bnxt_link_info *link_info)
2586{
2587 struct ethtool_link_settings *base = &lk_ksettings->base;
2588
2589 if (link_info->link_state == BNXT_LINK_STATE_UP) {
2590 base->speed = bnxt_fw_to_ethtool_speed(fw_link_speed: link_info->link_speed);
2591 base->duplex = DUPLEX_HALF;
2592 if (link_info->duplex & BNXT_LINK_DUPLEX_FULL)
2593 base->duplex = DUPLEX_FULL;
2594 lk_ksettings->lanes = link_info->active_lanes;
2595 } else if (!link_info->autoneg) {
2596 base->speed = bnxt_fw_to_ethtool_speed(fw_link_speed: link_info->req_link_speed);
2597 base->duplex = DUPLEX_HALF;
2598 if (link_info->req_duplex == BNXT_LINK_DUPLEX_FULL)
2599 base->duplex = DUPLEX_FULL;
2600 }
2601}
2602
2603static int bnxt_get_link_ksettings(struct net_device *dev,
2604 struct ethtool_link_ksettings *lk_ksettings)
2605{
2606 struct ethtool_link_settings *base = &lk_ksettings->base;
2607 enum ethtool_link_mode_bit_indices link_mode;
2608 struct bnxt *bp = netdev_priv(dev);
2609 struct bnxt_link_info *link_info;
2610 enum bnxt_media_type media;
2611
2612 ethtool_link_ksettings_zero_link_mode(lk_ksettings, lp_advertising);
2613 ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising);
2614 ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported);
2615 base->duplex = DUPLEX_UNKNOWN;
2616 base->speed = SPEED_UNKNOWN;
2617 link_info = &bp->link_info;
2618
2619 mutex_lock(&bp->link_lock);
2620 bnxt_get_ethtool_modes(link_info, lk_ksettings);
2621 media = bnxt_get_media(link_info);
2622 bnxt_get_all_ethtool_support_speeds(link_info, media, lk_ksettings);
2623 bnxt_fw_to_ethtool_support_fec(link_info, lk_ksettings);
2624 link_mode = bnxt_get_link_mode(link_info);
2625 if (link_mode != BNXT_LINK_MODE_UNKNOWN)
2626 ethtool_params_from_link_mode(link_ksettings: lk_ksettings, link_mode);
2627 else
2628 bnxt_get_default_speeds(lk_ksettings, link_info);
2629
2630 if (link_info->autoneg) {
2631 bnxt_fw_to_ethtool_advertised_fec(link_info, lk_ksettings);
2632 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_Autoneg_BIT,
2633 addr: lk_ksettings->link_modes.advertising);
2634 base->autoneg = AUTONEG_ENABLE;
2635 bnxt_get_all_ethtool_adv_speeds(link_info, media, lk_ksettings);
2636 if (link_info->phy_link_status == BNXT_LINK_LINK)
2637 bnxt_get_all_ethtool_lp_speeds(link_info, media,
2638 lk_ksettings);
2639 } else {
2640 base->autoneg = AUTONEG_DISABLE;
2641 }
2642
2643 base->port = PORT_NONE;
2644 if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
2645 base->port = PORT_TP;
2646 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_TP_BIT,
2647 addr: lk_ksettings->link_modes.supported);
2648 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_TP_BIT,
2649 addr: lk_ksettings->link_modes.advertising);
2650 } else {
2651 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FIBRE_BIT,
2652 addr: lk_ksettings->link_modes.supported);
2653 linkmode_set_bit(nr: ETHTOOL_LINK_MODE_FIBRE_BIT,
2654 addr: lk_ksettings->link_modes.advertising);
2655
2656 if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC)
2657 base->port = PORT_DA;
2658 else
2659 base->port = PORT_FIBRE;
2660 }
2661 base->phy_address = link_info->phy_addr;
2662 mutex_unlock(lock: &bp->link_lock);
2663
2664 return 0;
2665}
2666
2667static int
2668bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 lanes)
2669{
2670 struct bnxt *bp = netdev_priv(dev);
2671 struct bnxt_link_info *link_info = &bp->link_info;
2672 u16 support_pam4_spds = link_info->support_pam4_speeds;
2673 u16 support_spds2 = link_info->support_speeds2;
2674 u16 support_spds = link_info->support_speeds;
2675 u8 sig_mode = BNXT_SIG_MODE_NRZ;
2676 u32 lanes_needed = 1;
2677 u16 fw_speed = 0;
2678
2679 switch (ethtool_speed) {
2680 case SPEED_100:
2681 if (support_spds & BNXT_LINK_SPEED_MSK_100MB)
2682 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100MB;
2683 break;
2684 case SPEED_1000:
2685 if ((support_spds & BNXT_LINK_SPEED_MSK_1GB) ||
2686 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_1GB))
2687 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_1GB;
2688 break;
2689 case SPEED_2500:
2690 if (support_spds & BNXT_LINK_SPEED_MSK_2_5GB)
2691 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_2_5GB;
2692 break;
2693 case SPEED_10000:
2694 if ((support_spds & BNXT_LINK_SPEED_MSK_10GB) ||
2695 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_10GB))
2696 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10GB;
2697 break;
2698 case SPEED_20000:
2699 if (support_spds & BNXT_LINK_SPEED_MSK_20GB) {
2700 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_20GB;
2701 lanes_needed = 2;
2702 }
2703 break;
2704 case SPEED_25000:
2705 if ((support_spds & BNXT_LINK_SPEED_MSK_25GB) ||
2706 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_25GB))
2707 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_25GB;
2708 break;
2709 case SPEED_40000:
2710 if ((support_spds & BNXT_LINK_SPEED_MSK_40GB) ||
2711 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_40GB)) {
2712 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB;
2713 lanes_needed = 4;
2714 }
2715 break;
2716 case SPEED_50000:
2717 if (((support_spds & BNXT_LINK_SPEED_MSK_50GB) ||
2718 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_50GB)) &&
2719 lanes != 1) {
2720 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB;
2721 lanes_needed = 2;
2722 } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_50GB) {
2723 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_50GB;
2724 sig_mode = BNXT_SIG_MODE_PAM4;
2725 } else if (support_spds2 & BNXT_LINK_SPEEDS2_MSK_50GB_PAM4) {
2726 fw_speed = BNXT_LINK_SPEED_50GB_PAM4;
2727 sig_mode = BNXT_SIG_MODE_PAM4;
2728 }
2729 break;
2730 case SPEED_100000:
2731 if (((support_spds & BNXT_LINK_SPEED_MSK_100GB) ||
2732 (support_spds2 & BNXT_LINK_SPEEDS2_MSK_100GB)) &&
2733 lanes != 2 && lanes != 1) {
2734 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB;
2735 lanes_needed = 4;
2736 } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_100GB) {
2737 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_100GB;
2738 sig_mode = BNXT_SIG_MODE_PAM4;
2739 lanes_needed = 2;
2740 } else if ((support_spds2 & BNXT_LINK_SPEEDS2_MSK_100GB_PAM4) &&
2741 lanes != 1) {
2742 fw_speed = BNXT_LINK_SPEED_100GB_PAM4;
2743 sig_mode = BNXT_SIG_MODE_PAM4;
2744 lanes_needed = 2;
2745 } else if (support_spds2 & BNXT_LINK_SPEEDS2_MSK_100GB_PAM4_112) {
2746 fw_speed = BNXT_LINK_SPEED_100GB_PAM4_112;
2747 sig_mode = BNXT_SIG_MODE_PAM4_112;
2748 }
2749 break;
2750 case SPEED_200000:
2751 if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_200GB) {
2752 fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB;
2753 sig_mode = BNXT_SIG_MODE_PAM4;
2754 lanes_needed = 4;
2755 } else if ((support_spds2 & BNXT_LINK_SPEEDS2_MSK_200GB_PAM4) &&
2756 lanes != 2) {
2757 fw_speed = BNXT_LINK_SPEED_200GB_PAM4;
2758 sig_mode = BNXT_SIG_MODE_PAM4;
2759 lanes_needed = 4;
2760 } else if (support_spds2 & BNXT_LINK_SPEEDS2_MSK_200GB_PAM4_112) {
2761 fw_speed = BNXT_LINK_SPEED_200GB_PAM4_112;
2762 sig_mode = BNXT_SIG_MODE_PAM4_112;
2763 lanes_needed = 2;
2764 }
2765 break;
2766 case SPEED_400000:
2767 if ((support_spds2 & BNXT_LINK_SPEEDS2_MSK_400GB_PAM4) &&
2768 lanes != 4) {
2769 fw_speed = BNXT_LINK_SPEED_400GB_PAM4;
2770 sig_mode = BNXT_SIG_MODE_PAM4;
2771 lanes_needed = 8;
2772 } else if (support_spds2 & BNXT_LINK_SPEEDS2_MSK_400GB_PAM4_112) {
2773 fw_speed = BNXT_LINK_SPEED_400GB_PAM4_112;
2774 sig_mode = BNXT_SIG_MODE_PAM4_112;
2775 lanes_needed = 4;
2776 }
2777 break;
2778 }
2779
2780 if (!fw_speed) {
2781 netdev_err(dev, format: "unsupported speed!\n");
2782 return -EINVAL;
2783 }
2784
2785 if (lanes && lanes != lanes_needed) {
2786 netdev_err(dev, format: "unsupported number of lanes for speed\n");
2787 return -EINVAL;
2788 }
2789
2790 if (link_info->req_link_speed == fw_speed &&
2791 link_info->req_signal_mode == sig_mode &&
2792 link_info->autoneg == 0)
2793 return -EALREADY;
2794
2795 link_info->req_link_speed = fw_speed;
2796 link_info->req_signal_mode = sig_mode;
2797 link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
2798 link_info->autoneg = 0;
2799 link_info->advertising = 0;
2800 link_info->advertising_pam4 = 0;
2801
2802 return 0;
2803}
2804
2805u16 bnxt_get_fw_auto_link_speeds(const unsigned long *mode)
2806{
2807 u16 fw_speed_mask = 0;
2808
2809 if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_100baseT_Full_BIT, addr: mode) ||
2810 linkmode_test_bit(nr: ETHTOOL_LINK_MODE_100baseT_Half_BIT, addr: mode))
2811 fw_speed_mask |= BNXT_LINK_SPEED_MSK_100MB;
2812
2813 if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_1000baseT_Full_BIT, addr: mode) ||
2814 linkmode_test_bit(nr: ETHTOOL_LINK_MODE_1000baseT_Half_BIT, addr: mode))
2815 fw_speed_mask |= BNXT_LINK_SPEED_MSK_1GB;
2816
2817 if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_10000baseT_Full_BIT, addr: mode))
2818 fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB;
2819
2820 if (linkmode_test_bit(nr: ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, addr: mode))
2821 fw_speed_mask |= BNXT_LINK_SPEED_MSK_40GB;
2822
2823 return fw_speed_mask;
2824}
2825
2826static int bnxt_set_link_ksettings(struct net_device *dev,
2827 const struct ethtool_link_ksettings *lk_ksettings)
2828{
2829 struct bnxt *bp = netdev_priv(dev);
2830 struct bnxt_link_info *link_info = &bp->link_info;
2831 const struct ethtool_link_settings *base = &lk_ksettings->base;
2832 bool set_pause = false;
2833 u32 speed, lanes = 0;
2834 int rc = 0;
2835
2836 if (!BNXT_PHY_CFG_ABLE(bp))
2837 return -EOPNOTSUPP;
2838
2839 mutex_lock(&bp->link_lock);
2840 if (base->autoneg == AUTONEG_ENABLE) {
2841 bnxt_set_ethtool_speeds(link_info,
2842 et_mask: lk_ksettings->link_modes.advertising);
2843 link_info->autoneg |= BNXT_AUTONEG_SPEED;
2844 if (!link_info->advertising && !link_info->advertising_pam4) {
2845 link_info->advertising = link_info->support_auto_speeds;
2846 link_info->advertising_pam4 =
2847 link_info->support_pam4_auto_speeds;
2848 }
2849 /* any change to autoneg will cause link change, therefore the
2850 * driver should put back the original pause setting in autoneg
2851 */
2852 if (!(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE))
2853 set_pause = true;
2854 } else {
2855 u8 phy_type = link_info->phy_type;
2856
2857 if (phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASET ||
2858 phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASETE ||
2859 link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
2860 netdev_err(dev, format: "10GBase-T devices must autoneg\n");
2861 rc = -EINVAL;
2862 goto set_setting_exit;
2863 }
2864 if (base->duplex == DUPLEX_HALF) {
2865 netdev_err(dev, format: "HALF DUPLEX is not supported!\n");
2866 rc = -EINVAL;
2867 goto set_setting_exit;
2868 }
2869 speed = base->speed;
2870 lanes = lk_ksettings->lanes;
2871 rc = bnxt_force_link_speed(dev, ethtool_speed: speed, lanes);
2872 if (rc) {
2873 if (rc == -EALREADY)
2874 rc = 0;
2875 goto set_setting_exit;
2876 }
2877 }
2878
2879 if (netif_running(dev))
2880 rc = bnxt_hwrm_set_link_setting(bp, set_pause, false);
2881
2882set_setting_exit:
2883 mutex_unlock(lock: &bp->link_lock);
2884 return rc;
2885}
2886
2887static int bnxt_get_fecparam(struct net_device *dev,
2888 struct ethtool_fecparam *fec)
2889{
2890 struct bnxt *bp = netdev_priv(dev);
2891 struct bnxt_link_info *link_info;
2892 u8 active_fec;
2893 u16 fec_cfg;
2894
2895 link_info = &bp->link_info;
2896 fec_cfg = link_info->fec_cfg;
2897 active_fec = link_info->active_fec_sig_mode &
2898 PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK;
2899 if (fec_cfg & BNXT_FEC_NONE) {
2900 fec->fec = ETHTOOL_FEC_NONE;
2901 fec->active_fec = ETHTOOL_FEC_NONE;
2902 return 0;
2903 }
2904 if (fec_cfg & BNXT_FEC_AUTONEG)
2905 fec->fec |= ETHTOOL_FEC_AUTO;
2906 if (fec_cfg & BNXT_FEC_ENC_BASE_R)
2907 fec->fec |= ETHTOOL_FEC_BASER;
2908 if (fec_cfg & BNXT_FEC_ENC_RS)
2909 fec->fec |= ETHTOOL_FEC_RS;
2910 if (fec_cfg & BNXT_FEC_ENC_LLRS)
2911 fec->fec |= ETHTOOL_FEC_LLRS;
2912
2913 switch (active_fec) {
2914 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE:
2915 fec->active_fec |= ETHTOOL_FEC_BASER;
2916 break;
2917 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE:
2918 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE:
2919 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE:
2920 fec->active_fec |= ETHTOOL_FEC_RS;
2921 break;
2922 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE:
2923 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE:
2924 fec->active_fec |= ETHTOOL_FEC_LLRS;
2925 break;
2926 case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE:
2927 fec->active_fec |= ETHTOOL_FEC_OFF;
2928 break;
2929 }
2930 return 0;
2931}
2932
2933static void bnxt_get_fec_stats(struct net_device *dev,
2934 struct ethtool_fec_stats *fec_stats)
2935{
2936 struct bnxt *bp = netdev_priv(dev);
2937 u64 *rx;
2938
2939 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
2940 return;
2941
2942 rx = bp->rx_port_stats_ext.sw_stats;
2943 fec_stats->corrected_bits.total =
2944 *(rx + BNXT_RX_STATS_EXT_OFFSET(rx_corrected_bits));
2945
2946 if (bp->fw_rx_stats_ext_size <= BNXT_RX_STATS_EXT_NUM_LEGACY)
2947 return;
2948
2949 fec_stats->corrected_blocks.total =
2950 *(rx + BNXT_RX_STATS_EXT_OFFSET(rx_fec_corrected_blocks));
2951 fec_stats->uncorrectable_blocks.total =
2952 *(rx + BNXT_RX_STATS_EXT_OFFSET(rx_fec_uncorrectable_blocks));
2953}
2954
2955static u32 bnxt_ethtool_forced_fec_to_fw(struct bnxt_link_info *link_info,
2956 u32 fec)
2957{
2958 u32 fw_fec = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE;
2959
2960 if (fec & ETHTOOL_FEC_BASER)
2961 fw_fec |= BNXT_FEC_BASE_R_ON(link_info);
2962 else if (fec & ETHTOOL_FEC_RS)
2963 fw_fec |= BNXT_FEC_RS_ON(link_info);
2964 else if (fec & ETHTOOL_FEC_LLRS)
2965 fw_fec |= BNXT_FEC_LLRS_ON;
2966 return fw_fec;
2967}
2968
2969static int bnxt_set_fecparam(struct net_device *dev,
2970 struct ethtool_fecparam *fecparam)
2971{
2972 struct hwrm_port_phy_cfg_input *req;
2973 struct bnxt *bp = netdev_priv(dev);
2974 struct bnxt_link_info *link_info;
2975 u32 new_cfg, fec = fecparam->fec;
2976 u16 fec_cfg;
2977 int rc;
2978
2979 link_info = &bp->link_info;
2980 fec_cfg = link_info->fec_cfg;
2981 if (fec_cfg & BNXT_FEC_NONE)
2982 return -EOPNOTSUPP;
2983
2984 if (fec & ETHTOOL_FEC_OFF) {
2985 new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE |
2986 BNXT_FEC_ALL_OFF(link_info);
2987 goto apply_fec;
2988 }
2989 if (((fec & ETHTOOL_FEC_AUTO) && !(fec_cfg & BNXT_FEC_AUTONEG_CAP)) ||
2990 ((fec & ETHTOOL_FEC_RS) && !(fec_cfg & BNXT_FEC_ENC_RS_CAP)) ||
2991 ((fec & ETHTOOL_FEC_LLRS) && !(fec_cfg & BNXT_FEC_ENC_LLRS_CAP)) ||
2992 ((fec & ETHTOOL_FEC_BASER) && !(fec_cfg & BNXT_FEC_ENC_BASE_R_CAP)))
2993 return -EINVAL;
2994
2995 if (fec & ETHTOOL_FEC_AUTO) {
2996 if (!link_info->autoneg)
2997 return -EINVAL;
2998 new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE;
2999 } else {
3000 new_cfg = bnxt_ethtool_forced_fec_to_fw(link_info, fec);
3001 }
3002
3003apply_fec:
3004 rc = hwrm_req_init(bp, req, HWRM_PORT_PHY_CFG);
3005 if (rc)
3006 return rc;
3007 req->flags = cpu_to_le32(new_cfg | PORT_PHY_CFG_REQ_FLAGS_RESET_PHY);
3008 rc = hwrm_req_send(bp, req);
3009 /* update current settings */
3010 if (!rc) {
3011 mutex_lock(&bp->link_lock);
3012 bnxt_update_link(bp, chng_link_state: false);
3013 mutex_unlock(lock: &bp->link_lock);
3014 }
3015 return rc;
3016}
3017
3018static void bnxt_get_pauseparam(struct net_device *dev,
3019 struct ethtool_pauseparam *epause)
3020{
3021 struct bnxt *bp = netdev_priv(dev);
3022 struct bnxt_link_info *link_info = &bp->link_info;
3023
3024 if (BNXT_VF(bp))
3025 return;
3026 epause->autoneg = !!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL);
3027 epause->rx_pause = !!(link_info->req_flow_ctrl & BNXT_LINK_PAUSE_RX);
3028 epause->tx_pause = !!(link_info->req_flow_ctrl & BNXT_LINK_PAUSE_TX);
3029}
3030
3031static void bnxt_get_pause_stats(struct net_device *dev,
3032 struct ethtool_pause_stats *epstat)
3033{
3034 struct bnxt *bp = netdev_priv(dev);
3035 u64 *rx, *tx;
3036
3037 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
3038 return;
3039
3040 rx = bp->port_stats.sw_stats;
3041 tx = bp->port_stats.sw_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
3042
3043 epstat->rx_pause_frames = BNXT_GET_RX_PORT_STATS64(rx, rx_pause_frames);
3044 epstat->tx_pause_frames = BNXT_GET_TX_PORT_STATS64(tx, tx_pause_frames);
3045}
3046
3047static int bnxt_set_pauseparam(struct net_device *dev,
3048 struct ethtool_pauseparam *epause)
3049{
3050 int rc = 0;
3051 struct bnxt *bp = netdev_priv(dev);
3052 struct bnxt_link_info *link_info = &bp->link_info;
3053
3054 if (!BNXT_PHY_CFG_ABLE(bp) || (bp->phy_flags & BNXT_PHY_FL_NO_PAUSE))
3055 return -EOPNOTSUPP;
3056
3057 mutex_lock(&bp->link_lock);
3058 if (epause->autoneg) {
3059 if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
3060 rc = -EINVAL;
3061 goto pause_exit;
3062 }
3063
3064 link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
3065 link_info->req_flow_ctrl = 0;
3066 } else {
3067 /* when transition from auto pause to force pause,
3068 * force a link change
3069 */
3070 if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL)
3071 link_info->force_link_chng = true;
3072 link_info->autoneg &= ~BNXT_AUTONEG_FLOW_CTRL;
3073 link_info->req_flow_ctrl = 0;
3074 }
3075 if (epause->rx_pause)
3076 link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_RX;
3077
3078 if (epause->tx_pause)
3079 link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX;
3080
3081 if (netif_running(dev))
3082 rc = bnxt_hwrm_set_pause(bp);
3083
3084pause_exit:
3085 mutex_unlock(lock: &bp->link_lock);
3086 return rc;
3087}
3088
3089static u32 bnxt_get_link(struct net_device *dev)
3090{
3091 struct bnxt *bp = netdev_priv(dev);
3092
3093 /* TODO: handle MF, VF, driver close case */
3094 return BNXT_LINK_IS_UP(bp);
3095}
3096
3097int bnxt_hwrm_nvm_get_dev_info(struct bnxt *bp,
3098 struct hwrm_nvm_get_dev_info_output *nvm_dev_info)
3099{
3100 struct hwrm_nvm_get_dev_info_output *resp;
3101 struct hwrm_nvm_get_dev_info_input *req;
3102 int rc;
3103
3104 if (BNXT_VF(bp))
3105 return -EOPNOTSUPP;
3106
3107 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_DEV_INFO);
3108 if (rc)
3109 return rc;
3110
3111 resp = hwrm_req_hold(bp, req);
3112 rc = hwrm_req_send(bp, req);
3113 if (!rc)
3114 memcpy(nvm_dev_info, resp, sizeof(*resp));
3115 hwrm_req_drop(bp, req);
3116 return rc;
3117}
3118
3119static void bnxt_print_admin_err(struct bnxt *bp)
3120{
3121 netdev_info(dev: bp->dev, format: "PF does not have admin privileges to flash or reset the device\n");
3122}
3123
3124int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
3125 u16 ext, u16 *index, u32 *item_length,
3126 u32 *data_length);
3127
3128int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
3129 u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
3130 u32 dir_item_len, const u8 *data,
3131 size_t data_len)
3132{
3133 struct bnxt *bp = netdev_priv(dev);
3134 struct hwrm_nvm_write_input *req;
3135 int rc;
3136
3137 rc = hwrm_req_init(bp, req, HWRM_NVM_WRITE);
3138 if (rc)
3139 return rc;
3140
3141 if (data_len && data) {
3142 dma_addr_t dma_handle;
3143 u8 *kmem;
3144
3145 kmem = hwrm_req_dma_slice(bp, req, size: data_len, dma: &dma_handle);
3146 if (!kmem) {
3147 hwrm_req_drop(bp, req);
3148 return -ENOMEM;
3149 }
3150
3151 req->dir_data_length = cpu_to_le32(data_len);
3152
3153 memcpy(kmem, data, data_len);
3154 req->host_src_addr = cpu_to_le64(dma_handle);
3155 }
3156
3157 hwrm_req_timeout(bp, req, timeout: bp->hwrm_cmd_max_timeout);
3158 req->dir_type = cpu_to_le16(dir_type);
3159 req->dir_ordinal = cpu_to_le16(dir_ordinal);
3160 req->dir_ext = cpu_to_le16(dir_ext);
3161 req->dir_attr = cpu_to_le16(dir_attr);
3162 req->dir_item_length = cpu_to_le32(dir_item_len);
3163 rc = hwrm_req_send(bp, req);
3164
3165 if (rc == -EACCES)
3166 bnxt_print_admin_err(bp);
3167 return rc;
3168}
3169
3170int bnxt_hwrm_firmware_reset(struct net_device *dev, u8 proc_type,
3171 u8 self_reset, u8 flags)
3172{
3173 struct bnxt *bp = netdev_priv(dev);
3174 struct hwrm_fw_reset_input *req;
3175 int rc;
3176
3177 if (!bnxt_hwrm_reset_permitted(bp)) {
3178 netdev_warn(dev: bp->dev, format: "Reset denied by firmware, it may be inhibited by remote driver");
3179 return -EPERM;
3180 }
3181
3182 rc = hwrm_req_init(bp, req, HWRM_FW_RESET);
3183 if (rc)
3184 return rc;
3185
3186 req->embedded_proc_type = proc_type;
3187 req->selfrst_status = self_reset;
3188 req->flags = flags;
3189
3190 if (proc_type == FW_RESET_REQ_EMBEDDED_PROC_TYPE_AP) {
3191 rc = hwrm_req_send_silent(bp, req);
3192 } else {
3193 rc = hwrm_req_send(bp, req);
3194 if (rc == -EACCES)
3195 bnxt_print_admin_err(bp);
3196 }
3197 return rc;
3198}
3199
3200static int bnxt_firmware_reset(struct net_device *dev,
3201 enum bnxt_nvm_directory_type dir_type)
3202{
3203 u8 self_reset = FW_RESET_REQ_SELFRST_STATUS_SELFRSTNONE;
3204 u8 proc_type, flags = 0;
3205
3206 /* TODO: Address self-reset of APE/KONG/BONO/TANG or ungraceful reset */
3207 /* (e.g. when firmware isn't already running) */
3208 switch (dir_type) {
3209 case BNX_DIR_TYPE_CHIMP_PATCH:
3210 case BNX_DIR_TYPE_BOOTCODE:
3211 case BNX_DIR_TYPE_BOOTCODE_2:
3212 proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_BOOT;
3213 /* Self-reset ChiMP upon next PCIe reset: */
3214 self_reset = FW_RESET_REQ_SELFRST_STATUS_SELFRSTPCIERST;
3215 break;
3216 case BNX_DIR_TYPE_APE_FW:
3217 case BNX_DIR_TYPE_APE_PATCH:
3218 proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_MGMT;
3219 /* Self-reset APE upon next PCIe reset: */
3220 self_reset = FW_RESET_REQ_SELFRST_STATUS_SELFRSTPCIERST;
3221 break;
3222 case BNX_DIR_TYPE_KONG_FW:
3223 case BNX_DIR_TYPE_KONG_PATCH:
3224 proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_NETCTRL;
3225 break;
3226 case BNX_DIR_TYPE_BONO_FW:
3227 case BNX_DIR_TYPE_BONO_PATCH:
3228 proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_ROCE;
3229 break;
3230 default:
3231 return -EINVAL;
3232 }
3233
3234 return bnxt_hwrm_firmware_reset(dev, proc_type, self_reset, flags);
3235}
3236
3237static int bnxt_firmware_reset_chip(struct net_device *dev)
3238{
3239 struct bnxt *bp = netdev_priv(dev);
3240 u8 flags = 0;
3241
3242 if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET)
3243 flags = FW_RESET_REQ_FLAGS_RESET_GRACEFUL;
3244
3245 return bnxt_hwrm_firmware_reset(dev,
3246 FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP,
3247 FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP,
3248 flags);
3249}
3250
3251static int bnxt_firmware_reset_ap(struct net_device *dev)
3252{
3253 return bnxt_hwrm_firmware_reset(dev, FW_RESET_REQ_EMBEDDED_PROC_TYPE_AP,
3254 FW_RESET_REQ_SELFRST_STATUS_SELFRSTNONE,
3255 flags: 0);
3256}
3257
3258static int bnxt_flash_firmware(struct net_device *dev,
3259 u16 dir_type,
3260 const u8 *fw_data,
3261 size_t fw_size)
3262{
3263 int rc = 0;
3264 u16 code_type;
3265 u32 stored_crc;
3266 u32 calculated_crc;
3267 struct bnxt_fw_header *header = (struct bnxt_fw_header *)fw_data;
3268
3269 switch (dir_type) {
3270 case BNX_DIR_TYPE_BOOTCODE:
3271 case BNX_DIR_TYPE_BOOTCODE_2:
3272 code_type = CODE_BOOT;
3273 break;
3274 case BNX_DIR_TYPE_CHIMP_PATCH:
3275 code_type = CODE_CHIMP_PATCH;
3276 break;
3277 case BNX_DIR_TYPE_APE_FW:
3278 code_type = CODE_MCTP_PASSTHRU;
3279 break;
3280 case BNX_DIR_TYPE_APE_PATCH:
3281 code_type = CODE_APE_PATCH;
3282 break;
3283 case BNX_DIR_TYPE_KONG_FW:
3284 code_type = CODE_KONG_FW;
3285 break;
3286 case BNX_DIR_TYPE_KONG_PATCH:
3287 code_type = CODE_KONG_PATCH;
3288 break;
3289 case BNX_DIR_TYPE_BONO_FW:
3290 code_type = CODE_BONO_FW;
3291 break;
3292 case BNX_DIR_TYPE_BONO_PATCH:
3293 code_type = CODE_BONO_PATCH;
3294 break;
3295 default:
3296 netdev_err(dev, format: "Unsupported directory entry type: %u\n",
3297 dir_type);
3298 return -EINVAL;
3299 }
3300 if (fw_size < sizeof(struct bnxt_fw_header)) {
3301 netdev_err(dev, format: "Invalid firmware file size: %u\n",
3302 (unsigned int)fw_size);
3303 return -EINVAL;
3304 }
3305 if (header->signature != cpu_to_le32(BNXT_FIRMWARE_BIN_SIGNATURE)) {
3306 netdev_err(dev, format: "Invalid firmware signature: %08X\n",
3307 le32_to_cpu(header->signature));
3308 return -EINVAL;
3309 }
3310 if (header->code_type != code_type) {
3311 netdev_err(dev, format: "Expected firmware type: %d, read: %d\n",
3312 code_type, header->code_type);
3313 return -EINVAL;
3314 }
3315 if (header->device != DEVICE_CUMULUS_FAMILY) {
3316 netdev_err(dev, format: "Expected firmware device family %d, read: %d\n",
3317 DEVICE_CUMULUS_FAMILY, header->device);
3318 return -EINVAL;
3319 }
3320 /* Confirm the CRC32 checksum of the file: */
3321 stored_crc = le32_to_cpu(*(__le32 *)(fw_data + fw_size -
3322 sizeof(stored_crc)));
3323 calculated_crc = ~crc32(~0, fw_data, fw_size - sizeof(stored_crc));
3324 if (calculated_crc != stored_crc) {
3325 netdev_err(dev, format: "Firmware file CRC32 checksum (%08lX) does not match calculated checksum (%08lX)\n",
3326 (unsigned long)stored_crc,
3327 (unsigned long)calculated_crc);
3328 return -EINVAL;
3329 }
3330 rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
3331 dir_ext: 0, dir_attr: 0, dir_item_len: 0, data: fw_data, data_len: fw_size);
3332 if (rc == 0) /* Firmware update successful */
3333 rc = bnxt_firmware_reset(dev, dir_type);
3334
3335 return rc;
3336}
3337
3338static int bnxt_flash_microcode(struct net_device *dev,
3339 u16 dir_type,
3340 const u8 *fw_data,
3341 size_t fw_size)
3342{
3343 struct bnxt_ucode_trailer *trailer;
3344 u32 calculated_crc;
3345 u32 stored_crc;
3346 int rc = 0;
3347
3348 if (fw_size < sizeof(struct bnxt_ucode_trailer)) {
3349 netdev_err(dev, format: "Invalid microcode file size: %u\n",
3350 (unsigned int)fw_size);
3351 return -EINVAL;
3352 }
3353 trailer = (struct bnxt_ucode_trailer *)(fw_data + (fw_size -
3354 sizeof(*trailer)));
3355 if (trailer->sig != cpu_to_le32(BNXT_UCODE_TRAILER_SIGNATURE)) {
3356 netdev_err(dev, format: "Invalid microcode trailer signature: %08X\n",
3357 le32_to_cpu(trailer->sig));
3358 return -EINVAL;
3359 }
3360 if (le16_to_cpu(trailer->dir_type) != dir_type) {
3361 netdev_err(dev, format: "Expected microcode type: %d, read: %d\n",
3362 dir_type, le16_to_cpu(trailer->dir_type));
3363 return -EINVAL;
3364 }
3365 if (le16_to_cpu(trailer->trailer_length) <
3366 sizeof(struct bnxt_ucode_trailer)) {
3367 netdev_err(dev, format: "Invalid microcode trailer length: %d\n",
3368 le16_to_cpu(trailer->trailer_length));
3369 return -EINVAL;
3370 }
3371
3372 /* Confirm the CRC32 checksum of the file: */
3373 stored_crc = le32_to_cpu(*(__le32 *)(fw_data + fw_size -
3374 sizeof(stored_crc)));
3375 calculated_crc = ~crc32(~0, fw_data, fw_size - sizeof(stored_crc));
3376 if (calculated_crc != stored_crc) {
3377 netdev_err(dev,
3378 format: "CRC32 (%08lX) does not match calculated: %08lX\n",
3379 (unsigned long)stored_crc,
3380 (unsigned long)calculated_crc);
3381 return -EINVAL;
3382 }
3383 rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
3384 dir_ext: 0, dir_attr: 0, dir_item_len: 0, data: fw_data, data_len: fw_size);
3385
3386 return rc;
3387}
3388
3389static bool bnxt_dir_type_is_ape_bin_format(u16 dir_type)
3390{
3391 switch (dir_type) {
3392 case BNX_DIR_TYPE_CHIMP_PATCH:
3393 case BNX_DIR_TYPE_BOOTCODE:
3394 case BNX_DIR_TYPE_BOOTCODE_2:
3395 case BNX_DIR_TYPE_APE_FW:
3396 case BNX_DIR_TYPE_APE_PATCH:
3397 case BNX_DIR_TYPE_KONG_FW:
3398 case BNX_DIR_TYPE_KONG_PATCH:
3399 case BNX_DIR_TYPE_BONO_FW:
3400 case BNX_DIR_TYPE_BONO_PATCH:
3401 return true;
3402 }
3403
3404 return false;
3405}
3406
3407static bool bnxt_dir_type_is_other_exec_format(u16 dir_type)
3408{
3409 switch (dir_type) {
3410 case BNX_DIR_TYPE_AVS:
3411 case BNX_DIR_TYPE_EXP_ROM_MBA:
3412 case BNX_DIR_TYPE_PCIE:
3413 case BNX_DIR_TYPE_TSCF_UCODE:
3414 case BNX_DIR_TYPE_EXT_PHY:
3415 case BNX_DIR_TYPE_CCM:
3416 case BNX_DIR_TYPE_ISCSI_BOOT:
3417 case BNX_DIR_TYPE_ISCSI_BOOT_IPV6:
3418 case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6:
3419 return true;
3420 }
3421
3422 return false;
3423}
3424
3425static bool bnxt_dir_type_is_executable(u16 dir_type)
3426{
3427 return bnxt_dir_type_is_ape_bin_format(dir_type) ||
3428 bnxt_dir_type_is_other_exec_format(dir_type);
3429}
3430
3431static int bnxt_flash_firmware_from_file(struct net_device *dev,
3432 u16 dir_type,
3433 const char *filename)
3434{
3435 const struct firmware *fw;
3436 int rc;
3437
3438 rc = request_firmware(fw: &fw, name: filename, device: &dev->dev);
3439 if (rc != 0) {
3440 netdev_err(dev, format: "Error %d requesting firmware file: %s\n",
3441 rc, filename);
3442 return rc;
3443 }
3444 if (bnxt_dir_type_is_ape_bin_format(dir_type))
3445 rc = bnxt_flash_firmware(dev, dir_type, fw_data: fw->data, fw_size: fw->size);
3446 else if (bnxt_dir_type_is_other_exec_format(dir_type))
3447 rc = bnxt_flash_microcode(dev, dir_type, fw_data: fw->data, fw_size: fw->size);
3448 else
3449 rc = bnxt_flash_nvram(dev, dir_type, BNX_DIR_ORDINAL_FIRST,
3450 dir_ext: 0, dir_attr: 0, dir_item_len: 0, data: fw->data, data_len: fw->size);
3451 release_firmware(fw);
3452 return rc;
3453}
3454
3455#define MSG_INTEGRITY_ERR "PKG install error : Data integrity on NVM"
3456#define MSG_INVALID_PKG "PKG install error : Invalid package"
3457#define MSG_AUTHENTICATION_ERR "PKG install error : Authentication error"
3458#define MSG_INVALID_DEV "PKG install error : Invalid device"
3459#define MSG_INTERNAL_ERR "PKG install error : Internal error"
3460#define MSG_NO_PKG_UPDATE_AREA_ERR "PKG update area not created in nvram"
3461#define MSG_NO_SPACE_ERR "PKG insufficient update area in nvram"
3462#define MSG_RESIZE_UPDATE_ERR "Resize UPDATE entry error"
3463#define MSG_ANTI_ROLLBACK_ERR "HWRM_NVM_INSTALL_UPDATE failure due to Anti-rollback detected"
3464#define MSG_GENERIC_FAILURE_ERR "HWRM_NVM_INSTALL_UPDATE failure"
3465
3466static int nvm_update_err_to_stderr(struct net_device *dev, u8 result,
3467 struct netlink_ext_ack *extack)
3468{
3469 switch (result) {
3470 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_TYPE_PARAMETER:
3471 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_INDEX_PARAMETER:
3472 case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_DATA_ERROR:
3473 case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_CHECKSUM_ERROR:
3474 case NVM_INSTALL_UPDATE_RESP_RESULT_ITEM_NOT_FOUND:
3475 case NVM_INSTALL_UPDATE_RESP_RESULT_ITEM_LOCKED:
3476 BNXT_NVM_ERR_MSG(dev, extack, MSG_INTEGRITY_ERR);
3477 return -EINVAL;
3478 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PREREQUISITE:
3479 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_FILE_HEADER:
3480 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_SIGNATURE:
3481 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PROP_STREAM:
3482 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PROP_LENGTH:
3483 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_MANIFEST:
3484 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_TRAILER:
3485 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_CHECKSUM:
3486 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_ITEM_CHECKSUM:
3487 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_DATA_LENGTH:
3488 case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_DIRECTIVE:
3489 case NVM_INSTALL_UPDATE_RESP_RESULT_DUPLICATE_ITEM:
3490 case NVM_INSTALL_UPDATE_RESP_RESULT_ZERO_LENGTH_ITEM:
3491 BNXT_NVM_ERR_MSG(dev, extack, MSG_INVALID_PKG);
3492 return -ENOPKG;
3493 case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_AUTHENTICATION_ERROR:
3494 BNXT_NVM_ERR_MSG(dev, extack, MSG_AUTHENTICATION_ERR);
3495 return -EPERM;
3496 case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_CHIP_REV:
3497 case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_DEVICE_ID:
3498 case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_SUBSYS_VENDOR:
3499 case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_SUBSYS_ID:
3500 case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_PLATFORM:
3501 BNXT_NVM_ERR_MSG(dev, extack, MSG_INVALID_DEV);
3502 return -EOPNOTSUPP;
3503 default:
3504 BNXT_NVM_ERR_MSG(dev, extack, MSG_INTERNAL_ERR);
3505 return -EIO;
3506 }
3507}
3508
3509#define BNXT_PKG_DMA_SIZE 0x40000
3510#define BNXT_NVM_MORE_FLAG (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_MODE))
3511#define BNXT_NVM_LAST_FLAG (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_LAST))
3512
3513static int bnxt_resize_update_entry(struct net_device *dev, size_t fw_size,
3514 struct netlink_ext_ack *extack)
3515{
3516 u32 item_len;
3517 int rc;
3518
3519 rc = bnxt_find_nvram_item(dev, type: BNX_DIR_TYPE_UPDATE,
3520 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, NULL,
3521 item_length: &item_len, NULL);
3522 if (rc) {
3523 BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_PKG_UPDATE_AREA_ERR);
3524 return rc;
3525 }
3526
3527 if (fw_size > item_len) {
3528 rc = bnxt_flash_nvram(dev, dir_type: BNX_DIR_TYPE_UPDATE,
3529 BNX_DIR_ORDINAL_FIRST, dir_ext: 0, dir_attr: 1,
3530 round_up(fw_size, 4096), NULL, data_len: 0);
3531 if (rc) {
3532 BNXT_NVM_ERR_MSG(dev, extack, MSG_RESIZE_UPDATE_ERR);
3533 return rc;
3534 }
3535 }
3536 return 0;
3537}
3538
3539int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
3540 u32 install_type, struct netlink_ext_ack *extack)
3541{
3542 struct hwrm_nvm_install_update_input *install;
3543 struct hwrm_nvm_install_update_output *resp;
3544 struct hwrm_nvm_modify_input *modify;
3545 struct bnxt *bp = netdev_priv(dev);
3546 bool defrag_attempted = false;
3547 dma_addr_t dma_handle;
3548 u8 *kmem = NULL;
3549 u32 modify_len;
3550 u32 item_len;
3551 u8 cmd_err;
3552 u16 index;
3553 int rc;
3554
3555 /* resize before flashing larger image than available space */
3556 rc = bnxt_resize_update_entry(dev, fw_size: fw->size, extack);
3557 if (rc)
3558 return rc;
3559
3560 bnxt_hwrm_fw_set_time(bp);
3561
3562 rc = hwrm_req_init(bp, modify, HWRM_NVM_MODIFY);
3563 if (rc)
3564 return rc;
3565
3566 /* Try allocating a large DMA buffer first. Older fw will
3567 * cause excessive NVRAM erases when using small blocks.
3568 */
3569 modify_len = roundup_pow_of_two(fw->size);
3570 modify_len = min_t(u32, modify_len, BNXT_PKG_DMA_SIZE);
3571 while (1) {
3572 kmem = hwrm_req_dma_slice(bp, req: modify, size: modify_len, dma: &dma_handle);
3573 if (!kmem && modify_len > PAGE_SIZE)
3574 modify_len /= 2;
3575 else
3576 break;
3577 }
3578 if (!kmem) {
3579 hwrm_req_drop(bp, req: modify);
3580 return -ENOMEM;
3581 }
3582
3583 rc = hwrm_req_init(bp, install, HWRM_NVM_INSTALL_UPDATE);
3584 if (rc) {
3585 hwrm_req_drop(bp, req: modify);
3586 return rc;
3587 }
3588
3589 hwrm_req_timeout(bp, req: modify, timeout: bp->hwrm_cmd_max_timeout);
3590 hwrm_req_timeout(bp, req: install, timeout: bp->hwrm_cmd_max_timeout);
3591
3592 hwrm_req_hold(bp, req: modify);
3593 modify->host_src_addr = cpu_to_le64(dma_handle);
3594
3595 resp = hwrm_req_hold(bp, req: install);
3596 if ((install_type & 0xffff) == 0)
3597 install_type >>= 16;
3598 install->install_type = cpu_to_le32(install_type);
3599
3600 do {
3601 u32 copied = 0, len = modify_len;
3602
3603 rc = bnxt_find_nvram_item(dev, type: BNX_DIR_TYPE_UPDATE,
3604 BNX_DIR_ORDINAL_FIRST,
3605 BNX_DIR_EXT_NONE,
3606 index: &index, item_length: &item_len, NULL);
3607 if (rc) {
3608 BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_PKG_UPDATE_AREA_ERR);
3609 break;
3610 }
3611 if (fw->size > item_len) {
3612 BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_SPACE_ERR);
3613 rc = -EFBIG;
3614 break;
3615 }
3616
3617 modify->dir_idx = cpu_to_le16(index);
3618
3619 if (fw->size > modify_len)
3620 modify->flags = BNXT_NVM_MORE_FLAG;
3621 while (copied < fw->size) {
3622 u32 balance = fw->size - copied;
3623
3624 if (balance <= modify_len) {
3625 len = balance;
3626 if (copied)
3627 modify->flags |= BNXT_NVM_LAST_FLAG;
3628 }
3629 memcpy(kmem, fw->data + copied, len);
3630 modify->len = cpu_to_le32(len);
3631 modify->offset = cpu_to_le32(copied);
3632 rc = hwrm_req_send(bp, req: modify);
3633 if (rc)
3634 goto pkg_abort;
3635 copied += len;
3636 }
3637
3638 rc = hwrm_req_send_silent(bp, req: install);
3639 if (!rc)
3640 break;
3641
3642 if (defrag_attempted) {
3643 /* We have tried to defragment already in the previous
3644 * iteration. Return with the result for INSTALL_UPDATE
3645 */
3646 break;
3647 }
3648
3649 cmd_err = ((struct hwrm_err_output *)resp)->cmd_err;
3650
3651 switch (cmd_err) {
3652 case NVM_INSTALL_UPDATE_CMD_ERR_CODE_ANTI_ROLLBACK:
3653 BNXT_NVM_ERR_MSG(dev, extack, MSG_ANTI_ROLLBACK_ERR);
3654 rc = -EALREADY;
3655 break;
3656 case NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR:
3657 install->flags =
3658 cpu_to_le16(NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG);
3659
3660 rc = hwrm_req_send_silent(bp, req: install);
3661 if (!rc)
3662 break;
3663
3664 cmd_err = ((struct hwrm_err_output *)resp)->cmd_err;
3665
3666 if (cmd_err == NVM_INSTALL_UPDATE_CMD_ERR_CODE_NO_SPACE) {
3667 /* FW has cleared NVM area, driver will create
3668 * UPDATE directory and try the flash again
3669 */
3670 defrag_attempted = true;
3671 install->flags = 0;
3672 rc = bnxt_flash_nvram(dev: bp->dev,
3673 dir_type: BNX_DIR_TYPE_UPDATE,
3674 BNX_DIR_ORDINAL_FIRST,
3675 dir_ext: 0, dir_attr: 0, dir_item_len: item_len, NULL, data_len: 0);
3676 if (!rc)
3677 break;
3678 }
3679 fallthrough;
3680 default:
3681 BNXT_NVM_ERR_MSG(dev, extack, MSG_GENERIC_FAILURE_ERR);
3682 }
3683 } while (defrag_attempted && !rc);
3684
3685pkg_abort:
3686 hwrm_req_drop(bp, req: modify);
3687 hwrm_req_drop(bp, req: install);
3688
3689 if (resp->result) {
3690 netdev_err(dev, format: "PKG install error = %d, problem_item = %d\n",
3691 (s8)resp->result, (int)resp->problem_item);
3692 rc = nvm_update_err_to_stderr(dev, result: resp->result, extack);
3693 }
3694 if (rc == -EACCES)
3695 bnxt_print_admin_err(bp);
3696 return rc;
3697}
3698
3699static int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
3700 u32 install_type, struct netlink_ext_ack *extack)
3701{
3702 const struct firmware *fw;
3703 int rc;
3704
3705 rc = request_firmware(fw: &fw, name: filename, device: &dev->dev);
3706 if (rc != 0) {
3707 netdev_err(dev, format: "PKG error %d requesting file: %s\n",
3708 rc, filename);
3709 return rc;
3710 }
3711
3712 rc = bnxt_flash_package_from_fw_obj(dev, fw, install_type, extack);
3713
3714 release_firmware(fw);
3715
3716 return rc;
3717}
3718
3719static int bnxt_flash_device(struct net_device *dev,
3720 struct ethtool_flash *flash)
3721{
3722 if (!BNXT_PF((struct bnxt *)netdev_priv(dev))) {
3723 netdev_err(dev, format: "flashdev not supported from a virtual function\n");
3724 return -EINVAL;
3725 }
3726
3727 if (flash->region == ETHTOOL_FLASH_ALL_REGIONS ||
3728 flash->region > 0xffff)
3729 return bnxt_flash_package_from_file(dev, filename: flash->data,
3730 install_type: flash->region, NULL);
3731
3732 return bnxt_flash_firmware_from_file(dev, dir_type: flash->region, filename: flash->data);
3733}
3734
3735static int nvm_get_dir_info(struct net_device *dev, u32 *entries, u32 *length)
3736{
3737 struct hwrm_nvm_get_dir_info_output *output;
3738 struct hwrm_nvm_get_dir_info_input *req;
3739 struct bnxt *bp = netdev_priv(dev);
3740 int rc;
3741
3742 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_DIR_INFO);
3743 if (rc)
3744 return rc;
3745
3746 output = hwrm_req_hold(bp, req);
3747 rc = hwrm_req_send(bp, req);
3748 if (!rc) {
3749 *entries = le32_to_cpu(output->entries);
3750 *length = le32_to_cpu(output->entry_length);
3751 }
3752 hwrm_req_drop(bp, req);
3753 return rc;
3754}
3755
3756static int bnxt_get_eeprom_len(struct net_device *dev)
3757{
3758 struct bnxt *bp = netdev_priv(dev);
3759
3760 if (BNXT_VF(bp))
3761 return 0;
3762
3763 /* The -1 return value allows the entire 32-bit range of offsets to be
3764 * passed via the ethtool command-line utility.
3765 */
3766 return -1;
3767}
3768
3769static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
3770{
3771 struct bnxt *bp = netdev_priv(dev);
3772 int rc;
3773 u32 dir_entries;
3774 u32 entry_length;
3775 u8 *buf;
3776 size_t buflen;
3777 dma_addr_t dma_handle;
3778 struct hwrm_nvm_get_dir_entries_input *req;
3779
3780 rc = nvm_get_dir_info(dev, entries: &dir_entries, length: &entry_length);
3781 if (rc != 0)
3782 return rc;
3783
3784 if (!dir_entries || !entry_length)
3785 return -EIO;
3786
3787 /* Insert 2 bytes of directory info (count and size of entries) */
3788 if (len < 2)
3789 return -EINVAL;
3790
3791 *data++ = dir_entries;
3792 *data++ = entry_length;
3793 len -= 2;
3794 memset(data, 0xff, len);
3795
3796 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_DIR_ENTRIES);
3797 if (rc)
3798 return rc;
3799
3800 buflen = mul_u32_u32(a: dir_entries, b: entry_length);
3801 buf = hwrm_req_dma_slice(bp, req, size: buflen, dma: &dma_handle);
3802 if (!buf) {
3803 hwrm_req_drop(bp, req);
3804 return -ENOMEM;
3805 }
3806 req->host_dest_addr = cpu_to_le64(dma_handle);
3807
3808 hwrm_req_hold(bp, req); /* hold the slice */
3809 rc = hwrm_req_send(bp, req);
3810 if (rc == 0)
3811 memcpy(data, buf, len > buflen ? buflen : len);
3812 hwrm_req_drop(bp, req);
3813 return rc;
3814}
3815
3816int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
3817 u32 length, u8 *data)
3818{
3819 struct bnxt *bp = netdev_priv(dev);
3820 int rc;
3821 u8 *buf;
3822 dma_addr_t dma_handle;
3823 struct hwrm_nvm_read_input *req;
3824
3825 if (!length)
3826 return -EINVAL;
3827
3828 rc = hwrm_req_init(bp, req, HWRM_NVM_READ);
3829 if (rc)
3830 return rc;
3831
3832 buf = hwrm_req_dma_slice(bp, req, size: length, dma: &dma_handle);
3833 if (!buf) {
3834 hwrm_req_drop(bp, req);
3835 return -ENOMEM;
3836 }
3837
3838 req->host_dest_addr = cpu_to_le64(dma_handle);
3839 req->dir_idx = cpu_to_le16(index);
3840 req->offset = cpu_to_le32(offset);
3841 req->len = cpu_to_le32(length);
3842
3843 hwrm_req_hold(bp, req); /* hold the slice */
3844 rc = hwrm_req_send(bp, req);
3845 if (rc == 0)
3846 memcpy(data, buf, length);
3847 hwrm_req_drop(bp, req);
3848 return rc;
3849}
3850
3851int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
3852 u16 ext, u16 *index, u32 *item_length,
3853 u32 *data_length)
3854{
3855 struct hwrm_nvm_find_dir_entry_output *output;
3856 struct hwrm_nvm_find_dir_entry_input *req;
3857 struct bnxt *bp = netdev_priv(dev);
3858 int rc;
3859
3860 rc = hwrm_req_init(bp, req, HWRM_NVM_FIND_DIR_ENTRY);
3861 if (rc)
3862 return rc;
3863
3864 req->enables = 0;
3865 req->dir_idx = 0;
3866 req->dir_type = cpu_to_le16(type);
3867 req->dir_ordinal = cpu_to_le16(ordinal);
3868 req->dir_ext = cpu_to_le16(ext);
3869 req->opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ;
3870 output = hwrm_req_hold(bp, req);
3871 rc = hwrm_req_send_silent(bp, req);
3872 if (rc == 0) {
3873 if (index)
3874 *index = le16_to_cpu(output->dir_idx);
3875 if (item_length)
3876 *item_length = le32_to_cpu(output->dir_item_length);
3877 if (data_length)
3878 *data_length = le32_to_cpu(output->dir_data_length);
3879 }
3880 hwrm_req_drop(bp, req);
3881 return rc;
3882}
3883
3884static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen)
3885{
3886 char *retval = NULL;
3887 char *p;
3888 char *value;
3889 int field = 0;
3890
3891 if (datalen < 1)
3892 return NULL;
3893 /* null-terminate the log data (removing last '\n'): */
3894 data[datalen - 1] = 0;
3895 for (p = data; *p != 0; p++) {
3896 field = 0;
3897 retval = NULL;
3898 while (*p != 0 && *p != '\n') {
3899 value = p;
3900 while (*p != 0 && *p != '\t' && *p != '\n')
3901 p++;
3902 if (field == desired_field)
3903 retval = value;
3904 if (*p != '\t')
3905 break;
3906 *p = 0;
3907 field++;
3908 p++;
3909 }
3910 if (*p == 0)
3911 break;
3912 *p = 0;
3913 }
3914 return retval;
3915}
3916
3917int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size)
3918{
3919 struct bnxt *bp = netdev_priv(dev);
3920 u16 index = 0;
3921 char *pkgver;
3922 u32 pkglen;
3923 u8 *pkgbuf;
3924 int rc;
3925
3926 rc = bnxt_find_nvram_item(dev, type: BNX_DIR_TYPE_PKG_LOG,
3927 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
3928 index: &index, NULL, data_length: &pkglen);
3929 if (rc)
3930 return rc;
3931
3932 pkgbuf = kzalloc(size: pkglen, GFP_KERNEL);
3933 if (!pkgbuf) {
3934 dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n",
3935 pkglen);
3936 return -ENOMEM;
3937 }
3938
3939 rc = bnxt_get_nvram_item(dev, index, offset: 0, length: pkglen, data: pkgbuf);
3940 if (rc)
3941 goto err;
3942
3943 pkgver = bnxt_parse_pkglog(desired_field: BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, data: pkgbuf,
3944 datalen: pkglen);
3945 if (pkgver && *pkgver != 0 && isdigit(c: *pkgver))
3946 strscpy(ver, pkgver, size);
3947 else
3948 rc = -ENOENT;
3949
3950err:
3951 kfree(objp: pkgbuf);
3952
3953 return rc;
3954}
3955
3956static void bnxt_get_pkgver(struct net_device *dev)
3957{
3958 struct bnxt *bp = netdev_priv(dev);
3959 char buf[FW_VER_STR_LEN];
3960 int len;
3961
3962 if (!bnxt_get_pkginfo(dev, ver: buf, size: sizeof(buf))) {
3963 len = strlen(bp->fw_ver_str);
3964 snprintf(buf: bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
3965 fmt: "/pkg %s", buf);
3966 }
3967}
3968
3969static int bnxt_get_eeprom(struct net_device *dev,
3970 struct ethtool_eeprom *eeprom,
3971 u8 *data)
3972{
3973 u32 index;
3974 u32 offset;
3975
3976 if (eeprom->offset == 0) /* special offset value to get directory */
3977 return bnxt_get_nvram_directory(dev, len: eeprom->len, data);
3978
3979 index = eeprom->offset >> 24;
3980 offset = eeprom->offset & 0xffffff;
3981
3982 if (index == 0) {
3983 netdev_err(dev, format: "unsupported index value: %d\n", index);
3984 return -EINVAL;
3985 }
3986
3987 return bnxt_get_nvram_item(dev, index: index - 1, offset, length: eeprom->len, data);
3988}
3989
3990static int bnxt_erase_nvram_directory(struct net_device *dev, u8 index)
3991{
3992 struct hwrm_nvm_erase_dir_entry_input *req;
3993 struct bnxt *bp = netdev_priv(dev);
3994 int rc;
3995
3996 rc = hwrm_req_init(bp, req, HWRM_NVM_ERASE_DIR_ENTRY);
3997 if (rc)
3998 return rc;
3999
4000 req->dir_idx = cpu_to_le16(index);
4001 return hwrm_req_send(bp, req);
4002}
4003
4004static int bnxt_set_eeprom(struct net_device *dev,
4005 struct ethtool_eeprom *eeprom,
4006 u8 *data)
4007{
4008 struct bnxt *bp = netdev_priv(dev);
4009 u8 index, dir_op;
4010 u16 type, ext, ordinal, attr;
4011
4012 if (!BNXT_PF(bp)) {
4013 netdev_err(dev, format: "NVM write not supported from a virtual function\n");
4014 return -EINVAL;
4015 }
4016
4017 type = eeprom->magic >> 16;
4018
4019 if (type == 0xffff) { /* special value for directory operations */
4020 index = eeprom->magic & 0xff;
4021 dir_op = eeprom->magic >> 8;
4022 if (index == 0)
4023 return -EINVAL;
4024 switch (dir_op) {
4025 case 0x0e: /* erase */
4026 if (eeprom->offset != ~eeprom->magic)
4027 return -EINVAL;
4028 return bnxt_erase_nvram_directory(dev, index: index - 1);
4029 default:
4030 return -EINVAL;
4031 }
4032 }
4033
4034 /* Create or re-write an NVM item: */
4035 if (bnxt_dir_type_is_executable(dir_type: type))
4036 return -EOPNOTSUPP;
4037 ext = eeprom->magic & 0xffff;
4038 ordinal = eeprom->offset >> 16;
4039 attr = eeprom->offset & 0xffff;
4040
4041 return bnxt_flash_nvram(dev, dir_type: type, dir_ordinal: ordinal, dir_ext: ext, dir_attr: attr, dir_item_len: 0, data,
4042 data_len: eeprom->len);
4043}
4044
4045static int bnxt_set_eee(struct net_device *dev, struct ethtool_keee *edata)
4046{
4047 __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
4048 __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp);
4049 struct bnxt *bp = netdev_priv(dev);
4050 struct ethtool_keee *eee = &bp->eee;
4051 struct bnxt_link_info *link_info = &bp->link_info;
4052 int rc = 0;
4053
4054 if (!BNXT_PHY_CFG_ABLE(bp))
4055 return -EOPNOTSUPP;
4056
4057 if (!(bp->phy_flags & BNXT_PHY_FL_EEE_CAP))
4058 return -EOPNOTSUPP;
4059
4060 mutex_lock(&bp->link_lock);
4061 _bnxt_fw_to_linkmode(mode: advertising, fw_speeds: link_info->advertising);
4062 if (!edata->eee_enabled)
4063 goto eee_ok;
4064
4065 if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) {
4066 netdev_warn(dev, format: "EEE requires autoneg\n");
4067 rc = -EINVAL;
4068 goto eee_exit;
4069 }
4070 if (edata->tx_lpi_enabled) {
4071 if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi ||
4072 edata->tx_lpi_timer < bp->lpi_tmr_lo)) {
4073 netdev_warn(dev, format: "Valid LPI timer range is %d and %d microsecs\n",
4074 bp->lpi_tmr_lo, bp->lpi_tmr_hi);
4075 rc = -EINVAL;
4076 goto eee_exit;
4077 } else if (!bp->lpi_tmr_hi) {
4078 edata->tx_lpi_timer = eee->tx_lpi_timer;
4079 }
4080 }
4081 if (linkmode_empty(src: edata->advertised)) {
4082 linkmode_and(dst: edata->advertised, a: advertising, b: eee->supported);
4083 } else if (linkmode_andnot(dst: tmp, src1: edata->advertised, src2: advertising)) {
4084 netdev_warn(dev, format: "EEE advertised must be a subset of autoneg advertised speeds\n");
4085 rc = -EINVAL;
4086 goto eee_exit;
4087 }
4088
4089 linkmode_copy(dst: eee->advertised, src: edata->advertised);
4090 eee->tx_lpi_enabled = edata->tx_lpi_enabled;
4091 eee->tx_lpi_timer = edata->tx_lpi_timer;
4092eee_ok:
4093 eee->eee_enabled = edata->eee_enabled;
4094
4095 if (netif_running(dev))
4096 rc = bnxt_hwrm_set_link_setting(bp, false, true);
4097
4098eee_exit:
4099 mutex_unlock(lock: &bp->link_lock);
4100 return rc;
4101}
4102
4103static int bnxt_get_eee(struct net_device *dev, struct ethtool_keee *edata)
4104{
4105 struct bnxt *bp = netdev_priv(dev);
4106
4107 if (!(bp->phy_flags & BNXT_PHY_FL_EEE_CAP))
4108 return -EOPNOTSUPP;
4109
4110 *edata = bp->eee;
4111 if (!bp->eee.eee_enabled) {
4112 /* Preserve tx_lpi_timer so that the last value will be used
4113 * by default when it is re-enabled.
4114 */
4115 linkmode_zero(dst: edata->advertised);
4116 edata->tx_lpi_enabled = 0;
4117 }
4118
4119 if (!bp->eee.eee_active)
4120 linkmode_zero(dst: edata->lp_advertised);
4121
4122 return 0;
4123}
4124
4125static int bnxt_read_sfp_module_eeprom_info(struct bnxt *bp, u16 i2c_addr,
4126 u16 page_number, u8 bank,
4127 u16 start_addr, u16 data_length,
4128 u8 *buf)
4129{
4130 struct hwrm_port_phy_i2c_read_output *output;
4131 struct hwrm_port_phy_i2c_read_input *req;
4132 int rc, byte_offset = 0;
4133
4134 rc = hwrm_req_init(bp, req, HWRM_PORT_PHY_I2C_READ);
4135 if (rc)
4136 return rc;
4137
4138 output = hwrm_req_hold(bp, req);
4139 req->i2c_slave_addr = i2c_addr;
4140 req->page_number = cpu_to_le16(page_number);
4141 req->port_id = cpu_to_le16(bp->pf.port_id);
4142 do {
4143 u16 xfer_size;
4144
4145 xfer_size = min_t(u16, data_length, BNXT_MAX_PHY_I2C_RESP_SIZE);
4146 data_length -= xfer_size;
4147 req->page_offset = cpu_to_le16(start_addr + byte_offset);
4148 req->data_length = xfer_size;
4149 req->enables =
4150 cpu_to_le32((start_addr + byte_offset ?
4151 PORT_PHY_I2C_READ_REQ_ENABLES_PAGE_OFFSET :
4152 0) |
4153 (bank ?
4154 PORT_PHY_I2C_READ_REQ_ENABLES_BANK_NUMBER :
4155 0));
4156 rc = hwrm_req_send(bp, req);
4157 if (!rc)
4158 memcpy(buf + byte_offset, output->data, xfer_size);
4159 byte_offset += xfer_size;
4160 } while (!rc && data_length > 0);
4161 hwrm_req_drop(bp, req);
4162
4163 return rc;
4164}
4165
4166static int bnxt_get_module_info(struct net_device *dev,
4167 struct ethtool_modinfo *modinfo)
4168{
4169 u8 data[SFF_DIAG_SUPPORT_OFFSET + 1];
4170 struct bnxt *bp = netdev_priv(dev);
4171 int rc;
4172
4173 /* No point in going further if phy status indicates
4174 * module is not inserted or if it is powered down or
4175 * if it is of type 10GBase-T
4176 */
4177 if (bp->link_info.module_status >
4178 PORT_PHY_QCFG_RESP_MODULE_STATUS_WARNINGMSG)
4179 return -EOPNOTSUPP;
4180
4181 /* This feature is not supported in older firmware versions */
4182 if (bp->hwrm_spec_code < 0x10202)
4183 return -EOPNOTSUPP;
4184
4185 rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, page_number: 0, bank: 0, start_addr: 0,
4186 SFF_DIAG_SUPPORT_OFFSET + 1,
4187 buf: data);
4188 if (!rc) {
4189 u8 module_id = data[0];
4190 u8 diag_supported = data[SFF_DIAG_SUPPORT_OFFSET];
4191
4192 switch (module_id) {
4193 case SFF_MODULE_ID_SFP:
4194 modinfo->type = ETH_MODULE_SFF_8472;
4195 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
4196 if (!diag_supported)
4197 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
4198 break;
4199 case SFF_MODULE_ID_QSFP:
4200 case SFF_MODULE_ID_QSFP_PLUS:
4201 modinfo->type = ETH_MODULE_SFF_8436;
4202 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
4203 break;
4204 case SFF_MODULE_ID_QSFP28:
4205 modinfo->type = ETH_MODULE_SFF_8636;
4206 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
4207 break;
4208 default:
4209 rc = -EOPNOTSUPP;
4210 break;
4211 }
4212 }
4213 return rc;
4214}
4215
4216static int bnxt_get_module_eeprom(struct net_device *dev,
4217 struct ethtool_eeprom *eeprom,
4218 u8 *data)
4219{
4220 struct bnxt *bp = netdev_priv(dev);
4221 u16 start = eeprom->offset, length = eeprom->len;
4222 int rc = 0;
4223
4224 memset(data, 0, eeprom->len);
4225
4226 /* Read A0 portion of the EEPROM */
4227 if (start < ETH_MODULE_SFF_8436_LEN) {
4228 if (start + eeprom->len > ETH_MODULE_SFF_8436_LEN)
4229 length = ETH_MODULE_SFF_8436_LEN - start;
4230 rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, page_number: 0, bank: 0,
4231 start_addr: start, data_length: length, buf: data);
4232 if (rc)
4233 return rc;
4234 start += length;
4235 data += length;
4236 length = eeprom->len - length;
4237 }
4238
4239 /* Read A2 portion of the EEPROM */
4240 if (length) {
4241 start -= ETH_MODULE_SFF_8436_LEN;
4242 rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A2, page_number: 0, bank: 0,
4243 start_addr: start, data_length: length, buf: data);
4244 }
4245 return rc;
4246}
4247
4248static int bnxt_get_module_status(struct bnxt *bp, struct netlink_ext_ack *extack)
4249{
4250 if (bp->link_info.module_status <=
4251 PORT_PHY_QCFG_RESP_MODULE_STATUS_WARNINGMSG)
4252 return 0;
4253
4254 switch (bp->link_info.module_status) {
4255 case PORT_PHY_QCFG_RESP_MODULE_STATUS_PWRDOWN:
4256 NL_SET_ERR_MSG_MOD(extack, "Transceiver module is powering down");
4257 break;
4258 case PORT_PHY_QCFG_RESP_MODULE_STATUS_NOTINSERTED:
4259 NL_SET_ERR_MSG_MOD(extack, "Transceiver module not inserted");
4260 break;
4261 case PORT_PHY_QCFG_RESP_MODULE_STATUS_CURRENTFAULT:
4262 NL_SET_ERR_MSG_MOD(extack, "Transceiver module disabled due to current fault");
4263 break;
4264 default:
4265 NL_SET_ERR_MSG_MOD(extack, "Unknown error");
4266 break;
4267 }
4268 return -EINVAL;
4269}
4270
4271static int bnxt_get_module_eeprom_by_page(struct net_device *dev,
4272 const struct ethtool_module_eeprom *page_data,
4273 struct netlink_ext_ack *extack)
4274{
4275 struct bnxt *bp = netdev_priv(dev);
4276 int rc;
4277
4278 rc = bnxt_get_module_status(bp, extack);
4279 if (rc)
4280 return rc;
4281
4282 if (bp->hwrm_spec_code < 0x10202) {
4283 NL_SET_ERR_MSG_MOD(extack, "Firmware version too old");
4284 return -EINVAL;
4285 }
4286
4287 if (page_data->bank && !(bp->phy_flags & BNXT_PHY_FL_BANK_SEL)) {
4288 NL_SET_ERR_MSG_MOD(extack, "Firmware not capable for bank selection");
4289 return -EINVAL;
4290 }
4291
4292 rc = bnxt_read_sfp_module_eeprom_info(bp, i2c_addr: page_data->i2c_address << 1,
4293 page_number: page_data->page, bank: page_data->bank,
4294 start_addr: page_data->offset,
4295 data_length: page_data->length,
4296 buf: page_data->data);
4297 if (rc) {
4298 NL_SET_ERR_MSG_MOD(extack, "Module`s eeprom read failed");
4299 return rc;
4300 }
4301 return page_data->length;
4302}
4303
4304static int bnxt_nway_reset(struct net_device *dev)
4305{
4306 int rc = 0;
4307
4308 struct bnxt *bp = netdev_priv(dev);
4309 struct bnxt_link_info *link_info = &bp->link_info;
4310
4311 if (!BNXT_PHY_CFG_ABLE(bp))
4312 return -EOPNOTSUPP;
4313
4314 if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
4315 return -EINVAL;
4316
4317 if (netif_running(dev))
4318 rc = bnxt_hwrm_set_link_setting(bp, true, false);
4319
4320 return rc;
4321}
4322
4323static int bnxt_set_phys_id(struct net_device *dev,
4324 enum ethtool_phys_id_state state)
4325{
4326 struct hwrm_port_led_cfg_input *req;
4327 struct bnxt *bp = netdev_priv(dev);
4328 struct bnxt_pf_info *pf = &bp->pf;
4329 struct bnxt_led_cfg *led_cfg;
4330 u8 led_state;
4331 __le16 duration;
4332 int rc, i;
4333
4334 if (!bp->num_leds || BNXT_VF(bp))
4335 return -EOPNOTSUPP;
4336
4337 if (state == ETHTOOL_ID_ACTIVE) {
4338 led_state = PORT_LED_CFG_REQ_LED0_STATE_BLINKALT;
4339 duration = cpu_to_le16(500);
4340 } else if (state == ETHTOOL_ID_INACTIVE) {
4341 led_state = PORT_LED_CFG_REQ_LED1_STATE_DEFAULT;
4342 duration = cpu_to_le16(0);
4343 } else {
4344 return -EINVAL;
4345 }
4346 rc = hwrm_req_init(bp, req, HWRM_PORT_LED_CFG);
4347 if (rc)
4348 return rc;
4349
4350 req->port_id = cpu_to_le16(pf->port_id);
4351 req->num_leds = bp->num_leds;
4352 led_cfg = (struct bnxt_led_cfg *)&req->led0_id;
4353 for (i = 0; i < bp->num_leds; i++, led_cfg++) {
4354 req->enables |= BNXT_LED_DFLT_ENABLES(i);
4355 led_cfg->led_id = bp->leds[i].led_id;
4356 led_cfg->led_state = led_state;
4357 led_cfg->led_blink_on = duration;
4358 led_cfg->led_blink_off = duration;
4359 led_cfg->led_group_id = bp->leds[i].led_group_id;
4360 }
4361 return hwrm_req_send(bp, req);
4362}
4363
4364static int bnxt_hwrm_selftest_irq(struct bnxt *bp, u16 cmpl_ring)
4365{
4366 struct hwrm_selftest_irq_input *req;
4367 int rc;
4368
4369 rc = hwrm_req_init(bp, req, HWRM_SELFTEST_IRQ);
4370 if (rc)
4371 return rc;
4372
4373 req->cmpl_ring = cpu_to_le16(cmpl_ring);
4374 return hwrm_req_send(bp, req);
4375}
4376
4377static int bnxt_test_irq(struct bnxt *bp)
4378{
4379 int i;
4380
4381 for (i = 0; i < bp->cp_nr_rings; i++) {
4382 u16 cmpl_ring = bp->grp_info[i].cp_fw_ring_id;
4383 int rc;
4384
4385 rc = bnxt_hwrm_selftest_irq(bp, cmpl_ring);
4386 if (rc)
4387 return rc;
4388 }
4389 return 0;
4390}
4391
4392static int bnxt_hwrm_mac_loopback(struct bnxt *bp, bool enable)
4393{
4394 struct hwrm_port_mac_cfg_input *req;
4395 int rc;
4396
4397 rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
4398 if (rc)
4399 return rc;
4400
4401 req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_LPBK);
4402 if (enable)
4403 req->lpbk = PORT_MAC_CFG_REQ_LPBK_LOCAL;
4404 else
4405 req->lpbk = PORT_MAC_CFG_REQ_LPBK_NONE;
4406 return hwrm_req_send(bp, req);
4407}
4408
4409static int bnxt_query_force_speeds(struct bnxt *bp, u16 *force_speeds)
4410{
4411 struct hwrm_port_phy_qcaps_output *resp;
4412 struct hwrm_port_phy_qcaps_input *req;
4413 int rc;
4414
4415 rc = hwrm_req_init(bp, req, HWRM_PORT_PHY_QCAPS);
4416 if (rc)
4417 return rc;
4418
4419 resp = hwrm_req_hold(bp, req);
4420 rc = hwrm_req_send(bp, req);
4421 if (!rc)
4422 *force_speeds = le16_to_cpu(resp->supported_speeds_force_mode);
4423
4424 hwrm_req_drop(bp, req);
4425 return rc;
4426}
4427
4428static int bnxt_disable_an_for_lpbk(struct bnxt *bp,
4429 struct hwrm_port_phy_cfg_input *req)
4430{
4431 struct bnxt_link_info *link_info = &bp->link_info;
4432 u16 fw_advertising;
4433 u16 fw_speed;
4434 int rc;
4435
4436 if (!link_info->autoneg ||
4437 (bp->phy_flags & BNXT_PHY_FL_AN_PHY_LPBK))
4438 return 0;
4439
4440 rc = bnxt_query_force_speeds(bp, force_speeds: &fw_advertising);
4441 if (rc)
4442 return rc;
4443
4444 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_1GB;
4445 if (BNXT_LINK_IS_UP(bp))
4446 fw_speed = bp->link_info.link_speed;
4447 else if (fw_advertising & BNXT_LINK_SPEED_MSK_10GB)
4448 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10GB;
4449 else if (fw_advertising & BNXT_LINK_SPEED_MSK_25GB)
4450 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_25GB;
4451 else if (fw_advertising & BNXT_LINK_SPEED_MSK_40GB)
4452 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB;
4453 else if (fw_advertising & BNXT_LINK_SPEED_MSK_50GB)
4454 fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB;
4455
4456 req->force_link_speed = cpu_to_le16(fw_speed);
4457 req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE |
4458 PORT_PHY_CFG_REQ_FLAGS_RESET_PHY);
4459 rc = hwrm_req_send(bp, req);
4460 req->flags = 0;
4461 req->force_link_speed = cpu_to_le16(0);
4462 return rc;
4463}
4464
4465static int bnxt_hwrm_phy_loopback(struct bnxt *bp, bool enable, bool ext)
4466{
4467 struct hwrm_port_phy_cfg_input *req;
4468 int rc;
4469
4470 rc = hwrm_req_init(bp, req, HWRM_PORT_PHY_CFG);
4471 if (rc)
4472 return rc;
4473
4474 /* prevent bnxt_disable_an_for_lpbk() from consuming the request */
4475 hwrm_req_hold(bp, req);
4476
4477 if (enable) {
4478 bnxt_disable_an_for_lpbk(bp, req);
4479 if (ext)
4480 req->lpbk = PORT_PHY_CFG_REQ_LPBK_EXTERNAL;
4481 else
4482 req->lpbk = PORT_PHY_CFG_REQ_LPBK_LOCAL;
4483 } else {
4484 req->lpbk = PORT_PHY_CFG_REQ_LPBK_NONE;
4485 }
4486 req->enables = cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_LPBK);
4487 rc = hwrm_req_send(bp, req);
4488 hwrm_req_drop(bp, req);
4489 return rc;
4490}
4491
4492static int bnxt_rx_loopback(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
4493 u32 raw_cons, int pkt_size)
4494{
4495 struct bnxt_napi *bnapi = cpr->bnapi;
4496 struct bnxt_rx_ring_info *rxr;
4497 struct bnxt_sw_rx_bd *rx_buf;
4498 struct rx_cmp *rxcmp;
4499 u16 cp_cons, cons;
4500 u8 *data;
4501 u32 len;
4502 int i;
4503
4504 rxr = bnapi->rx_ring;
4505 cp_cons = RING_CMP(raw_cons);
4506 rxcmp = (struct rx_cmp *)
4507 &cpr->cp_desc_ring[CP_RING(cp_cons)][CP_IDX(cp_cons)];
4508 cons = rxcmp->rx_cmp_opaque;
4509 rx_buf = &rxr->rx_buf_ring[cons];
4510 data = rx_buf->data_ptr;
4511 len = le32_to_cpu(rxcmp->rx_cmp_len_flags_type) >> RX_CMP_LEN_SHIFT;
4512 if (len != pkt_size)
4513 return -EIO;
4514 i = ETH_ALEN;
4515 if (!ether_addr_equal(addr1: data + i, addr2: bnapi->bp->dev->dev_addr))
4516 return -EIO;
4517 i += ETH_ALEN;
4518 for ( ; i < pkt_size; i++) {
4519 if (data[i] != (u8)(i & 0xff))
4520 return -EIO;
4521 }
4522 return 0;
4523}
4524
4525static int bnxt_poll_loopback(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
4526 int pkt_size)
4527{
4528 struct tx_cmp *txcmp;
4529 int rc = -EIO;
4530 u32 raw_cons;
4531 u32 cons;
4532 int i;
4533
4534 raw_cons = cpr->cp_raw_cons;
4535 for (i = 0; i < 200; i++) {
4536 cons = RING_CMP(raw_cons);
4537 txcmp = &cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)];
4538
4539 if (!TX_CMP_VALID(txcmp, raw_cons)) {
4540 udelay(5);
4541 continue;
4542 }
4543
4544 /* The valid test of the entry must be done first before
4545 * reading any further.
4546 */
4547 dma_rmb();
4548 if (TX_CMP_TYPE(txcmp) == CMP_TYPE_RX_L2_CMP ||
4549 TX_CMP_TYPE(txcmp) == CMP_TYPE_RX_L2_V3_CMP) {
4550 rc = bnxt_rx_loopback(bp, cpr, raw_cons, pkt_size);
4551 raw_cons = NEXT_RAW_CMP(raw_cons);
4552 raw_cons = NEXT_RAW_CMP(raw_cons);
4553 break;
4554 }
4555 raw_cons = NEXT_RAW_CMP(raw_cons);
4556 }
4557 cpr->cp_raw_cons = raw_cons;
4558 return rc;
4559}
4560
4561static int bnxt_run_loopback(struct bnxt *bp)
4562{
4563 struct bnxt_tx_ring_info *txr = &bp->tx_ring[0];
4564 struct bnxt_rx_ring_info *rxr = &bp->rx_ring[0];
4565 struct bnxt_cp_ring_info *cpr;
4566 int pkt_size, i = 0;
4567 struct sk_buff *skb;
4568 dma_addr_t map;
4569 u8 *data;
4570 int rc;
4571
4572 cpr = &rxr->bnapi->cp_ring;
4573 if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS)
4574 cpr = rxr->rx_cpr;
4575 pkt_size = min(bp->dev->mtu + ETH_HLEN, bp->rx_copy_thresh);
4576 skb = netdev_alloc_skb(dev: bp->dev, length: pkt_size);
4577 if (!skb)
4578 return -ENOMEM;
4579 data = skb_put(skb, len: pkt_size);
4580 ether_addr_copy(dst: &data[i], src: bp->dev->dev_addr);
4581 i += ETH_ALEN;
4582 ether_addr_copy(dst: &data[i], src: bp->dev->dev_addr);
4583 i += ETH_ALEN;
4584 for ( ; i < pkt_size; i++)
4585 data[i] = (u8)(i & 0xff);
4586
4587 map = dma_map_single(&bp->pdev->dev, skb->data, pkt_size,
4588 DMA_TO_DEVICE);
4589 if (dma_mapping_error(dev: &bp->pdev->dev, dma_addr: map)) {
4590 dev_kfree_skb(skb);
4591 return -EIO;
4592 }
4593 bnxt_xmit_bd(bp, txr, mapping: map, len: pkt_size, NULL);
4594
4595 /* Sync BD data before updating doorbell */
4596 wmb();
4597
4598 bnxt_db_write(bp, db: &txr->tx_db, idx: txr->tx_prod);
4599 rc = bnxt_poll_loopback(bp, cpr, pkt_size);
4600
4601 dma_unmap_single(&bp->pdev->dev, map, pkt_size, DMA_TO_DEVICE);
4602 dev_kfree_skb(skb);
4603 return rc;
4604}
4605
4606static int bnxt_run_fw_tests(struct bnxt *bp, u8 test_mask, u8 *test_results)
4607{
4608 struct hwrm_selftest_exec_output *resp;
4609 struct hwrm_selftest_exec_input *req;
4610 int rc;
4611
4612 rc = hwrm_req_init(bp, req, HWRM_SELFTEST_EXEC);
4613 if (rc)
4614 return rc;
4615
4616 hwrm_req_timeout(bp, req, timeout: bp->test_info->timeout);
4617 req->flags = test_mask;
4618
4619 resp = hwrm_req_hold(bp, req);
4620 rc = hwrm_req_send(bp, req);
4621 *test_results = resp->test_success;
4622 hwrm_req_drop(bp, req);
4623 return rc;
4624}
4625
4626#define BNXT_DRV_TESTS 4
4627#define BNXT_MACLPBK_TEST_IDX (bp->num_tests - BNXT_DRV_TESTS)
4628#define BNXT_PHYLPBK_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 1)
4629#define BNXT_EXTLPBK_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 2)
4630#define BNXT_IRQ_TEST_IDX (BNXT_MACLPBK_TEST_IDX + 3)
4631
4632static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
4633 u64 *buf)
4634{
4635 struct bnxt *bp = netdev_priv(dev);
4636 bool do_ext_lpbk = false;
4637 bool offline = false;
4638 u8 test_results = 0;
4639 u8 test_mask = 0;
4640 int rc = 0, i;
4641
4642 if (!bp->num_tests || !BNXT_PF(bp))
4643 return;
4644 memset(buf, 0, sizeof(u64) * bp->num_tests);
4645 if (!netif_running(dev)) {
4646 etest->flags |= ETH_TEST_FL_FAILED;
4647 return;
4648 }
4649
4650 if ((etest->flags & ETH_TEST_FL_EXTERNAL_LB) &&
4651 (bp->phy_flags & BNXT_PHY_FL_EXT_LPBK))
4652 do_ext_lpbk = true;
4653
4654 if (etest->flags & ETH_TEST_FL_OFFLINE) {
4655 if (bp->pf.active_vfs || !BNXT_SINGLE_PF(bp)) {
4656 etest->flags |= ETH_TEST_FL_FAILED;
4657 netdev_warn(dev, format: "Offline tests cannot be run with active VFs or on shared PF\n");
4658 return;
4659 }
4660 offline = true;
4661 }
4662
4663 for (i = 0; i < bp->num_tests - BNXT_DRV_TESTS; i++) {
4664 u8 bit_val = 1 << i;
4665
4666 if (!(bp->test_info->offline_mask & bit_val))
4667 test_mask |= bit_val;
4668 else if (offline)
4669 test_mask |= bit_val;
4670 }
4671 if (!offline) {
4672 bnxt_run_fw_tests(bp, test_mask, test_results: &test_results);
4673 } else {
4674 bnxt_ulp_stop(bp);
4675 bnxt_close_nic(bp, true, false);
4676 bnxt_run_fw_tests(bp, test_mask, test_results: &test_results);
4677
4678 buf[BNXT_MACLPBK_TEST_IDX] = 1;
4679 bnxt_hwrm_mac_loopback(bp, enable: true);
4680 msleep(msecs: 250);
4681 rc = bnxt_half_open_nic(bp);
4682 if (rc) {
4683 bnxt_hwrm_mac_loopback(bp, enable: false);
4684 etest->flags |= ETH_TEST_FL_FAILED;
4685 bnxt_ulp_start(bp, err: rc);
4686 return;
4687 }
4688 if (bnxt_run_loopback(bp))
4689 etest->flags |= ETH_TEST_FL_FAILED;
4690 else
4691 buf[BNXT_MACLPBK_TEST_IDX] = 0;
4692
4693 bnxt_hwrm_mac_loopback(bp, enable: false);
4694 bnxt_hwrm_phy_loopback(bp, enable: true, ext: false);
4695 msleep(msecs: 1000);
4696 if (bnxt_run_loopback(bp)) {
4697 buf[BNXT_PHYLPBK_TEST_IDX] = 1;
4698 etest->flags |= ETH_TEST_FL_FAILED;
4699 }
4700 if (do_ext_lpbk) {
4701 etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
4702 bnxt_hwrm_phy_loopback(bp, enable: true, ext: true);
4703 msleep(msecs: 1000);
4704 if (bnxt_run_loopback(bp)) {
4705 buf[BNXT_EXTLPBK_TEST_IDX] = 1;
4706 etest->flags |= ETH_TEST_FL_FAILED;
4707 }
4708 }
4709 bnxt_hwrm_phy_loopback(bp, enable: false, ext: false);
4710 bnxt_half_close_nic(bp);
4711 rc = bnxt_open_nic(bp, true, true);
4712 bnxt_ulp_start(bp, err: rc);
4713 }
4714 if (rc || bnxt_test_irq(bp)) {
4715 buf[BNXT_IRQ_TEST_IDX] = 1;
4716 etest->flags |= ETH_TEST_FL_FAILED;
4717 }
4718 for (i = 0; i < bp->num_tests - BNXT_DRV_TESTS; i++) {
4719 u8 bit_val = 1 << i;
4720
4721 if ((test_mask & bit_val) && !(test_results & bit_val)) {
4722 buf[i] = 1;
4723 etest->flags |= ETH_TEST_FL_FAILED;
4724 }
4725 }
4726}
4727
4728static int bnxt_reset(struct net_device *dev, u32 *flags)
4729{
4730 struct bnxt *bp = netdev_priv(dev);
4731 bool reload = false;
4732 u32 req = *flags;
4733
4734 if (!req)
4735 return -EINVAL;
4736
4737 if (!BNXT_PF(bp)) {
4738 netdev_err(dev, format: "Reset is not supported from a VF\n");
4739 return -EOPNOTSUPP;
4740 }
4741
4742 if (pci_vfs_assigned(dev: bp->pdev) &&
4743 !(bp->fw_cap & BNXT_FW_CAP_HOT_RESET)) {
4744 netdev_err(dev,
4745 format: "Reset not allowed when VFs are assigned to VMs\n");
4746 return -EBUSY;
4747 }
4748
4749 if ((req & BNXT_FW_RESET_CHIP) == BNXT_FW_RESET_CHIP) {
4750 /* This feature is not supported in older firmware versions */
4751 if (bp->hwrm_spec_code >= 0x10803) {
4752 if (!bnxt_firmware_reset_chip(dev)) {
4753 netdev_info(dev, format: "Firmware reset request successful.\n");
4754 if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET))
4755 reload = true;
4756 *flags &= ~BNXT_FW_RESET_CHIP;
4757 }
4758 } else if (req == BNXT_FW_RESET_CHIP) {
4759 return -EOPNOTSUPP; /* only request, fail hard */
4760 }
4761 }
4762
4763 if (!BNXT_CHIP_P4_PLUS(bp) && (req & BNXT_FW_RESET_AP)) {
4764 /* This feature is not supported in older firmware versions */
4765 if (bp->hwrm_spec_code >= 0x10803) {
4766 if (!bnxt_firmware_reset_ap(dev)) {
4767 netdev_info(dev, format: "Reset application processor successful.\n");
4768 reload = true;
4769 *flags &= ~BNXT_FW_RESET_AP;
4770 }
4771 } else if (req == BNXT_FW_RESET_AP) {
4772 return -EOPNOTSUPP; /* only request, fail hard */
4773 }
4774 }
4775
4776 if (reload)
4777 netdev_info(dev, format: "Reload driver to complete reset\n");
4778
4779 return 0;
4780}
4781
4782static int bnxt_set_dump(struct net_device *dev, struct ethtool_dump *dump)
4783{
4784 struct bnxt *bp = netdev_priv(dev);
4785
4786 if (dump->flag > BNXT_DUMP_CRASH) {
4787 netdev_info(dev, format: "Supports only Live(0) and Crash(1) dumps.\n");
4788 return -EINVAL;
4789 }
4790
4791 if (!IS_ENABLED(CONFIG_TEE_BNXT_FW) && dump->flag == BNXT_DUMP_CRASH) {
4792 netdev_info(dev, format: "Cannot collect crash dump as TEE_BNXT_FW config option is not enabled.\n");
4793 return -EOPNOTSUPP;
4794 }
4795
4796 bp->dump_flag = dump->flag;
4797 return 0;
4798}
4799
4800static int bnxt_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
4801{
4802 struct bnxt *bp = netdev_priv(dev);
4803
4804 if (bp->hwrm_spec_code < 0x10801)
4805 return -EOPNOTSUPP;
4806
4807 dump->version = bp->ver_resp.hwrm_fw_maj_8b << 24 |
4808 bp->ver_resp.hwrm_fw_min_8b << 16 |
4809 bp->ver_resp.hwrm_fw_bld_8b << 8 |
4810 bp->ver_resp.hwrm_fw_rsvd_8b;
4811
4812 dump->flag = bp->dump_flag;
4813 dump->len = bnxt_get_coredump_length(bp, dump_type: bp->dump_flag);
4814 return 0;
4815}
4816
4817static int bnxt_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
4818 void *buf)
4819{
4820 struct bnxt *bp = netdev_priv(dev);
4821
4822 if (bp->hwrm_spec_code < 0x10801)
4823 return -EOPNOTSUPP;
4824
4825 memset(buf, 0, dump->len);
4826
4827 dump->flag = bp->dump_flag;
4828 return bnxt_get_coredump(bp, dump_type: dump->flag, buf, dump_len: &dump->len);
4829}
4830
4831static int bnxt_get_ts_info(struct net_device *dev,
4832 struct ethtool_ts_info *info)
4833{
4834 struct bnxt *bp = netdev_priv(dev);
4835 struct bnxt_ptp_cfg *ptp;
4836
4837 ptp = bp->ptp_cfg;
4838 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
4839 SOF_TIMESTAMPING_RX_SOFTWARE |
4840 SOF_TIMESTAMPING_SOFTWARE;
4841
4842 info->phc_index = -1;
4843 if (!ptp)
4844 return 0;
4845
4846 info->so_timestamping |= SOF_TIMESTAMPING_TX_HARDWARE |
4847 SOF_TIMESTAMPING_RX_HARDWARE |
4848 SOF_TIMESTAMPING_RAW_HARDWARE;
4849 if (ptp->ptp_clock)
4850 info->phc_index = ptp_clock_index(ptp: ptp->ptp_clock);
4851
4852 info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
4853
4854 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
4855 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
4856 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
4857
4858 if (bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS)
4859 info->rx_filters |= (1 << HWTSTAMP_FILTER_ALL);
4860 return 0;
4861}
4862
4863void bnxt_ethtool_init(struct bnxt *bp)
4864{
4865 struct hwrm_selftest_qlist_output *resp;
4866 struct hwrm_selftest_qlist_input *req;
4867 struct bnxt_test_info *test_info;
4868 struct net_device *dev = bp->dev;
4869 int i, rc;
4870
4871 if (!(bp->fw_cap & BNXT_FW_CAP_PKG_VER))
4872 bnxt_get_pkgver(dev);
4873
4874 bp->num_tests = 0;
4875 if (bp->hwrm_spec_code < 0x10704 || !BNXT_PF(bp))
4876 return;
4877
4878 test_info = bp->test_info;
4879 if (!test_info) {
4880 test_info = kzalloc(size: sizeof(*bp->test_info), GFP_KERNEL);
4881 if (!test_info)
4882 return;
4883 bp->test_info = test_info;
4884 }
4885
4886 if (hwrm_req_init(bp, req, HWRM_SELFTEST_QLIST))
4887 return;
4888
4889 resp = hwrm_req_hold(bp, req);
4890 rc = hwrm_req_send_silent(bp, req);
4891 if (rc)
4892 goto ethtool_init_exit;
4893
4894 bp->num_tests = resp->num_tests + BNXT_DRV_TESTS;
4895 if (bp->num_tests > BNXT_MAX_TEST)
4896 bp->num_tests = BNXT_MAX_TEST;
4897
4898 test_info->offline_mask = resp->offline_tests;
4899 test_info->timeout = le16_to_cpu(resp->test_timeout);
4900 if (!test_info->timeout)
4901 test_info->timeout = HWRM_CMD_TIMEOUT;
4902 for (i = 0; i < bp->num_tests; i++) {
4903 char *str = test_info->string[i];
4904 char *fw_str = resp->test_name[i];
4905
4906 if (i == BNXT_MACLPBK_TEST_IDX) {
4907 strcpy(p: str, q: "Mac loopback test (offline)");
4908 } else if (i == BNXT_PHYLPBK_TEST_IDX) {
4909 strcpy(p: str, q: "Phy loopback test (offline)");
4910 } else if (i == BNXT_EXTLPBK_TEST_IDX) {
4911 strcpy(p: str, q: "Ext loopback test (offline)");
4912 } else if (i == BNXT_IRQ_TEST_IDX) {
4913 strcpy(p: str, q: "Interrupt_test (offline)");
4914 } else {
4915 snprintf(buf: str, ETH_GSTRING_LEN, fmt: "%s test (%s)",
4916 fw_str, test_info->offline_mask & (1 << i) ?
4917 "offline" : "online");
4918 }
4919 }
4920
4921ethtool_init_exit:
4922 hwrm_req_drop(bp, req);
4923}
4924
4925static void bnxt_get_eth_phy_stats(struct net_device *dev,
4926 struct ethtool_eth_phy_stats *phy_stats)
4927{
4928 struct bnxt *bp = netdev_priv(dev);
4929 u64 *rx;
4930
4931 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
4932 return;
4933
4934 rx = bp->rx_port_stats_ext.sw_stats;
4935 phy_stats->SymbolErrorDuringCarrier =
4936 *(rx + BNXT_RX_STATS_EXT_OFFSET(rx_pcs_symbol_err));
4937}
4938
4939static void bnxt_get_eth_mac_stats(struct net_device *dev,
4940 struct ethtool_eth_mac_stats *mac_stats)
4941{
4942 struct bnxt *bp = netdev_priv(dev);
4943 u64 *rx, *tx;
4944
4945 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
4946 return;
4947
4948 rx = bp->port_stats.sw_stats;
4949 tx = bp->port_stats.sw_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
4950
4951 mac_stats->FramesReceivedOK =
4952 BNXT_GET_RX_PORT_STATS64(rx, rx_good_frames);
4953 mac_stats->FramesTransmittedOK =
4954 BNXT_GET_TX_PORT_STATS64(tx, tx_good_frames);
4955 mac_stats->FrameCheckSequenceErrors =
4956 BNXT_GET_RX_PORT_STATS64(rx, rx_fcs_err_frames);
4957 mac_stats->AlignmentErrors =
4958 BNXT_GET_RX_PORT_STATS64(rx, rx_align_err_frames);
4959 mac_stats->OutOfRangeLengthField =
4960 BNXT_GET_RX_PORT_STATS64(rx, rx_oor_len_frames);
4961}
4962
4963static void bnxt_get_eth_ctrl_stats(struct net_device *dev,
4964 struct ethtool_eth_ctrl_stats *ctrl_stats)
4965{
4966 struct bnxt *bp = netdev_priv(dev);
4967 u64 *rx;
4968
4969 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
4970 return;
4971
4972 rx = bp->port_stats.sw_stats;
4973 ctrl_stats->MACControlFramesReceived =
4974 BNXT_GET_RX_PORT_STATS64(rx, rx_ctrl_frames);
4975}
4976
4977static const struct ethtool_rmon_hist_range bnxt_rmon_ranges[] = {
4978 { 0, 64 },
4979 { 65, 127 },
4980 { 128, 255 },
4981 { 256, 511 },
4982 { 512, 1023 },
4983 { 1024, 1518 },
4984 { 1519, 2047 },
4985 { 2048, 4095 },
4986 { 4096, 9216 },
4987 { 9217, 16383 },
4988 {}
4989};
4990
4991static void bnxt_get_rmon_stats(struct net_device *dev,
4992 struct ethtool_rmon_stats *rmon_stats,
4993 const struct ethtool_rmon_hist_range **ranges)
4994{
4995 struct bnxt *bp = netdev_priv(dev);
4996 u64 *rx, *tx;
4997
4998 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS))
4999 return;
5000
5001 rx = bp->port_stats.sw_stats;
5002 tx = bp->port_stats.sw_stats + BNXT_TX_PORT_STATS_BYTE_OFFSET / 8;
5003
5004 rmon_stats->jabbers =
5005 BNXT_GET_RX_PORT_STATS64(rx, rx_jbr_frames);
5006 rmon_stats->oversize_pkts =
5007 BNXT_GET_RX_PORT_STATS64(rx, rx_ovrsz_frames);
5008 rmon_stats->undersize_pkts =
5009 BNXT_GET_RX_PORT_STATS64(rx, rx_undrsz_frames);
5010
5011 rmon_stats->hist[0] = BNXT_GET_RX_PORT_STATS64(rx, rx_64b_frames);
5012 rmon_stats->hist[1] = BNXT_GET_RX_PORT_STATS64(rx, rx_65b_127b_frames);
5013 rmon_stats->hist[2] = BNXT_GET_RX_PORT_STATS64(rx, rx_128b_255b_frames);
5014 rmon_stats->hist[3] = BNXT_GET_RX_PORT_STATS64(rx, rx_256b_511b_frames);
5015 rmon_stats->hist[4] =
5016 BNXT_GET_RX_PORT_STATS64(rx, rx_512b_1023b_frames);
5017 rmon_stats->hist[5] =
5018 BNXT_GET_RX_PORT_STATS64(rx, rx_1024b_1518b_frames);
5019 rmon_stats->hist[6] =
5020 BNXT_GET_RX_PORT_STATS64(rx, rx_1519b_2047b_frames);
5021 rmon_stats->hist[7] =
5022 BNXT_GET_RX_PORT_STATS64(rx, rx_2048b_4095b_frames);
5023 rmon_stats->hist[8] =
5024 BNXT_GET_RX_PORT_STATS64(rx, rx_4096b_9216b_frames);
5025 rmon_stats->hist[9] =
5026 BNXT_GET_RX_PORT_STATS64(rx, rx_9217b_16383b_frames);
5027
5028 rmon_stats->hist_tx[0] =
5029 BNXT_GET_TX_PORT_STATS64(tx, tx_64b_frames);
5030 rmon_stats->hist_tx[1] =
5031 BNXT_GET_TX_PORT_STATS64(tx, tx_65b_127b_frames);
5032 rmon_stats->hist_tx[2] =
5033 BNXT_GET_TX_PORT_STATS64(tx, tx_128b_255b_frames);
5034 rmon_stats->hist_tx[3] =
5035 BNXT_GET_TX_PORT_STATS64(tx, tx_256b_511b_frames);
5036 rmon_stats->hist_tx[4] =
5037 BNXT_GET_TX_PORT_STATS64(tx, tx_512b_1023b_frames);
5038 rmon_stats->hist_tx[5] =
5039 BNXT_GET_TX_PORT_STATS64(tx, tx_1024b_1518b_frames);
5040 rmon_stats->hist_tx[6] =
5041 BNXT_GET_TX_PORT_STATS64(tx, tx_1519b_2047b_frames);
5042 rmon_stats->hist_tx[7] =
5043 BNXT_GET_TX_PORT_STATS64(tx, tx_2048b_4095b_frames);
5044 rmon_stats->hist_tx[8] =
5045 BNXT_GET_TX_PORT_STATS64(tx, tx_4096b_9216b_frames);
5046 rmon_stats->hist_tx[9] =
5047 BNXT_GET_TX_PORT_STATS64(tx, tx_9217b_16383b_frames);
5048
5049 *ranges = bnxt_rmon_ranges;
5050}
5051
5052static void bnxt_get_link_ext_stats(struct net_device *dev,
5053 struct ethtool_link_ext_stats *stats)
5054{
5055 struct bnxt *bp = netdev_priv(dev);
5056 u64 *rx;
5057
5058 if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
5059 return;
5060
5061 rx = bp->rx_port_stats_ext.sw_stats;
5062 stats->link_down_events =
5063 *(rx + BNXT_RX_STATS_EXT_OFFSET(link_down_events));
5064}
5065
5066void bnxt_ethtool_free(struct bnxt *bp)
5067{
5068 kfree(objp: bp->test_info);
5069 bp->test_info = NULL;
5070}
5071
5072const struct ethtool_ops bnxt_ethtool_ops = {
5073 .cap_link_lanes_supported = 1,
5074 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
5075 ETHTOOL_COALESCE_MAX_FRAMES |
5076 ETHTOOL_COALESCE_USECS_IRQ |
5077 ETHTOOL_COALESCE_MAX_FRAMES_IRQ |
5078 ETHTOOL_COALESCE_STATS_BLOCK_USECS |
5079 ETHTOOL_COALESCE_USE_ADAPTIVE_RX |
5080 ETHTOOL_COALESCE_USE_CQE,
5081 .get_link_ksettings = bnxt_get_link_ksettings,
5082 .set_link_ksettings = bnxt_set_link_ksettings,
5083 .get_fec_stats = bnxt_get_fec_stats,
5084 .get_fecparam = bnxt_get_fecparam,
5085 .set_fecparam = bnxt_set_fecparam,
5086 .get_pause_stats = bnxt_get_pause_stats,
5087 .get_pauseparam = bnxt_get_pauseparam,
5088 .set_pauseparam = bnxt_set_pauseparam,
5089 .get_drvinfo = bnxt_get_drvinfo,
5090 .get_regs_len = bnxt_get_regs_len,
5091 .get_regs = bnxt_get_regs,
5092 .get_wol = bnxt_get_wol,
5093 .set_wol = bnxt_set_wol,
5094 .get_coalesce = bnxt_get_coalesce,
5095 .set_coalesce = bnxt_set_coalesce,
5096 .get_msglevel = bnxt_get_msglevel,
5097 .set_msglevel = bnxt_set_msglevel,
5098 .get_sset_count = bnxt_get_sset_count,
5099 .get_strings = bnxt_get_strings,
5100 .get_ethtool_stats = bnxt_get_ethtool_stats,
5101 .set_ringparam = bnxt_set_ringparam,
5102 .get_ringparam = bnxt_get_ringparam,
5103 .get_channels = bnxt_get_channels,
5104 .set_channels = bnxt_set_channels,
5105 .get_rxnfc = bnxt_get_rxnfc,
5106 .set_rxnfc = bnxt_set_rxnfc,
5107 .get_rxfh_indir_size = bnxt_get_rxfh_indir_size,
5108 .get_rxfh_key_size = bnxt_get_rxfh_key_size,
5109 .get_rxfh = bnxt_get_rxfh,
5110 .set_rxfh = bnxt_set_rxfh,
5111 .flash_device = bnxt_flash_device,
5112 .get_eeprom_len = bnxt_get_eeprom_len,
5113 .get_eeprom = bnxt_get_eeprom,
5114 .set_eeprom = bnxt_set_eeprom,
5115 .get_link = bnxt_get_link,
5116 .get_link_ext_stats = bnxt_get_link_ext_stats,
5117 .get_eee = bnxt_get_eee,
5118 .set_eee = bnxt_set_eee,
5119 .get_module_info = bnxt_get_module_info,
5120 .get_module_eeprom = bnxt_get_module_eeprom,
5121 .get_module_eeprom_by_page = bnxt_get_module_eeprom_by_page,
5122 .nway_reset = bnxt_nway_reset,
5123 .set_phys_id = bnxt_set_phys_id,
5124 .self_test = bnxt_self_test,
5125 .get_ts_info = bnxt_get_ts_info,
5126 .reset = bnxt_reset,
5127 .set_dump = bnxt_set_dump,
5128 .get_dump_flag = bnxt_get_dump_flag,
5129 .get_dump_data = bnxt_get_dump_data,
5130 .get_eth_phy_stats = bnxt_get_eth_phy_stats,
5131 .get_eth_mac_stats = bnxt_get_eth_mac_stats,
5132 .get_eth_ctrl_stats = bnxt_get_eth_ctrl_stats,
5133 .get_rmon_stats = bnxt_get_rmon_stats,
5134};
5135

source code of linux/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c