1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 #include <linux/ethtool.h>
4 #include <linux/linkmode.h>
5 #include <linux/netdevice.h>
6 #include <linux/nvme.h>
8 #include <linux/io-64-nonatomic-lo-hi.h>
10 #include <linux/rtnetlink.h>
13 #include "funeth_txrx.h"
15 /* Min queue depth. The smallest power-of-2 supporting jumbo frames with 4K
16 * pages is 8. Require it for all types of queues though some could work with
19 #define FUNETH_MIN_QDEPTH 8
21 static const char mac_tx_stat_names
[][ETH_GSTRING_LEN
] = {
22 "mac_tx_octets_total",
23 "mac_tx_frames_total",
24 "mac_tx_vlan_frames_ok",
25 "mac_tx_unicast_frames",
26 "mac_tx_multicast_frames",
27 "mac_tx_broadcast_frames",
47 static const char mac_rx_stat_names
[][ETH_GSTRING_LEN
] = {
48 "mac_rx_octets_total",
49 "mac_rx_frames_total",
50 "mac_rx_VLAN_frames_ok",
51 "mac_rx_unicast_frames",
52 "mac_rx_multicast_frames",
53 "mac_rx_broadcast_frames",
56 "mac_rx_alignment_errors",
75 static const char * const txq_stat_names
[] = {
80 "tx_encapsulated_tso",
86 "tx_tls_encrypted_packets",
87 "tx_tls_encrypted_bytes",
89 "tx_tls_drop_no_sync_data",
92 static const char * const xdpq_stat_names
[] = {
96 "tx_xdp_mapping_errors",
99 static const char * const rxq_stat_names
[] = {
111 "rx_budget_exhausted",
115 static const char * const tls_stat_names
[] = {
121 static void fun_link_modes_to_ethtool(u64 modes
,
122 unsigned long *ethtool_modes_map
)
124 #define ADD_LINK_MODE(mode) \
125 __set_bit(ETHTOOL_LINK_MODE_ ## mode ## _BIT, ethtool_modes_map)
127 if (modes
& FUN_PORT_CAP_AUTONEG
)
128 ADD_LINK_MODE(Autoneg
);
129 if (modes
& FUN_PORT_CAP_1000_X
)
130 ADD_LINK_MODE(1000baseX_Full
);
131 if (modes
& FUN_PORT_CAP_10G_R
) {
132 ADD_LINK_MODE(10000baseCR_Full
);
133 ADD_LINK_MODE(10000baseSR_Full
);
134 ADD_LINK_MODE(10000baseLR_Full
);
135 ADD_LINK_MODE(10000baseER_Full
);
137 if (modes
& FUN_PORT_CAP_25G_R
) {
138 ADD_LINK_MODE(25000baseCR_Full
);
139 ADD_LINK_MODE(25000baseSR_Full
);
141 if (modes
& FUN_PORT_CAP_40G_R4
) {
142 ADD_LINK_MODE(40000baseCR4_Full
);
143 ADD_LINK_MODE(40000baseSR4_Full
);
144 ADD_LINK_MODE(40000baseLR4_Full
);
146 if (modes
& FUN_PORT_CAP_50G_R2
) {
147 ADD_LINK_MODE(50000baseCR2_Full
);
148 ADD_LINK_MODE(50000baseSR2_Full
);
150 if (modes
& FUN_PORT_CAP_50G_R
) {
151 ADD_LINK_MODE(50000baseCR_Full
);
152 ADD_LINK_MODE(50000baseSR_Full
);
153 ADD_LINK_MODE(50000baseLR_ER_FR_Full
);
155 if (modes
& FUN_PORT_CAP_100G_R4
) {
156 ADD_LINK_MODE(100000baseCR4_Full
);
157 ADD_LINK_MODE(100000baseSR4_Full
);
158 ADD_LINK_MODE(100000baseLR4_ER4_Full
);
160 if (modes
& FUN_PORT_CAP_100G_R2
) {
161 ADD_LINK_MODE(100000baseCR2_Full
);
162 ADD_LINK_MODE(100000baseSR2_Full
);
163 ADD_LINK_MODE(100000baseLR2_ER2_FR2_Full
);
165 if (modes
& FUN_PORT_CAP_FEC_NONE
)
166 ADD_LINK_MODE(FEC_NONE
);
167 if (modes
& FUN_PORT_CAP_FEC_FC
)
168 ADD_LINK_MODE(FEC_BASER
);
169 if (modes
& FUN_PORT_CAP_FEC_RS
)
170 ADD_LINK_MODE(FEC_RS
);
171 if (modes
& FUN_PORT_CAP_RX_PAUSE
)
172 ADD_LINK_MODE(Pause
);
177 static void set_asym_pause(u64 advertising
, struct ethtool_link_ksettings
*ks
)
179 bool rx_pause
, tx_pause
;
181 rx_pause
= advertising
& FUN_PORT_CAP_RX_PAUSE
;
182 tx_pause
= advertising
& FUN_PORT_CAP_TX_PAUSE
;
183 if (tx_pause
^ rx_pause
)
184 ethtool_link_ksettings_add_link_mode(ks
, advertising
,
188 static unsigned int fun_port_type(unsigned int xcvr
)
203 static int fun_get_link_ksettings(struct net_device
*netdev
,
204 struct ethtool_link_ksettings
*ks
)
206 const struct funeth_priv
*fp
= netdev_priv(netdev
);
207 unsigned int seq
, speed
, xcvr
;
211 ethtool_link_ksettings_zero_link_mode(ks
, supported
);
212 ethtool_link_ksettings_zero_link_mode(ks
, advertising
);
213 ethtool_link_ksettings_zero_link_mode(ks
, lp_advertising
);
215 /* Link settings change asynchronously, take a consistent snapshot */
217 seq
= read_seqcount_begin(&fp
->link_seq
);
218 link_up
= netif_carrier_ok(netdev
);
219 speed
= fp
->link_speed
;
220 xcvr
= fp
->xcvr_type
;
221 lp_advertising
= fp
->lp_advertising
;
222 } while (read_seqcount_retry(&fp
->link_seq
, seq
));
225 ks
->base
.speed
= speed
;
226 ks
->base
.duplex
= DUPLEX_FULL
;
227 fun_link_modes_to_ethtool(lp_advertising
,
228 ks
->link_modes
.lp_advertising
);
230 ks
->base
.speed
= SPEED_UNKNOWN
;
231 ks
->base
.duplex
= DUPLEX_UNKNOWN
;
234 ks
->base
.autoneg
= (fp
->advertising
& FUN_PORT_CAP_AUTONEG
) ?
235 AUTONEG_ENABLE
: AUTONEG_DISABLE
;
236 ks
->base
.port
= fun_port_type(xcvr
);
238 fun_link_modes_to_ethtool(fp
->port_caps
, ks
->link_modes
.supported
);
239 if (fp
->port_caps
& (FUN_PORT_CAP_RX_PAUSE
| FUN_PORT_CAP_TX_PAUSE
))
240 ethtool_link_ksettings_add_link_mode(ks
, supported
, Asym_Pause
);
242 fun_link_modes_to_ethtool(fp
->advertising
, ks
->link_modes
.advertising
);
243 set_asym_pause(fp
->advertising
, ks
);
247 static u64
fun_advert_modes(const struct ethtool_link_ksettings
*ks
)
251 #define HAS_MODE(mode) \
252 ethtool_link_ksettings_test_link_mode(ks, advertising, mode)
254 if (HAS_MODE(1000baseX_Full
))
255 modes
|= FUN_PORT_CAP_1000_X
;
256 if (HAS_MODE(10000baseCR_Full
) || HAS_MODE(10000baseSR_Full
) ||
257 HAS_MODE(10000baseLR_Full
) || HAS_MODE(10000baseER_Full
))
258 modes
|= FUN_PORT_CAP_10G_R
;
259 if (HAS_MODE(25000baseCR_Full
) || HAS_MODE(25000baseSR_Full
))
260 modes
|= FUN_PORT_CAP_25G_R
;
261 if (HAS_MODE(40000baseCR4_Full
) || HAS_MODE(40000baseSR4_Full
) ||
262 HAS_MODE(40000baseLR4_Full
))
263 modes
|= FUN_PORT_CAP_40G_R4
;
264 if (HAS_MODE(50000baseCR2_Full
) || HAS_MODE(50000baseSR2_Full
))
265 modes
|= FUN_PORT_CAP_50G_R2
;
266 if (HAS_MODE(50000baseCR_Full
) || HAS_MODE(50000baseSR_Full
) ||
267 HAS_MODE(50000baseLR_ER_FR_Full
))
268 modes
|= FUN_PORT_CAP_50G_R
;
269 if (HAS_MODE(100000baseCR4_Full
) || HAS_MODE(100000baseSR4_Full
) ||
270 HAS_MODE(100000baseLR4_ER4_Full
))
271 modes
|= FUN_PORT_CAP_100G_R4
;
272 if (HAS_MODE(100000baseCR2_Full
) || HAS_MODE(100000baseSR2_Full
) ||
273 HAS_MODE(100000baseLR2_ER2_FR2_Full
))
274 modes
|= FUN_PORT_CAP_100G_R2
;
280 static u64
fun_speed_to_link_mode(unsigned int speed
)
284 return FUN_PORT_CAP_100G_R4
| FUN_PORT_CAP_100G_R2
;
286 return FUN_PORT_CAP_50G_R
| FUN_PORT_CAP_50G_R2
;
288 return FUN_PORT_CAP_40G_R4
;
290 return FUN_PORT_CAP_25G_R
;
292 return FUN_PORT_CAP_10G_R
;
294 return FUN_PORT_CAP_1000_X
;
300 static int fun_change_advert(struct funeth_priv
*fp
, u64 new_advert
)
304 if (new_advert
== fp
->advertising
)
307 err
= fun_port_write_cmd(fp
, FUN_ADMIN_PORT_KEY_ADVERT
, new_advert
);
309 fp
->advertising
= new_advert
;
313 #define FUN_PORT_CAP_FEC_MASK \
314 (FUN_PORT_CAP_FEC_NONE | FUN_PORT_CAP_FEC_FC | FUN_PORT_CAP_FEC_RS)
316 static int fun_set_link_ksettings(struct net_device
*netdev
,
317 const struct ethtool_link_ksettings
*ks
)
319 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported
) = {};
320 struct funeth_priv
*fp
= netdev_priv(netdev
);
323 /* eswitch ports don't support mode changes */
324 if (fp
->port_caps
& FUN_PORT_CAP_VPORT
)
327 if (ks
->base
.duplex
== DUPLEX_HALF
)
329 if (ks
->base
.autoneg
== AUTONEG_ENABLE
&&
330 !(fp
->port_caps
& FUN_PORT_CAP_AUTONEG
))
333 if (ks
->base
.autoneg
== AUTONEG_ENABLE
) {
334 if (linkmode_empty(ks
->link_modes
.advertising
))
337 fun_link_modes_to_ethtool(fp
->port_caps
, supported
);
338 if (!linkmode_subset(ks
->link_modes
.advertising
, supported
))
341 new_advert
= fun_advert_modes(ks
) | FUN_PORT_CAP_AUTONEG
;
343 new_advert
= fun_speed_to_link_mode(ks
->base
.speed
);
344 new_advert
&= fp
->port_caps
;
348 new_advert
|= fp
->advertising
&
349 (FUN_PORT_CAP_PAUSE_MASK
| FUN_PORT_CAP_FEC_MASK
);
351 return fun_change_advert(fp
, new_advert
);
354 static void fun_get_pauseparam(struct net_device
*netdev
,
355 struct ethtool_pauseparam
*pause
)
357 const struct funeth_priv
*fp
= netdev_priv(netdev
);
358 u8 active_pause
= fp
->active_fc
;
360 pause
->rx_pause
= !!(active_pause
& FUN_PORT_CAP_RX_PAUSE
);
361 pause
->tx_pause
= !!(active_pause
& FUN_PORT_CAP_TX_PAUSE
);
362 pause
->autoneg
= !!(fp
->advertising
& FUN_PORT_CAP_AUTONEG
);
365 static int fun_set_pauseparam(struct net_device
*netdev
,
366 struct ethtool_pauseparam
*pause
)
368 struct funeth_priv
*fp
= netdev_priv(netdev
);
371 if (fp
->port_caps
& FUN_PORT_CAP_VPORT
)
373 /* Forcing PAUSE settings with AN enabled is unsupported. */
374 if (!pause
->autoneg
&& (fp
->advertising
& FUN_PORT_CAP_AUTONEG
))
376 if (pause
->autoneg
&& !(fp
->advertising
& FUN_PORT_CAP_AUTONEG
))
378 if (pause
->tx_pause
&& !(fp
->port_caps
& FUN_PORT_CAP_TX_PAUSE
))
380 if (pause
->rx_pause
&& !(fp
->port_caps
& FUN_PORT_CAP_RX_PAUSE
))
383 new_advert
= fp
->advertising
& ~FUN_PORT_CAP_PAUSE_MASK
;
385 new_advert
|= FUN_PORT_CAP_TX_PAUSE
;
387 new_advert
|= FUN_PORT_CAP_RX_PAUSE
;
389 return fun_change_advert(fp
, new_advert
);
392 static int fun_restart_an(struct net_device
*netdev
)
394 struct funeth_priv
*fp
= netdev_priv(netdev
);
396 if (!(fp
->advertising
& FUN_PORT_CAP_AUTONEG
))
399 return fun_port_write_cmd(fp
, FUN_ADMIN_PORT_KEY_ADVERT
,
400 FUN_PORT_CAP_AUTONEG
);
403 static int fun_set_phys_id(struct net_device
*netdev
,
404 enum ethtool_phys_id_state state
)
406 struct funeth_priv
*fp
= netdev_priv(netdev
);
409 if (fp
->port_caps
& FUN_PORT_CAP_VPORT
)
411 if (state
!= ETHTOOL_ID_ACTIVE
&& state
!= ETHTOOL_ID_INACTIVE
)
414 beacon
= state
== ETHTOOL_ID_ACTIVE
? FUN_PORT_LED_BEACON_ON
:
415 FUN_PORT_LED_BEACON_OFF
;
416 return fun_port_write_cmd(fp
, FUN_ADMIN_PORT_KEY_LED
, beacon
);
419 static void fun_get_drvinfo(struct net_device
*netdev
,
420 struct ethtool_drvinfo
*info
)
422 const struct funeth_priv
*fp
= netdev_priv(netdev
);
424 strscpy(info
->driver
, KBUILD_MODNAME
, sizeof(info
->driver
));
425 strscpy(info
->bus_info
, pci_name(fp
->pdev
), sizeof(info
->bus_info
));
428 static u32
fun_get_msglevel(struct net_device
*netdev
)
430 const struct funeth_priv
*fp
= netdev_priv(netdev
);
432 return fp
->msg_enable
;
435 static void fun_set_msglevel(struct net_device
*netdev
, u32 value
)
437 struct funeth_priv
*fp
= netdev_priv(netdev
);
439 fp
->msg_enable
= value
;
442 static int fun_get_regs_len(struct net_device
*dev
)
444 return NVME_REG_ACQ
+ sizeof(u64
);
447 static void fun_get_regs(struct net_device
*dev
, struct ethtool_regs
*regs
,
450 const struct funeth_priv
*fp
= netdev_priv(dev
);
451 void __iomem
*bar
= fp
->fdev
->bar
;
454 *(u64
*)(buf
+ NVME_REG_CAP
) = readq(bar
+ NVME_REG_CAP
);
455 *(u32
*)(buf
+ NVME_REG_VS
) = readl(bar
+ NVME_REG_VS
);
456 *(u32
*)(buf
+ NVME_REG_INTMS
) = readl(bar
+ NVME_REG_INTMS
);
457 *(u32
*)(buf
+ NVME_REG_INTMC
) = readl(bar
+ NVME_REG_INTMC
);
458 *(u32
*)(buf
+ NVME_REG_CC
) = readl(bar
+ NVME_REG_CC
);
459 *(u32
*)(buf
+ NVME_REG_CSTS
) = readl(bar
+ NVME_REG_CSTS
);
460 *(u32
*)(buf
+ NVME_REG_AQA
) = readl(bar
+ NVME_REG_AQA
);
461 *(u64
*)(buf
+ NVME_REG_ASQ
) = readq(bar
+ NVME_REG_ASQ
);
462 *(u64
*)(buf
+ NVME_REG_ACQ
) = readq(bar
+ NVME_REG_ACQ
);
465 static int fun_get_coalesce(struct net_device
*netdev
,
466 struct ethtool_coalesce
*coal
,
467 struct kernel_ethtool_coalesce
*kcoal
,
468 struct netlink_ext_ack
*ext_ack
)
470 const struct funeth_priv
*fp
= netdev_priv(netdev
);
472 coal
->rx_coalesce_usecs
= fp
->rx_coal_usec
;
473 coal
->rx_max_coalesced_frames
= fp
->rx_coal_count
;
474 coal
->use_adaptive_rx_coalesce
= !fp
->cq_irq_db
;
475 coal
->tx_coalesce_usecs
= fp
->tx_coal_usec
;
476 coal
->tx_max_coalesced_frames
= fp
->tx_coal_count
;
480 static int fun_set_coalesce(struct net_device
*netdev
,
481 struct ethtool_coalesce
*coal
,
482 struct kernel_ethtool_coalesce
*kcoal
,
483 struct netlink_ext_ack
*ext_ack
)
485 struct funeth_priv
*fp
= netdev_priv(netdev
);
486 struct funeth_rxq
**rxqs
;
487 unsigned int i
, db_val
;
489 if (coal
->rx_coalesce_usecs
> FUN_DB_INTCOAL_USEC_M
||
490 coal
->rx_max_coalesced_frames
> FUN_DB_INTCOAL_ENTRIES_M
||
491 (coal
->rx_coalesce_usecs
| coal
->rx_max_coalesced_frames
) == 0 ||
492 coal
->tx_coalesce_usecs
> FUN_DB_INTCOAL_USEC_M
||
493 coal
->tx_max_coalesced_frames
> FUN_DB_INTCOAL_ENTRIES_M
||
494 (coal
->tx_coalesce_usecs
| coal
->tx_max_coalesced_frames
) == 0)
497 /* a timer is required if there's any coalescing */
498 if ((coal
->rx_max_coalesced_frames
> 1 && !coal
->rx_coalesce_usecs
) ||
499 (coal
->tx_max_coalesced_frames
> 1 && !coal
->tx_coalesce_usecs
))
502 fp
->rx_coal_usec
= coal
->rx_coalesce_usecs
;
503 fp
->rx_coal_count
= coal
->rx_max_coalesced_frames
;
504 fp
->tx_coal_usec
= coal
->tx_coalesce_usecs
;
505 fp
->tx_coal_count
= coal
->tx_max_coalesced_frames
;
507 db_val
= FUN_IRQ_CQ_DB(fp
->rx_coal_usec
, fp
->rx_coal_count
);
508 WRITE_ONCE(fp
->cq_irq_db
, db_val
);
510 rxqs
= rtnl_dereference(fp
->rxqs
);
514 for (i
= 0; i
< netdev
->real_num_rx_queues
; i
++)
515 WRITE_ONCE(rxqs
[i
]->irq_db_val
, db_val
);
517 db_val
= FUN_IRQ_SQ_DB(fp
->tx_coal_usec
, fp
->tx_coal_count
);
518 for (i
= 0; i
< netdev
->real_num_tx_queues
; i
++)
519 WRITE_ONCE(fp
->txqs
[i
]->irq_db_val
, db_val
);
524 static void fun_get_channels(struct net_device
*netdev
,
525 struct ethtool_channels
*chan
)
527 chan
->max_rx
= netdev
->num_rx_queues
;
528 chan
->rx_count
= netdev
->real_num_rx_queues
;
530 chan
->max_tx
= netdev
->num_tx_queues
;
531 chan
->tx_count
= netdev
->real_num_tx_queues
;
534 static int fun_set_channels(struct net_device
*netdev
,
535 struct ethtool_channels
*chan
)
537 if (!chan
->tx_count
|| !chan
->rx_count
)
540 if (chan
->tx_count
== netdev
->real_num_tx_queues
&&
541 chan
->rx_count
== netdev
->real_num_rx_queues
)
544 if (netif_running(netdev
))
545 return fun_change_num_queues(netdev
, chan
->tx_count
,
548 fun_set_ring_count(netdev
, chan
->tx_count
, chan
->rx_count
);
552 static void fun_get_ringparam(struct net_device
*netdev
,
553 struct ethtool_ringparam
*ring
,
554 struct kernel_ethtool_ringparam
*kring
,
555 struct netlink_ext_ack
*extack
)
557 const struct funeth_priv
*fp
= netdev_priv(netdev
);
558 unsigned int max_depth
= fp
->fdev
->q_depth
;
560 /* We size CQs to be twice the RQ depth so max RQ depth is half the
563 ring
->rx_max_pending
= max_depth
/ 2;
564 ring
->tx_max_pending
= max_depth
;
566 ring
->rx_pending
= fp
->rq_depth
;
567 ring
->tx_pending
= fp
->sq_depth
;
569 kring
->rx_buf_len
= PAGE_SIZE
;
570 kring
->cqe_size
= FUNETH_CQE_SIZE
;
573 static int fun_set_ringparam(struct net_device
*netdev
,
574 struct ethtool_ringparam
*ring
,
575 struct kernel_ethtool_ringparam
*kring
,
576 struct netlink_ext_ack
*extack
)
578 struct funeth_priv
*fp
= netdev_priv(netdev
);
581 if (ring
->rx_mini_pending
|| ring
->rx_jumbo_pending
)
584 /* queue depths must be powers-of-2 */
585 if (!is_power_of_2(ring
->rx_pending
) ||
586 !is_power_of_2(ring
->tx_pending
))
589 if (ring
->rx_pending
< FUNETH_MIN_QDEPTH
||
590 ring
->tx_pending
< FUNETH_MIN_QDEPTH
)
593 if (fp
->sq_depth
== ring
->tx_pending
&&
594 fp
->rq_depth
== ring
->rx_pending
)
597 if (netif_running(netdev
)) {
598 struct fun_qset req
= {
599 .cq_depth
= 2 * ring
->rx_pending
,
600 .rq_depth
= ring
->rx_pending
,
601 .sq_depth
= ring
->tx_pending
604 rc
= fun_replace_queues(netdev
, &req
, extack
);
609 fp
->sq_depth
= ring
->tx_pending
;
610 fp
->rq_depth
= ring
->rx_pending
;
611 fp
->cq_depth
= 2 * fp
->rq_depth
;
615 static int fun_get_sset_count(struct net_device
*dev
, int sset
)
617 const struct funeth_priv
*fp
= netdev_priv(dev
);
622 n
= (dev
->real_num_tx_queues
+ 1) * ARRAY_SIZE(txq_stat_names
) +
623 (dev
->real_num_rx_queues
+ 1) * ARRAY_SIZE(rxq_stat_names
) +
624 (fp
->num_xdpqs
+ 1) * ARRAY_SIZE(xdpq_stat_names
) +
625 ARRAY_SIZE(tls_stat_names
);
626 if (fp
->port_caps
& FUN_PORT_CAP_STATS
) {
627 n
+= ARRAY_SIZE(mac_tx_stat_names
) +
628 ARRAY_SIZE(mac_rx_stat_names
);
637 static void fun_get_strings(struct net_device
*netdev
, u32 sset
, u8
*data
)
639 const struct funeth_priv
*fp
= netdev_priv(netdev
);
645 if (fp
->port_caps
& FUN_PORT_CAP_STATS
) {
646 memcpy(p
, mac_tx_stat_names
, sizeof(mac_tx_stat_names
));
647 p
+= sizeof(mac_tx_stat_names
);
648 memcpy(p
, mac_rx_stat_names
, sizeof(mac_rx_stat_names
));
649 p
+= sizeof(mac_rx_stat_names
);
652 for (i
= 0; i
< netdev
->real_num_tx_queues
; i
++) {
653 for (j
= 0; j
< ARRAY_SIZE(txq_stat_names
); j
++)
654 ethtool_sprintf(&p
, "%s[%u]", txq_stat_names
[j
],
657 for (j
= 0; j
< ARRAY_SIZE(txq_stat_names
); j
++)
658 ethtool_puts(&p
, txq_stat_names
[j
]);
660 for (i
= 0; i
< fp
->num_xdpqs
; i
++) {
661 for (j
= 0; j
< ARRAY_SIZE(xdpq_stat_names
); j
++)
662 ethtool_sprintf(&p
, "%s[%u]",
663 xdpq_stat_names
[j
], i
);
665 for (j
= 0; j
< ARRAY_SIZE(xdpq_stat_names
); j
++)
666 ethtool_puts(&p
, xdpq_stat_names
[j
]);
668 for (i
= 0; i
< netdev
->real_num_rx_queues
; i
++) {
669 for (j
= 0; j
< ARRAY_SIZE(rxq_stat_names
); j
++)
670 ethtool_sprintf(&p
, "%s[%u]", rxq_stat_names
[j
],
673 for (j
= 0; j
< ARRAY_SIZE(rxq_stat_names
); j
++)
674 ethtool_puts(&p
, rxq_stat_names
[j
]);
676 for (j
= 0; j
< ARRAY_SIZE(tls_stat_names
); j
++)
677 ethtool_puts(&p
, tls_stat_names
[j
]);
684 static u64
*get_mac_stats(const struct funeth_priv
*fp
, u64
*data
)
687 *data++ = be64_to_cpu(fp->stats[PORT_MAC_RX_STATS_MAX + PORT_MAC_TX_##s])
689 TX_STAT(etherStatsOctets
);
690 TX_STAT(etherStatsPkts
);
691 TX_STAT(VLANTransmittedOK
);
692 TX_STAT(ifOutUcastPkts
);
693 TX_STAT(ifOutMulticastPkts
);
694 TX_STAT(ifOutBroadcastPkts
);
695 TX_STAT(ifOutErrors
);
696 TX_STAT(CBFCPAUSEFramesTransmitted_0
);
697 TX_STAT(CBFCPAUSEFramesTransmitted_1
);
698 TX_STAT(CBFCPAUSEFramesTransmitted_2
);
699 TX_STAT(CBFCPAUSEFramesTransmitted_3
);
700 TX_STAT(CBFCPAUSEFramesTransmitted_4
);
701 TX_STAT(CBFCPAUSEFramesTransmitted_5
);
702 TX_STAT(CBFCPAUSEFramesTransmitted_6
);
703 TX_STAT(CBFCPAUSEFramesTransmitted_7
);
704 TX_STAT(CBFCPAUSEFramesTransmitted_8
);
705 TX_STAT(CBFCPAUSEFramesTransmitted_9
);
706 TX_STAT(CBFCPAUSEFramesTransmitted_10
);
707 TX_STAT(CBFCPAUSEFramesTransmitted_11
);
708 TX_STAT(CBFCPAUSEFramesTransmitted_12
);
709 TX_STAT(CBFCPAUSEFramesTransmitted_13
);
710 TX_STAT(CBFCPAUSEFramesTransmitted_14
);
711 TX_STAT(CBFCPAUSEFramesTransmitted_15
);
713 #define RX_STAT(s) *data++ = be64_to_cpu(fp->stats[PORT_MAC_RX_##s])
715 RX_STAT(etherStatsOctets
);
716 RX_STAT(etherStatsPkts
);
717 RX_STAT(VLANReceivedOK
);
718 RX_STAT(ifInUcastPkts
);
719 RX_STAT(ifInMulticastPkts
);
720 RX_STAT(ifInBroadcastPkts
);
721 RX_STAT(etherStatsDropEvents
);
723 RX_STAT(aAlignmentErrors
);
724 RX_STAT(CBFCPAUSEFramesReceived_0
);
725 RX_STAT(CBFCPAUSEFramesReceived_1
);
726 RX_STAT(CBFCPAUSEFramesReceived_2
);
727 RX_STAT(CBFCPAUSEFramesReceived_3
);
728 RX_STAT(CBFCPAUSEFramesReceived_4
);
729 RX_STAT(CBFCPAUSEFramesReceived_5
);
730 RX_STAT(CBFCPAUSEFramesReceived_6
);
731 RX_STAT(CBFCPAUSEFramesReceived_7
);
732 RX_STAT(CBFCPAUSEFramesReceived_8
);
733 RX_STAT(CBFCPAUSEFramesReceived_9
);
734 RX_STAT(CBFCPAUSEFramesReceived_10
);
735 RX_STAT(CBFCPAUSEFramesReceived_11
);
736 RX_STAT(CBFCPAUSEFramesReceived_12
);
737 RX_STAT(CBFCPAUSEFramesReceived_13
);
738 RX_STAT(CBFCPAUSEFramesReceived_14
);
739 RX_STAT(CBFCPAUSEFramesReceived_15
);
747 static void fun_get_ethtool_stats(struct net_device
*netdev
,
748 struct ethtool_stats
*stats
, u64
*data
)
750 const struct funeth_priv
*fp
= netdev_priv(netdev
);
751 struct funeth_txq_stats txs
;
752 struct funeth_rxq_stats rxs
;
753 struct funeth_txq
**xdpqs
;
754 struct funeth_rxq
**rxqs
;
755 unsigned int i
, start
;
758 if (fp
->port_caps
& FUN_PORT_CAP_STATS
)
759 data
= get_mac_stats(fp
, data
);
761 rxqs
= rtnl_dereference(fp
->rxqs
);
765 #define ADD_STAT(cnt) do { \
766 *data = (cnt); *tot++ += *data++; \
770 totals
= data
+ netdev
->real_num_tx_queues
* ARRAY_SIZE(txq_stat_names
);
772 for (i
= 0; i
< netdev
->real_num_tx_queues
; i
++) {
775 FUN_QSTAT_READ(fp
->txqs
[i
], start
, txs
);
777 ADD_STAT(txs
.tx_pkts
);
778 ADD_STAT(txs
.tx_bytes
);
779 ADD_STAT(txs
.tx_cso
);
780 ADD_STAT(txs
.tx_tso
);
781 ADD_STAT(txs
.tx_encap_tso
);
782 ADD_STAT(txs
.tx_uso
);
783 ADD_STAT(txs
.tx_more
);
784 ADD_STAT(txs
.tx_nstops
);
785 ADD_STAT(txs
.tx_nrestarts
);
786 ADD_STAT(txs
.tx_map_err
);
787 ADD_STAT(txs
.tx_tls_pkts
);
788 ADD_STAT(txs
.tx_tls_bytes
);
789 ADD_STAT(txs
.tx_tls_fallback
);
790 ADD_STAT(txs
.tx_tls_drops
);
792 data
+= ARRAY_SIZE(txq_stat_names
);
795 xdpqs
= rtnl_dereference(fp
->xdpqs
);
796 totals
= data
+ fp
->num_xdpqs
* ARRAY_SIZE(xdpq_stat_names
);
798 for (i
= 0; i
< fp
->num_xdpqs
; i
++) {
801 FUN_QSTAT_READ(xdpqs
[i
], start
, txs
);
803 ADD_STAT(txs
.tx_pkts
);
804 ADD_STAT(txs
.tx_bytes
);
805 ADD_STAT(txs
.tx_xdp_full
);
806 ADD_STAT(txs
.tx_map_err
);
808 data
+= ARRAY_SIZE(xdpq_stat_names
);
811 totals
= data
+ netdev
->real_num_rx_queues
* ARRAY_SIZE(rxq_stat_names
);
813 for (i
= 0; i
< netdev
->real_num_rx_queues
; i
++) {
816 FUN_QSTAT_READ(rxqs
[i
], start
, rxs
);
818 ADD_STAT(rxs
.rx_pkts
);
819 ADD_STAT(rxs
.rx_bytes
);
820 ADD_STAT(rxs
.rx_cso
);
821 ADD_STAT(rxs
.gro_pkts
);
822 ADD_STAT(rxs
.gro_merged
);
823 ADD_STAT(rxs
.xdp_tx
);
824 ADD_STAT(rxs
.xdp_redir
);
825 ADD_STAT(rxs
.xdp_drops
);
826 ADD_STAT(rxs
.rx_bufs
);
827 ADD_STAT(rxs
.rx_page_alloc
);
828 ADD_STAT(rxs
.rx_mem_drops
+ rxs
.xdp_err
);
829 ADD_STAT(rxs
.rx_budget
);
830 ADD_STAT(rxs
.rx_map_err
);
832 data
+= ARRAY_SIZE(rxq_stat_names
);
835 *data
++ = atomic64_read(&fp
->tx_tls_add
);
836 *data
++ = atomic64_read(&fp
->tx_tls_del
);
837 *data
++ = atomic64_read(&fp
->tx_tls_resync
);
840 #define RX_STAT(fp, s) be64_to_cpu((fp)->stats[PORT_MAC_RX_##s])
841 #define TX_STAT(fp, s) \
842 be64_to_cpu((fp)->stats[PORT_MAC_RX_STATS_MAX + PORT_MAC_TX_##s])
843 #define FEC_STAT(fp, s) \
844 be64_to_cpu((fp)->stats[PORT_MAC_RX_STATS_MAX + \
845 PORT_MAC_TX_STATS_MAX + PORT_MAC_FEC_##s])
847 static void fun_get_pause_stats(struct net_device
*netdev
,
848 struct ethtool_pause_stats
*stats
)
850 const struct funeth_priv
*fp
= netdev_priv(netdev
);
852 if (!(fp
->port_caps
& FUN_PORT_CAP_STATS
))
855 stats
->tx_pause_frames
= TX_STAT(fp
, aPAUSEMACCtrlFramesTransmitted
);
856 stats
->rx_pause_frames
= RX_STAT(fp
, aPAUSEMACCtrlFramesReceived
);
859 static void fun_get_802_3_stats(struct net_device
*netdev
,
860 struct ethtool_eth_mac_stats
*stats
)
862 const struct funeth_priv
*fp
= netdev_priv(netdev
);
864 if (!(fp
->port_caps
& FUN_PORT_CAP_STATS
))
867 stats
->FramesTransmittedOK
= TX_STAT(fp
, aFramesTransmittedOK
);
868 stats
->FramesReceivedOK
= RX_STAT(fp
, aFramesReceivedOK
);
869 stats
->FrameCheckSequenceErrors
= RX_STAT(fp
, aFrameCheckSequenceErrors
);
870 stats
->OctetsTransmittedOK
= TX_STAT(fp
, OctetsTransmittedOK
);
871 stats
->OctetsReceivedOK
= RX_STAT(fp
, OctetsReceivedOK
);
872 stats
->InRangeLengthErrors
= RX_STAT(fp
, aInRangeLengthErrors
);
873 stats
->FrameTooLongErrors
= RX_STAT(fp
, aFrameTooLongErrors
);
876 static void fun_get_802_3_ctrl_stats(struct net_device
*netdev
,
877 struct ethtool_eth_ctrl_stats
*stats
)
879 const struct funeth_priv
*fp
= netdev_priv(netdev
);
881 if (!(fp
->port_caps
& FUN_PORT_CAP_STATS
))
884 stats
->MACControlFramesTransmitted
= TX_STAT(fp
, MACControlFramesTransmitted
);
885 stats
->MACControlFramesReceived
= RX_STAT(fp
, MACControlFramesReceived
);
888 static void fun_get_rmon_stats(struct net_device
*netdev
,
889 struct ethtool_rmon_stats
*stats
,
890 const struct ethtool_rmon_hist_range
**ranges
)
892 static const struct ethtool_rmon_hist_range rmon_ranges
[] = {
903 const struct funeth_priv
*fp
= netdev_priv(netdev
);
905 if (!(fp
->port_caps
& FUN_PORT_CAP_STATS
))
908 stats
->undersize_pkts
= RX_STAT(fp
, etherStatsUndersizePkts
);
909 stats
->oversize_pkts
= RX_STAT(fp
, etherStatsOversizePkts
);
910 stats
->fragments
= RX_STAT(fp
, etherStatsFragments
);
911 stats
->jabbers
= RX_STAT(fp
, etherStatsJabbers
);
913 stats
->hist
[0] = RX_STAT(fp
, etherStatsPkts64Octets
);
914 stats
->hist
[1] = RX_STAT(fp
, etherStatsPkts65to127Octets
);
915 stats
->hist
[2] = RX_STAT(fp
, etherStatsPkts128to255Octets
);
916 stats
->hist
[3] = RX_STAT(fp
, etherStatsPkts256to511Octets
);
917 stats
->hist
[4] = RX_STAT(fp
, etherStatsPkts512to1023Octets
);
918 stats
->hist
[5] = RX_STAT(fp
, etherStatsPkts1024to1518Octets
);
919 stats
->hist
[6] = RX_STAT(fp
, etherStatsPkts1519toMaxOctets
);
921 stats
->hist_tx
[0] = TX_STAT(fp
, etherStatsPkts64Octets
);
922 stats
->hist_tx
[1] = TX_STAT(fp
, etherStatsPkts65to127Octets
);
923 stats
->hist_tx
[2] = TX_STAT(fp
, etherStatsPkts128to255Octets
);
924 stats
->hist_tx
[3] = TX_STAT(fp
, etherStatsPkts256to511Octets
);
925 stats
->hist_tx
[4] = TX_STAT(fp
, etherStatsPkts512to1023Octets
);
926 stats
->hist_tx
[5] = TX_STAT(fp
, etherStatsPkts1024to1518Octets
);
927 stats
->hist_tx
[6] = TX_STAT(fp
, etherStatsPkts1519toMaxOctets
);
929 *ranges
= rmon_ranges
;
932 static void fun_get_fec_stats(struct net_device
*netdev
,
933 struct ethtool_fec_stats
*stats
)
935 const struct funeth_priv
*fp
= netdev_priv(netdev
);
937 if (!(fp
->port_caps
& FUN_PORT_CAP_STATS
))
940 stats
->corrected_blocks
.total
= FEC_STAT(fp
, Correctable
);
941 stats
->uncorrectable_blocks
.total
= FEC_STAT(fp
, Uncorrectable
);
948 static int fun_get_rxnfc(struct net_device
*netdev
, struct ethtool_rxnfc
*cmd
,
952 case ETHTOOL_GRXRINGS
:
953 cmd
->data
= netdev
->real_num_rx_queues
;
961 static int fun_set_rxnfc(struct net_device
*netdev
, struct ethtool_rxnfc
*info
)
966 static u32
fun_get_rxfh_indir_size(struct net_device
*netdev
)
968 const struct funeth_priv
*fp
= netdev_priv(netdev
);
970 return fp
->indir_table_nentries
;
973 static u32
fun_get_rxfh_key_size(struct net_device
*netdev
)
975 const struct funeth_priv
*fp
= netdev_priv(netdev
);
977 return sizeof(fp
->rss_key
);
980 static int fun_get_rxfh(struct net_device
*netdev
,
981 struct ethtool_rxfh_param
*rxfh
)
983 const struct funeth_priv
*fp
= netdev_priv(netdev
);
989 memcpy(rxfh
->indir
, fp
->indir_table
,
990 sizeof(u32
) * fp
->indir_table_nentries
);
993 memcpy(rxfh
->key
, fp
->rss_key
, sizeof(fp
->rss_key
));
995 rxfh
->hfunc
= fp
->hash_algo
== FUN_ETH_RSS_ALG_TOEPLITZ
?
996 ETH_RSS_HASH_TOP
: ETH_RSS_HASH_CRC32
;
1001 static int fun_set_rxfh(struct net_device
*netdev
,
1002 struct ethtool_rxfh_param
*rxfh
,
1003 struct netlink_ext_ack
*extack
)
1005 struct funeth_priv
*fp
= netdev_priv(netdev
);
1006 const u32
*rss_indir
= rxfh
->indir
? rxfh
->indir
: fp
->indir_table
;
1007 const u8
*rss_key
= rxfh
->key
? rxfh
->key
: fp
->rss_key
;
1008 enum fun_eth_hash_alg algo
;
1013 if (rxfh
->hfunc
== ETH_RSS_HASH_NO_CHANGE
)
1014 algo
= fp
->hash_algo
;
1015 else if (rxfh
->hfunc
== ETH_RSS_HASH_CRC32
)
1016 algo
= FUN_ETH_RSS_ALG_CRC32
;
1017 else if (rxfh
->hfunc
== ETH_RSS_HASH_TOP
)
1018 algo
= FUN_ETH_RSS_ALG_TOEPLITZ
;
1022 /* If the port is enabled try to reconfigure RSS and keep the new
1023 * settings if successful. If it is down we update the RSS settings
1024 * and apply them at the next UP time.
1026 if (netif_running(netdev
)) {
1027 int rc
= fun_config_rss(netdev
, algo
, rss_key
, rss_indir
,
1028 FUN_ADMIN_SUBOP_MODIFY
);
1033 fp
->hash_algo
= algo
;
1035 memcpy(fp
->rss_key
, rxfh
->key
, sizeof(fp
->rss_key
));
1037 memcpy(fp
->indir_table
, rxfh
->indir
,
1038 sizeof(u32
) * fp
->indir_table_nentries
);
1042 static int fun_get_ts_info(struct net_device
*netdev
,
1043 struct kernel_ethtool_ts_info
*info
)
1045 info
->so_timestamping
= SOF_TIMESTAMPING_RX_HARDWARE
|
1046 SOF_TIMESTAMPING_TX_SOFTWARE
|
1047 SOF_TIMESTAMPING_RAW_HARDWARE
;
1048 info
->tx_types
= BIT(HWTSTAMP_TX_OFF
);
1049 info
->rx_filters
= BIT(HWTSTAMP_FILTER_NONE
) | BIT(HWTSTAMP_FILTER_ALL
);
1053 static unsigned int to_ethtool_fec(unsigned int fun_fec
)
1055 unsigned int fec
= 0;
1057 if (fun_fec
== FUN_PORT_FEC_NA
)
1058 fec
|= ETHTOOL_FEC_NONE
;
1059 if (fun_fec
& FUN_PORT_FEC_OFF
)
1060 fec
|= ETHTOOL_FEC_OFF
;
1061 if (fun_fec
& FUN_PORT_FEC_RS
)
1062 fec
|= ETHTOOL_FEC_RS
;
1063 if (fun_fec
& FUN_PORT_FEC_FC
)
1064 fec
|= ETHTOOL_FEC_BASER
;
1065 if (fun_fec
& FUN_PORT_FEC_AUTO
)
1066 fec
|= ETHTOOL_FEC_AUTO
;
1070 static int fun_get_fecparam(struct net_device
*netdev
,
1071 struct ethtool_fecparam
*fec
)
1073 struct funeth_priv
*fp
= netdev_priv(netdev
);
1077 rc
= fun_port_read_cmd(fp
, FUN_ADMIN_PORT_KEY_FEC
, &fec_data
);
1081 fec
->active_fec
= to_ethtool_fec(fec_data
& 0xff);
1082 fec
->fec
= to_ethtool_fec(fec_data
>> 8);
1086 static int fun_set_fecparam(struct net_device
*netdev
,
1087 struct ethtool_fecparam
*fec
)
1089 struct funeth_priv
*fp
= netdev_priv(netdev
);
1093 case ETHTOOL_FEC_AUTO
:
1094 fec_mode
= FUN_PORT_FEC_AUTO
;
1096 case ETHTOOL_FEC_OFF
:
1097 if (!(fp
->port_caps
& FUN_PORT_CAP_FEC_NONE
))
1099 fec_mode
= FUN_PORT_FEC_OFF
;
1101 case ETHTOOL_FEC_BASER
:
1102 if (!(fp
->port_caps
& FUN_PORT_CAP_FEC_FC
))
1104 fec_mode
= FUN_PORT_FEC_FC
;
1106 case ETHTOOL_FEC_RS
:
1107 if (!(fp
->port_caps
& FUN_PORT_CAP_FEC_RS
))
1109 fec_mode
= FUN_PORT_FEC_RS
;
1115 return fun_port_write_cmd(fp
, FUN_ADMIN_PORT_KEY_FEC
, fec_mode
);
1118 static int fun_get_port_module_page(struct net_device
*netdev
,
1119 const struct ethtool_module_eeprom
*req
,
1120 struct netlink_ext_ack
*extack
)
1123 struct fun_admin_port_req req
;
1124 struct fun_admin_port_xcvr_read_rsp rsp
;
1126 struct funeth_priv
*fp
= netdev_priv(netdev
);
1129 if (fp
->port_caps
& FUN_PORT_CAP_VPORT
) {
1130 NL_SET_ERR_MSG_MOD(extack
,
1131 "Specified port is virtual, only physical ports have modules");
1135 cmd
.req
.common
= FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_PORT
,
1137 cmd
.req
.u
.xcvr_read
=
1138 FUN_ADMIN_PORT_XCVR_READ_REQ_INIT(0, netdev
->dev_port
,
1139 req
->bank
, req
->page
,
1140 req
->offset
, req
->length
,
1142 rc
= fun_submit_admin_sync_cmd(fp
->fdev
, &cmd
.req
.common
, &cmd
.rsp
,
1143 sizeof(cmd
.rsp
), 0);
1147 memcpy(req
->data
, cmd
.rsp
.data
, req
->length
);
1151 static const struct ethtool_ops fun_ethtool_ops
= {
1152 .supported_coalesce_params
= ETHTOOL_COALESCE_USECS
|
1153 ETHTOOL_COALESCE_MAX_FRAMES
,
1154 .get_link_ksettings
= fun_get_link_ksettings
,
1155 .set_link_ksettings
= fun_set_link_ksettings
,
1156 .set_phys_id
= fun_set_phys_id
,
1157 .get_drvinfo
= fun_get_drvinfo
,
1158 .get_msglevel
= fun_get_msglevel
,
1159 .set_msglevel
= fun_set_msglevel
,
1160 .get_regs_len
= fun_get_regs_len
,
1161 .get_regs
= fun_get_regs
,
1162 .get_link
= ethtool_op_get_link
,
1163 .get_coalesce
= fun_get_coalesce
,
1164 .set_coalesce
= fun_set_coalesce
,
1165 .get_ts_info
= fun_get_ts_info
,
1166 .get_ringparam
= fun_get_ringparam
,
1167 .set_ringparam
= fun_set_ringparam
,
1168 .get_sset_count
= fun_get_sset_count
,
1169 .get_strings
= fun_get_strings
,
1170 .get_ethtool_stats
= fun_get_ethtool_stats
,
1171 .get_rxnfc
= fun_get_rxnfc
,
1172 .set_rxnfc
= fun_set_rxnfc
,
1173 .get_rxfh_indir_size
= fun_get_rxfh_indir_size
,
1174 .get_rxfh_key_size
= fun_get_rxfh_key_size
,
1175 .get_rxfh
= fun_get_rxfh
,
1176 .set_rxfh
= fun_set_rxfh
,
1177 .get_channels
= fun_get_channels
,
1178 .set_channels
= fun_set_channels
,
1179 .get_fecparam
= fun_get_fecparam
,
1180 .set_fecparam
= fun_set_fecparam
,
1181 .get_pauseparam
= fun_get_pauseparam
,
1182 .set_pauseparam
= fun_set_pauseparam
,
1183 .nway_reset
= fun_restart_an
,
1184 .get_pause_stats
= fun_get_pause_stats
,
1185 .get_fec_stats
= fun_get_fec_stats
,
1186 .get_eth_mac_stats
= fun_get_802_3_stats
,
1187 .get_eth_ctrl_stats
= fun_get_802_3_ctrl_stats
,
1188 .get_rmon_stats
= fun_get_rmon_stats
,
1189 .get_module_eeprom_by_page
= fun_get_port_module_page
,
1192 void fun_set_ethtool_ops(struct net_device
*netdev
)
1194 netdev
->ethtool_ops
= &fun_ethtool_ops
;