diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-11-21 08:28:08 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-11-21 08:28:08 -0800 |
commit | fcc79e1714e8c2b8e216dc3149812edd37884eef (patch) | |
tree | 17a51d29db810b81412be040aaf380936b3261b4 /drivers/net/ethernet/sfc | |
parent | 6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7 (diff) | |
parent | dd7207838d38780b51e4690ee508ab2d5057e099 (diff) |
Merge tag 'net-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni:
"The most significant set of changes is the per netns RTNL. The new
behavior is disabled by default, regression risk should be contained.
Notably the new config knob PTP_1588_CLOCK_VMCLOCK will inherit its
default value from PTP_1588_CLOCK_KVM, as the first is intended to be
a more reliable replacement for the latter.
Core:
- Started a very large, in-progress, effort to make the RTNL lock
scope per network-namespace, thus reducing the lock contention
significantly in the containerized use-case, comprising:
- RCU-ified some relevant slices of the FIB control path
- introduce basic per netns locking helpers
- namespacified the IPv4 address hash table
- remove rtnl_register{,_module}() in favour of
rtnl_register_many()
- refactor rtnl_{new,del,set}link() moving as much validation as
possible out of RTNL lock
- convert all phonet doit() and dumpit() handlers to RCU
- convert IPv4 addresses manipulation to per-netns RTNL
- convert virtual interface creation to per-netns RTNL
the per-netns lock infrastructure is guarded by the
CONFIG_DEBUG_NET_SMALL_RTNL knob, disabled by default ad interim.
- Introduce NAPI suspension, to efficiently switching between busy
polling (NAPI processing suspended) and normal processing.
- Migrate the IPv4 routing input, output and control path from direct
ToS usage to DSCP macros. This is a work in progress to make ECN
handling consistent and reliable.
- Add drop reasons support to the IPv4 rotue input path, allowing
better introspection in case of packets drop.
- Make FIB seqnum lockless, dropping RTNL protection for read access.
- Make inet{,v6} addresses hashing less predicable.
- Allow providing timestamp OPT_ID via cmsg, to correlate TX packets
and timestamps
Things we sprinkled into general kernel code:
- Add small file operations for debugfs, to reduce the struct ops
size.
- Refactoring and optimization for the implementation of page_frag
API, This is a preparatory work to consolidate the page_frag
implementation.
Netfilter:
- Optimize set element transactions to reduce memory consumption
- Extended netlink error reporting for attribute parser failure.
- Make legacy xtables configs user selectable, giving users the
option to configure iptables without enabling any other config.
- Address a lot of false-positive RCU issues, pointed by recent CI
improvements.
BPF:
- Put xsk sockets on a struct diet and add various cleanups. Overall,
this helps to bump performance by 12% for some workloads.
- Extend BPF selftests to increase coverage of XDP features in
combination with BPF cpumap.
- Optimize and homogenize bpf_csum_diff helper for all archs and also
add a batch of new BPF selftests for it.
- Extend netkit with an option to delegate skb->{mark,priority}
scrubbing to its BPF program.
- Make the bpf_get_netns_cookie() helper available also to tc(x) BPF
programs.
Protocols:
- Introduces 4-tuple hash for connected udp sockets, speeding-up
significantly connected sockets lookup.
- Add a fastpath for some TCP timers that usually expires after
close, the socket lock contention.
- Add inbound and outbound xfrm state caches to speed up state
lookups.
- Avoid sending MPTCP advertisements on stale subflows, reducing
risks on loosing them.
- Make neighbours table flushing more scalable, maintaining per
device neigh lists.
Driver API:
- Introduce a unified interface to configure transmission H/W
shaping, and expose it to user-space via generic-netlink.
- Add support for per-NAPI config via netlink. This makes napi
configuration persistent across queues removal and re-creation.
Requires driver updates, currently supported drivers are:
nVidia/Mellanox mlx4 and mlx5, Broadcom brcm and Intel ice.
- Add ethtool support for writing SFP / PHY firmware blocks.
- Track RSS context allocation from ethtool core.
- Implement support for mirroring to DSA CPU port, via TC mirror
offload.
- Consolidate FDB updates notification, to avoid duplicates on
device-specific entries.
- Expose DPLL clock quality level to the user-space.
- Support master-slave PHY config via device tree.
Tests and tooling:
- forwarding: introduce deferred commands, to simplify the cleanup
phase
Drivers:
- Updated several drivers - Amazon vNic, Google vNic, Microsoft vNic,
Intel e1000e and Broadcom Tigon3 - to use netdev-genl to link the
IRQs and queues to NAPI IDs, allowing busy polling and better
introspection.
- Ethernet high-speed NICs:
- nVidia/Mellanox:
- mlx5:
- a large refactor to implement support for cross E-Switch
scheduling
- refactor H/W conter management to let it scale better
- H/W GRO cleanups
- Intel (100G, ice)::
- add support for ethtool reset
- implement support for per TX queue H/W shaping
- AMD/Solarflare:
- implement per device queue stats support
- Broadcom (bnxt):
- improve wildcard l4proto on IPv4/IPv6 ntuple rules
- Marvell Octeon:
- Add representor support for each Resource Virtualization Unit
(RVU) device.
- Hisilicon:
- add support for the BMC Gigabit Ethernet
- IBM (EMAC):
- driver cleanup and modernization
- Cisco (VIC):
- raise the queues number limit to 256
- Ethernet virtual:
- Google vNIC:
- implement page pool support
- macsec:
- inherit lower device's features and TSO limits when
offloading
- virtio_net:
- enable premapped mode by default
- support for XDP socket(AF_XDP) zerocopy TX
- wireguard:
- set the TSO max size to be GSO_MAX_SIZE, to aggregate larger
packets.
- Ethernet NICs embedded and virtual:
- Broadcom ASP:
- enable software timestamping
- Freescale:
- add enetc4 PF driver
- MediaTek: Airoha SoC:
- implement BQL support
- RealTek r8169:
- enable TSO by default on r8168/r8125
- implement extended ethtool stats
- Renesas AVB:
- enable TX checksum offload
- Synopsys (stmmac):
- support header splitting for vlan tagged packets
- move common code for DWMAC4 and DWXGMAC into a separate FPE
module.
- add dwmac driver support for T-HEAD TH1520 SoC
- Synopsys (xpcs):
- driver refactor and cleanup
- TI:
- icssg_prueth: add VLAN offload support
- Xilinx emaclite:
- add clock support
- Ethernet switches:
- Microchip:
- implement support for the lan969x Ethernet switch family
- add LAN9646 switch support to KSZ DSA driver
- Ethernet PHYs:
- Marvel: 88q2x: enable auto negotiation
- Microchip: add support for LAN865X Rev B1 and LAN867X Rev C1/C2
- PTP:
- Add support for the Amazon virtual clock device
- Add PtP driver for s390 clocks
- WiFi:
- mac80211
- EHT 1024 aggregation size for transmissions
- new operation to indicate that a new interface is to be added
- support radio separation of multi-band devices
- move wireless extension spy implementation to libiw
- Broadcom:
- brcmfmac: optional LPO clock support
- Microchip:
- add support for Atmel WILC3000
- Qualcomm (ath12k):
- firmware coredump collection support
- add debugfs support for a multitude of statistics
- Qualcomm (ath5k):
- Arcadyan ARV45XX AR2417 & Gigaset SX76[23] AR241[34]A support
- Realtek:
- rtw88: 8821au and 8812au USB adapters support
- rtw89: add thermal protection
- rtw89: fine tune BT-coexsitence to improve user experience
- rtw89: firmware secure boot for WiFi 6 chip
- Bluetooth
- add Qualcomm WCN785x support for ids Foxconn 0xe0fc/0xe0f3 and
0x13d3:0x3623
- add Realtek RTL8852BE support for id Foxconn 0xe123
- add MediaTek MT7920 support for wireless module ids
- btintel_pcie: add handshake between driver and firmware
- btintel_pcie: add recovery mechanism
- btnxpuart: add GPIO support to power save feature"
* tag 'net-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1475 commits)
mm: page_frag: fix a compile error when kernel is not compiled
Documentation: tipc: fix formatting issue in tipc.rst
selftests: nic_performance: Add selftest for performance of NIC driver
selftests: nic_link_layer: Add selftest case for speed and duplex states
selftests: nic_link_layer: Add link layer selftest for NIC driver
bnxt_en: Add FW trace coredump segments to the coredump
bnxt_en: Add a new ethtool -W dump flag
bnxt_en: Add 2 parameters to bnxt_fill_coredump_seg_hdr()
bnxt_en: Add functions to copy host context memory
bnxt_en: Do not free FW log context memory
bnxt_en: Manage the FW trace context memory
bnxt_en: Allocate backing store memory for FW trace logs
bnxt_en: Add a 'force' parameter to bnxt_free_ctx_mem()
bnxt_en: Refactor bnxt_free_ctx_mem()
bnxt_en: Add mem_valid bit to struct bnxt_ctx_mem_type
bnxt_en: Update firmware interface spec to 1.10.3.85
selftests/bpf: Add some tests with sockmap SK_PASS
bpf: fix recursive lock when verdict program return SK_PASS
wireguard: device: support big tcp GSO
wireguard: selftests: load nf_conntrack if not present
...
Diffstat (limited to 'drivers/net/ethernet/sfc')
44 files changed, 295 insertions, 323 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index de131fc5fa0b..452009ed7a43 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -1751,7 +1751,7 @@ static void efx_ef10_get_stat_mask(struct efx_nic *efx, unsigned long *mask) #endif } -static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 *names) +static size_t efx_ef10_describe_stats(struct efx_nic *efx, u8 **names) { DECLARE_BITMAP(mask, EF10_STAT_COUNT); diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.c b/drivers/net/ethernet/sfc/ef100_ethtool.c index 5c2551369812..6c3b74000d3b 100644 --- a/drivers/net/ethernet/sfc/ef100_ethtool.c +++ b/drivers/net/ethernet/sfc/ef100_ethtool.c @@ -59,6 +59,7 @@ const struct ethtool_ops ef100_ethtool_ops = { .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size, .rxfh_per_ctx_key = true, + .cap_rss_rxnfc_adds = true, .rxfh_priv_size = sizeof(struct efx_rss_context_priv), .get_rxfh = efx_ethtool_get_rxfh, .set_rxfh = efx_ethtool_set_rxfh, diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 6da06931187d..62e674d6ff60 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -583,7 +583,7 @@ static const struct efx_hw_stat_desc ef100_stat_desc[EF100_STAT_COUNT] = { EFX_GENERIC_SW_STAT(rx_noskb_drops), }; -static size_t ef100_describe_stats(struct efx_nic *efx, u8 *names) +static size_t ef100_describe_stats(struct efx_nic *efx, u8 **names) { DECLARE_BITMAP(mask, EF100_STAT_COUNT) = {}; diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c index 83d9db71d7d7..44dc75feb162 100644 --- a/drivers/net/ethernet/sfc/ef100_rx.c +++ b/drivers/net/ethernet/sfc/ef100_rx.c @@ -134,6 +134,9 @@ void __ef100_rx_packet(struct efx_channel *channel) goto free_rx_buffer; } + ++rx_queue->rx_packets; + rx_queue->rx_bytes += rx_buf->len; + efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh, csum); goto out; @@ -149,8 +152,6 @@ static void ef100_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index) struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; - ++rx_queue->rx_packets; - netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x\n", efx_rx_queue_index(rx_queue), index); diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 36b3b57e2055..650136dfc642 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -22,6 +22,7 @@ #include "net_driver.h" #include <net/gre.h> #include <net/udp_tunnel.h> +#include <net/netdev_queues.h> #include "efx.h" #include "efx_common.h" #include "efx_channels.h" @@ -417,14 +418,6 @@ unsigned int efx_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs) return usecs * 1000 / efx->timer_quantum_ns; } -unsigned int efx_ticks_to_usecs(struct efx_nic *efx, unsigned int ticks) -{ - /* We must round up when converting ticks to microseconds - * because we round down when converting the other way. - */ - return DIV_ROUND_UP(ticks * efx->timer_quantum_ns, 1000); -} - /* Set interrupt moderation parameters */ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, unsigned int rx_usecs, bool rx_adaptive, @@ -626,6 +619,113 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_bpf = efx_xdp }; +static void efx_get_queue_stats_rx(struct net_device *net_dev, int idx, + struct netdev_queue_stats_rx *stats) +{ + struct efx_nic *efx = efx_netdev_priv(net_dev); + struct efx_rx_queue *rx_queue; + struct efx_channel *channel; + + channel = efx_get_channel(efx, idx); + rx_queue = efx_channel_get_rx_queue(channel); + /* Count only packets since last time datapath was started */ + stats->packets = rx_queue->rx_packets - rx_queue->old_rx_packets; + stats->bytes = rx_queue->rx_bytes - rx_queue->old_rx_bytes; + stats->hw_drops = efx_get_queue_stat_rx_hw_drops(channel) - + channel->old_n_rx_hw_drops; + stats->hw_drop_overruns = channel->n_rx_nodesc_trunc - + channel->old_n_rx_hw_drop_overruns; +} + +static void efx_get_queue_stats_tx(struct net_device *net_dev, int idx, + struct netdev_queue_stats_tx *stats) +{ + struct efx_nic *efx = efx_netdev_priv(net_dev); + struct efx_tx_queue *tx_queue; + struct efx_channel *channel; + + channel = efx_get_tx_channel(efx, idx); + stats->packets = 0; + stats->bytes = 0; + stats->hw_gso_packets = 0; + stats->hw_gso_wire_packets = 0; + efx_for_each_channel_tx_queue(tx_queue, channel) { + stats->packets += tx_queue->complete_packets - + tx_queue->old_complete_packets; + stats->bytes += tx_queue->complete_bytes - + tx_queue->old_complete_bytes; + /* Note that, unlike stats->packets and stats->bytes, + * these count TXes enqueued, rather than completed, + * which may not be what users expect. + */ + stats->hw_gso_packets += tx_queue->tso_bursts - + tx_queue->old_tso_bursts; + stats->hw_gso_wire_packets += tx_queue->tso_packets - + tx_queue->old_tso_packets; + } +} + +static void efx_get_base_stats(struct net_device *net_dev, + struct netdev_queue_stats_rx *rx, + struct netdev_queue_stats_tx *tx) +{ + struct efx_nic *efx = efx_netdev_priv(net_dev); + struct efx_tx_queue *tx_queue; + struct efx_rx_queue *rx_queue; + struct efx_channel *channel; + + rx->packets = 0; + rx->bytes = 0; + rx->hw_drops = 0; + rx->hw_drop_overruns = 0; + tx->packets = 0; + tx->bytes = 0; + tx->hw_gso_packets = 0; + tx->hw_gso_wire_packets = 0; + + /* Count all packets on non-core queues, and packets before last + * datapath start on core queues. + */ + efx_for_each_channel(channel, efx) { + rx_queue = efx_channel_get_rx_queue(channel); + if (channel->channel >= net_dev->real_num_rx_queues) { + rx->packets += rx_queue->rx_packets; + rx->bytes += rx_queue->rx_bytes; + rx->hw_drops += efx_get_queue_stat_rx_hw_drops(channel); + rx->hw_drop_overruns += channel->n_rx_nodesc_trunc; + } else { + rx->packets += rx_queue->old_rx_packets; + rx->bytes += rx_queue->old_rx_bytes; + rx->hw_drops += channel->old_n_rx_hw_drops; + rx->hw_drop_overruns += channel->old_n_rx_hw_drop_overruns; + } + efx_for_each_channel_tx_queue(tx_queue, channel) { + if (channel->channel < efx->tx_channel_offset || + channel->channel >= efx->tx_channel_offset + + net_dev->real_num_tx_queues) { + tx->packets += tx_queue->complete_packets; + tx->bytes += tx_queue->complete_bytes; + tx->hw_gso_packets += tx_queue->tso_bursts; + tx->hw_gso_wire_packets += tx_queue->tso_packets; + } else { + tx->packets += tx_queue->old_complete_packets; + tx->bytes += tx_queue->old_complete_bytes; + tx->hw_gso_packets += tx_queue->old_tso_bursts; + tx->hw_gso_wire_packets += tx_queue->old_tso_packets; + } + /* Include XDP TX in device-wide stats */ + tx->packets += tx_queue->complete_xdp_packets; + tx->bytes += tx_queue->complete_xdp_bytes; + } + } +} + +static const struct netdev_stat_ops efx_stat_ops = { + .get_queue_stats_rx = efx_get_queue_stats_rx, + .get_queue_stats_tx = efx_get_queue_stats_tx, + .get_base_stats = efx_get_base_stats, +}; + static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog) { struct bpf_prog *old_prog; @@ -716,6 +816,7 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->watchdog_timeo = 5 * HZ; net_dev->irq = efx->pci_dev->irq; net_dev->netdev_ops = &efx_netdev_ops; + net_dev->stat_ops = &efx_stat_ops; if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) net_dev->priv_flags |= IFF_UNICAST_FLT; net_dev->ethtool_ops = &efx_ethtool_ops; diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 7a6cab883d66..45e191686625 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -168,7 +168,6 @@ extern const struct ethtool_ops efx_ethtool_ops; /* Global */ unsigned int efx_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs); -unsigned int efx_ticks_to_usecs(struct efx_nic *efx, unsigned int ticks); int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, unsigned int rx_usecs, bool rx_adaptive, bool rx_may_override_tx); diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c index f1723a6fb082..06b4f52713ef 100644 --- a/drivers/net/ethernet/sfc/efx_channels.c +++ b/drivers/net/ethernet/sfc/efx_channels.c @@ -1100,6 +1100,10 @@ void efx_start_channels(struct efx_nic *efx) atomic_inc(&efx->active_queues); } + /* reset per-queue stats */ + channel->old_n_rx_hw_drops = efx_get_queue_stat_rx_hw_drops(channel); + channel->old_n_rx_hw_drop_overruns = channel->n_rx_nodesc_trunc; + efx_for_each_channel_rx_queue(rx_queue, channel) { efx_init_rx_queue(rx_queue); atomic_inc(&efx->active_queues); @@ -1209,6 +1213,8 @@ static int efx_process_channel(struct efx_channel *channel, int budget) tx_queue->pkts_compl, tx_queue->bytes_compl); } + tx_queue->complete_packets += tx_queue->pkts_compl; + tx_queue->complete_bytes += tx_queue->bytes_compl; } /* Receive any packets we queued up */ diff --git a/drivers/net/ethernet/sfc/efx_channels.h b/drivers/net/ethernet/sfc/efx_channels.h index 46b702648721..547cf94014a3 100644 --- a/drivers/net/ethernet/sfc/efx_channels.h +++ b/drivers/net/ethernet/sfc/efx_channels.h @@ -43,6 +43,13 @@ struct efx_channel *efx_copy_channel(const struct efx_channel *old_channel); void efx_start_channels(struct efx_nic *efx); void efx_stop_channels(struct efx_nic *efx); +static inline u64 efx_get_queue_stat_rx_hw_drops(struct efx_channel *channel) +{ + return channel->n_rx_eth_crc_err + channel->n_rx_frm_trunc + + channel->n_rx_overlength + channel->n_rx_nodesc_trunc + + channel->n_rx_mport_bad; +} + void efx_init_napi_channel(struct efx_channel *channel); void efx_init_napi(struct efx_nic *efx); void efx_fini_napi_channel(struct efx_channel *channel); diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c index 13cf647051af..c88ec3e24836 100644 --- a/drivers/net/ethernet/sfc/efx_common.c +++ b/drivers/net/ethernet/sfc/efx_common.c @@ -635,22 +635,6 @@ int __efx_reconfigure_port(struct efx_nic *efx) return rc; } -/* Reinitialise the MAC to pick up new PHY settings, even if the port is - * disabled. - */ -int efx_reconfigure_port(struct efx_nic *efx) -{ - int rc; - - EFX_ASSERT_RESET_SERIALISED(efx); - - mutex_lock(&efx->mac_lock); - rc = __efx_reconfigure_port(efx); - mutex_unlock(&efx->mac_lock); - - return rc; -} - /************************************************************************** * * Device reset and suspend diff --git a/drivers/net/ethernet/sfc/efx_common.h b/drivers/net/ethernet/sfc/efx_common.h index 2c54dac3e662..19a8ca530969 100644 --- a/drivers/net/ethernet/sfc/efx_common.h +++ b/drivers/net/ethernet/sfc/efx_common.h @@ -40,7 +40,6 @@ void efx_destroy_reset_workqueue(void); void efx_start_monitor(struct efx_nic *efx); int __efx_reconfigure_port(struct efx_nic *efx); -int efx_reconfigure_port(struct efx_nic *efx); #define EFX_ASSERT_RESET_SERIALISED(efx) \ do { \ diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index bb1930818beb..83d715544f7f 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -263,6 +263,7 @@ const struct ethtool_ops efx_ethtool_ops = { .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size, .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size, .rxfh_per_ctx_key = true, + .cap_rss_rxnfc_adds = true, .rxfh_priv_size = sizeof(struct efx_rss_context_priv), .get_rxfh = efx_ethtool_get_rxfh, .set_rxfh = efx_ethtool_set_rxfh, diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c index 6ded44b86052..2d734496733f 100644 --- a/drivers/net/ethernet/sfc/ethtool_common.c +++ b/drivers/net/ethernet/sfc/ethtool_common.c @@ -75,7 +75,6 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = { EFX_ETHTOOL_UINT_TXQ_STAT(pio_packets), EFX_ETHTOOL_UINT_TXQ_STAT(cb_packets), EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), - EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_inner_ip_hdr_chksum_err), @@ -83,8 +82,8 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = { EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_outer_ip_hdr_chksum_err), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_outer_tcp_udp_chksum_err), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_eth_crc_err), - EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc), + EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_overlength), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_events), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_packets), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_drops), @@ -396,7 +395,7 @@ int efx_ethtool_fill_self_tests(struct efx_nic *efx, return n; } -static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) +static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 **strings) { size_t n_stats = 0; struct efx_channel *channel; @@ -404,24 +403,22 @@ static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) efx_for_each_channel(channel, efx) { if (efx_channel_has_tx_queues(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "tx-%u.tx_packets", - channel->tx_queue[0].queue / - EFX_MAX_TXQ_PER_CHANNEL); + if (!strings) + continue; - strings += ETH_GSTRING_LEN; - } + ethtool_sprintf(strings, "tx-%u.tx_packets", + channel->tx_queue[0].queue / + EFX_MAX_TXQ_PER_CHANNEL); } } efx_for_each_channel(channel, efx) { if (efx_channel_has_rx_queue(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "rx-%d.rx_packets", channel->channel); - strings += ETH_GSTRING_LEN; - } + if (!strings) + continue; + + ethtool_sprintf(strings, "rx-%d.rx_packets", + channel->channel); } } if (efx->xdp_tx_queue_count && efx->xdp_tx_queues) { @@ -429,11 +426,11 @@ static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) for (xdp = 0; xdp < efx->xdp_tx_queue_count; xdp++) { n_stats++; - if (strings) { - snprintf(strings, ETH_GSTRING_LEN, - "tx-xdp-cpu-%hu.tx_packets", xdp); - strings += ETH_GSTRING_LEN; - } + if (!strings) + continue; + + ethtool_sprintf(strings, "tx-xdp-cpu-%hu.tx_packets", + xdp); } } @@ -465,15 +462,11 @@ void efx_ethtool_get_strings(struct net_device *net_dev, switch (string_set) { case ETH_SS_STATS: - strings += (efx->type->describe_stats(efx, strings) * - ETH_GSTRING_LEN); + efx->type->describe_stats(efx, &strings); for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) - strscpy(strings + i * ETH_GSTRING_LEN, - efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); - strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; - strings += (efx_describe_per_queue_stats(efx, strings) * - ETH_GSTRING_LEN); - efx_ptp_describe_stats(efx, strings); + ethtool_puts(&strings, efx_sw_stat_desc[i].name); + efx_describe_per_queue_stats(efx, &strings); + efx_ptp_describe_stats(efx, &strings); break; case ETH_SS_TEST: efx_ethtool_fill_self_tests(efx, NULL, strings, NULL); diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c index 8925745f1c17..b07f7e4e2877 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -1886,14 +1886,6 @@ unsigned int ef4_usecs_to_ticks(struct ef4_nic *efx, unsigned int usecs) return usecs * 1000 / efx->timer_quantum_ns; } -unsigned int ef4_ticks_to_usecs(struct ef4_nic *efx, unsigned int ticks) -{ - /* We must round up when converting ticks to microseconds - * because we round down when converting the other way. - */ - return DIV_ROUND_UP(ticks * efx->timer_quantum_ns, 1000); -} - /* Set interrupt moderation parameters */ int ef4_init_irq_moderation(struct ef4_nic *efx, unsigned int tx_usecs, unsigned int rx_usecs, bool rx_adaptive, diff --git a/drivers/net/ethernet/sfc/falcon/efx.h b/drivers/net/ethernet/sfc/falcon/efx.h index d3b4646545fa..52508f2c8cb2 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.h +++ b/drivers/net/ethernet/sfc/falcon/efx.h @@ -198,7 +198,6 @@ int ef4_try_recovery(struct ef4_nic *efx); /* Global */ void ef4_schedule_reset(struct ef4_nic *efx, enum reset_type type); unsigned int ef4_usecs_to_ticks(struct ef4_nic *efx, unsigned int usecs); -unsigned int ef4_ticks_to_usecs(struct ef4_nic *efx, unsigned int ticks); int ef4_init_irq_moderation(struct ef4_nic *efx, unsigned int tx_usecs, unsigned int rx_usecs, bool rx_adaptive, bool rx_may_override_tx); diff --git a/drivers/net/ethernet/sfc/falcon/ethtool.c b/drivers/net/ethernet/sfc/falcon/ethtool.c index f4db683b80f7..04766448a545 100644 --- a/drivers/net/ethernet/sfc/falcon/ethtool.c +++ b/drivers/net/ethernet/sfc/falcon/ethtool.c @@ -353,7 +353,7 @@ static int ef4_ethtool_fill_self_tests(struct ef4_nic *efx, return n; } -static size_t ef4_describe_per_queue_stats(struct ef4_nic *efx, u8 *strings) +static size_t ef4_describe_per_queue_stats(struct ef4_nic *efx, u8 **strings) { size_t n_stats = 0; struct ef4_channel *channel; @@ -361,24 +361,22 @@ static size_t ef4_describe_per_queue_stats(struct ef4_nic *efx, u8 *strings) ef4_for_each_channel(channel, efx) { if (ef4_channel_has_tx_queues(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "tx-%u.tx_packets", - channel->tx_queue[0].queue / - EF4_TXQ_TYPES); + if (!strings) + continue; - strings += ETH_GSTRING_LEN; - } + ethtool_sprintf(strings, "tx-%u.tx_packets", + channel->tx_queue[0].queue / + EF4_TXQ_TYPES); } } ef4_for_each_channel(channel, efx) { if (ef4_channel_has_rx_queue(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "rx-%d.rx_packets", channel->channel); - strings += ETH_GSTRING_LEN; - } + if (!strings) + continue; + + ethtool_sprintf(strings, "rx-%d.rx_packets", + channel->channel); } } return n_stats; @@ -409,14 +407,10 @@ static void ef4_ethtool_get_strings(struct net_device *net_dev, switch (string_set) { case ETH_SS_STATS: - strings += (efx->type->describe_stats(efx, strings) * - ETH_GSTRING_LEN); + efx->type->describe_stats(efx, &strings); for (i = 0; i < EF4_ETHTOOL_SW_STAT_COUNT; i++) - strscpy(strings + i * ETH_GSTRING_LEN, - ef4_sw_stat_desc[i].name, ETH_GSTRING_LEN); - strings += EF4_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; - strings += (ef4_describe_per_queue_stats(efx, strings) * - ETH_GSTRING_LEN); + ethtool_puts(&strings, ef4_sw_stat_desc[i].name); + ef4_describe_per_queue_stats(efx, &strings); break; case ETH_SS_TEST: ef4_ethtool_fill_self_tests(efx, NULL, strings, NULL); diff --git a/drivers/net/ethernet/sfc/falcon/falcon.c b/drivers/net/ethernet/sfc/falcon/falcon.c index 36114ce88034..4af56333ea49 100644 --- a/drivers/net/ethernet/sfc/falcon/falcon.c +++ b/drivers/net/ethernet/sfc/falcon/falcon.c @@ -2564,7 +2564,7 @@ static void falcon_remove_nic(struct ef4_nic *efx) efx->nic_data = NULL; } -static size_t falcon_describe_nic_stats(struct ef4_nic *efx, u8 *names) +static size_t falcon_describe_nic_stats(struct ef4_nic *efx, u8 **names) { return ef4_nic_describe_stats(falcon_stat_desc, FALCON_STAT_COUNT, falcon_stat_mask, names); diff --git a/drivers/net/ethernet/sfc/falcon/farch.c b/drivers/net/ethernet/sfc/falcon/farch.c index c64623c2e80c..01017c41338e 100644 --- a/drivers/net/ethernet/sfc/falcon/farch.c +++ b/drivers/net/ethernet/sfc/falcon/farch.c @@ -1631,28 +1631,6 @@ void ef4_farch_rx_push_indir_table(struct ef4_nic *efx) } } -/* Looks at available SRAM resources and works out how many queues we - * can support, and where things like descriptor caches should live. - * - * SRAM is split up as follows: - * 0 buftbl entries for channels - * efx->vf_buftbl_base buftbl entries for SR-IOV - * efx->rx_dc_base RX descriptor caches - * efx->tx_dc_base TX descriptor caches - */ -void ef4_farch_dimension_resources(struct ef4_nic *efx, unsigned sram_lim_qw) -{ - unsigned vi_count; - - /* Account for the buffer table entries backing the datapath channels - * and the descriptor caches for those channels. - */ - vi_count = max(efx->n_channels, efx->n_tx_channels * EF4_TXQ_TYPES); - - efx->tx_dc_base = sram_lim_qw - vi_count * TX_DC_ENTRIES; - efx->rx_dc_base = efx->tx_dc_base - vi_count * RX_DC_ENTRIES; -} - u32 ef4_farch_fpga_ver(struct ef4_nic *efx) { ef4_oword_t altera_build; diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h index a2c7139f2b32..7ab0db44720d 100644 --- a/drivers/net/ethernet/sfc/falcon/net_driver.h +++ b/drivers/net/ethernet/sfc/falcon/net_driver.h @@ -1057,7 +1057,7 @@ struct ef4_nic_type { void (*finish_flush)(struct ef4_nic *efx); void (*prepare_flr)(struct ef4_nic *efx); void (*finish_flr)(struct ef4_nic *efx); - size_t (*describe_stats)(struct ef4_nic *efx, u8 *names); + size_t (*describe_stats)(struct ef4_nic *efx, u8 **names); size_t (*update_stats)(struct ef4_nic *efx, u64 *full_stats, struct rtnl_link_stats64 *core_stats); void (*start_stats)(struct ef4_nic *efx); diff --git a/drivers/net/ethernet/sfc/falcon/nic.c b/drivers/net/ethernet/sfc/falcon/nic.c index 78c851b5a56f..a6304686bc90 100644 --- a/drivers/net/ethernet/sfc/falcon/nic.c +++ b/drivers/net/ethernet/sfc/falcon/nic.c @@ -444,18 +444,15 @@ void ef4_nic_get_regs(struct ef4_nic *efx, void *buf) * bits in the first @count bits of @mask for which a name is defined. */ size_t ef4_nic_describe_stats(const struct ef4_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names) + const unsigned long *mask, u8 **names) { size_t visible = 0; size_t index; for_each_set_bit(index, mask, count) { if (desc[index].name) { - if (names) { - strscpy(names, desc[index].name, - ETH_GSTRING_LEN); - names += ETH_GSTRING_LEN; - } + if (names) + ethtool_puts(names, desc[index].name); ++visible; } } @@ -511,14 +508,3 @@ void ef4_nic_update_stats(const struct ef4_hw_stat_desc *desc, size_t count, } } } - -void ef4_nic_fix_nodesc_drop_stat(struct ef4_nic *efx, u64 *rx_nodesc_drops) -{ - /* if down, or this is the first update after coming up */ - if (!(efx->net_dev->flags & IFF_UP) || !efx->rx_nodesc_drops_prev_state) - efx->rx_nodesc_drops_while_down += - *rx_nodesc_drops - efx->rx_nodesc_drops_total; - efx->rx_nodesc_drops_total = *rx_nodesc_drops; - efx->rx_nodesc_drops_prev_state = !!(efx->net_dev->flags & IFF_UP); - *rx_nodesc_drops -= efx->rx_nodesc_drops_while_down; -} diff --git a/drivers/net/ethernet/sfc/falcon/nic.h b/drivers/net/ethernet/sfc/falcon/nic.h index ada6e036fd97..bc6ef937d0fe 100644 --- a/drivers/net/ethernet/sfc/falcon/nic.h +++ b/drivers/net/ethernet/sfc/falcon/nic.h @@ -477,7 +477,6 @@ void ef4_farch_finish_flr(struct ef4_nic *efx); void falcon_start_nic_stats(struct ef4_nic *efx); void falcon_stop_nic_stats(struct ef4_nic *efx); int falcon_reset_xaui(struct ef4_nic *efx); -void ef4_farch_dimension_resources(struct ef4_nic *efx, unsigned sram_lim_qw); void ef4_farch_init_common(struct ef4_nic *efx); void ef4_farch_rx_push_indir_table(struct ef4_nic *efx); @@ -498,14 +497,10 @@ size_t ef4_nic_get_regs_len(struct ef4_nic *efx); void ef4_nic_get_regs(struct ef4_nic *efx, void *buf); size_t ef4_nic_describe_stats(const struct ef4_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names); + const unsigned long *mask, u8 **names); void ef4_nic_update_stats(const struct ef4_hw_stat_desc *desc, size_t count, const unsigned long *mask, u64 *stats, const void *dma_buf, bool accumulate); -void ef4_nic_fix_nodesc_drop_stat(struct ef4_nic *efx, u64 *stat); - -#define EF4_MAX_FLUSH_TIME 5000 - void ef4_farch_generate_event(struct ef4_nic *efx, unsigned int evq, ef4_qword_t *event); diff --git a/drivers/net/ethernet/sfc/falcon/tx.c b/drivers/net/ethernet/sfc/falcon/tx.c index b9369483758c..e6e80b039ca2 100644 --- a/drivers/net/ethernet/sfc/falcon/tx.c +++ b/drivers/net/ethernet/sfc/falcon/tx.c @@ -40,14 +40,6 @@ static inline u8 *ef4_tx_get_copy_buffer(struct ef4_tx_queue *tx_queue, return (u8 *)page_buf->addr + offset; } -u8 *ef4_tx_get_copy_buffer_limited(struct ef4_tx_queue *tx_queue, - struct ef4_tx_buffer *buffer, size_t len) -{ - if (len > EF4_TX_CB_SIZE) - return NULL; - return ef4_tx_get_copy_buffer(tx_queue, buffer); -} - static void ef4_dequeue_buffer(struct ef4_tx_queue *tx_queue, struct ef4_tx_buffer *buffer, unsigned int *pkts_compl, diff --git a/drivers/net/ethernet/sfc/falcon/tx.h b/drivers/net/ethernet/sfc/falcon/tx.h index 2a88c59cbbbe..868ed8a861ab 100644 --- a/drivers/net/ethernet/sfc/falcon/tx.h +++ b/drivers/net/ethernet/sfc/falcon/tx.h @@ -15,9 +15,6 @@ unsigned int ef4_tx_limit_len(struct ef4_tx_queue *tx_queue, dma_addr_t dma_addr, unsigned int len); -u8 *ef4_tx_get_copy_buffer_limited(struct ef4_tx_queue *tx_queue, - struct ef4_tx_buffer *buffer, size_t len); - int ef4_enqueue_skb_tso(struct ef4_tx_queue *tx_queue, struct sk_buff *skb, bool *data_mapped); diff --git a/drivers/net/ethernet/sfc/mae.c b/drivers/net/ethernet/sfc/mae.c index 10709d828a63..50f097487b14 100644 --- a/drivers/net/ethernet/sfc/mae.c +++ b/drivers/net/ethernet/sfc/mae.c @@ -76,17 +76,6 @@ void efx_mae_mport_uplink(struct efx_nic *efx __always_unused, u32 *out) *out = EFX_DWORD_VAL(mport); } -void efx_mae_mport_vf(struct efx_nic *efx __always_unused, u32 vf_id, u32 *out) -{ - efx_dword_t mport; - - EFX_POPULATE_DWORD_3(mport, - MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_FUNC, - MAE_MPORT_SELECTOR_FUNC_PF_ID, MAE_MPORT_SELECTOR_FUNC_PF_ID_CALLER, - MAE_MPORT_SELECTOR_FUNC_VF_ID, vf_id); - *out = EFX_DWORD_VAL(mport); -} - /* Constructs an mport selector from an mport ID, because they're not the same */ void efx_mae_mport_mport(struct efx_nic *efx __always_unused, u32 mport_id, u32 *out) { diff --git a/drivers/net/ethernet/sfc/mae.h b/drivers/net/ethernet/sfc/mae.h index 8df30bc4f3ba..db79912c86d8 100644 --- a/drivers/net/ethernet/sfc/mae.h +++ b/drivers/net/ethernet/sfc/mae.h @@ -23,7 +23,6 @@ int efx_mae_free_mport(struct efx_nic *efx, u32 id); void efx_mae_mport_wire(struct efx_nic *efx, u32 *out); void efx_mae_mport_uplink(struct efx_nic *efx, u32 *out); -void efx_mae_mport_vf(struct efx_nic *efx, u32 vf_id, u32 *out); void efx_mae_mport_mport(struct efx_nic *efx, u32 mport_id, u32 *out); int efx_mae_lookup_mport(struct efx_nic *efx, u32 selector, u32 *id); diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 76578502226e..d461b1a6ce81 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -1051,15 +1051,6 @@ efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, cookie, false); } -int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd, - const efx_dword_t *inbuf, size_t inlen, - size_t outlen, efx_mcdi_async_completer *complete, - unsigned long cookie) -{ - return _efx_mcdi_rpc_async(efx, cmd, inbuf, inlen, outlen, complete, - cookie, true); -} - int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual) @@ -1068,14 +1059,6 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, outlen_actual, false, NULL, NULL); } -int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd, size_t inlen, - efx_dword_t *outbuf, size_t outlen, - size_t *outlen_actual) -{ - return _efx_mcdi_rpc_finish(efx, cmd, inlen, outbuf, outlen, - outlen_actual, true, NULL, NULL); -} - void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd, size_t inlen, efx_dword_t *outbuf, size_t outlen, int rc) @@ -1982,33 +1965,6 @@ efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, int *id_out) } -int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out) -{ - MCDI_DECLARE_BUF(outbuf, MC_CMD_WOL_FILTER_GET_OUT_LEN); - size_t outlen; - int rc; - - rc = efx_mcdi_rpc(efx, MC_CMD_WOL_FILTER_GET, NULL, 0, - outbuf, sizeof(outbuf), &outlen); - if (rc) - goto fail; - - if (outlen < MC_CMD_WOL_FILTER_GET_OUT_LEN) { - rc = -EIO; - goto fail; - } - - *id_out = (int)MCDI_DWORD(outbuf, WOL_FILTER_GET_OUT_FILTER_ID); - - return 0; - -fail: - *id_out = -1; - netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); - return rc; -} - - int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id) { MCDI_DECLARE_BUF(inbuf, MC_CMD_WOL_FILTER_REMOVE_IN_LEN); @@ -2021,38 +1977,6 @@ int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id) return rc; } -int efx_mcdi_flush_rxqs(struct efx_nic *efx) -{ - struct efx_channel *channel; - struct efx_rx_queue *rx_queue; - MCDI_DECLARE_BUF(inbuf, - MC_CMD_FLUSH_RX_QUEUES_IN_LEN(EFX_MAX_CHANNELS)); - int rc, count; - - BUILD_BUG_ON(EFX_MAX_CHANNELS > - MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM); - - count = 0; - efx_for_each_channel(channel, efx) { - efx_for_each_channel_rx_queue(rx_queue, channel) { - if (rx_queue->flush_pending) { - rx_queue->flush_pending = false; - atomic_dec(&efx->rxq_flush_pending); - MCDI_SET_ARRAY_DWORD( - inbuf, FLUSH_RX_QUEUES_IN_QID_OFST, - count, efx_rx_queue_index(rx_queue)); - count++; - } - } - } - - rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, inbuf, - MC_CMD_FLUSH_RX_QUEUES_IN_LEN(count), NULL, 0, NULL); - WARN_ON(rc < 0); - - return rc; -} - int efx_mcdi_wol_filter_reset(struct efx_nic *efx) { int rc; diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index ea612c619874..cdb17d7c147f 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -155,9 +155,6 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, efx_dword_t *outbuf, size_t outlen, size_t *outlen_actual); -int efx_mcdi_rpc_finish_quiet(struct efx_nic *efx, unsigned cmd, - size_t inlen, efx_dword_t *outbuf, - size_t outlen, size_t *outlen_actual); typedef void efx_mcdi_async_completer(struct efx_nic *efx, unsigned long cookie, int rc, @@ -167,11 +164,6 @@ int efx_mcdi_rpc_async(struct efx_nic *efx, unsigned int cmd, const efx_dword_t *inbuf, size_t inlen, size_t outlen, efx_mcdi_async_completer *complete, unsigned long cookie); -int efx_mcdi_rpc_async_quiet(struct efx_nic *efx, unsigned int cmd, - const efx_dword_t *inbuf, size_t inlen, - size_t outlen, - efx_mcdi_async_completer *complete, - unsigned long cookie); void efx_mcdi_display_error(struct efx_nic *efx, unsigned cmd, size_t inlen, efx_dword_t *outbuf, @@ -410,10 +402,8 @@ int efx_mcdi_handle_assertion(struct efx_nic *efx); int efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, int *id_out); -int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); int efx_mcdi_wol_filter_reset(struct efx_nic *efx); -int efx_mcdi_flush_rxqs(struct efx_nic *efx); void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev); void efx_mcdi_mac_start_stats(struct efx_nic *efx); void efx_mcdi_mac_stop_stats(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b85c51cbe7f9..620ba6ef3514 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -193,6 +193,12 @@ struct efx_tx_buffer { * @initialised: Has hardware queue been initialised? * @timestamping: Is timestamping enabled for this channel? * @xdp_tx: Is this an XDP tx queue? + * @old_complete_packets: Value of @complete_packets as of last + * efx_init_tx_queue() + * @old_complete_bytes: Value of @complete_bytes as of last + * efx_init_tx_queue() + * @old_tso_bursts: Value of @tso_bursts as of last efx_init_tx_queue() + * @old_tso_packets: Value of @tso_packets as of last efx_init_tx_queue() * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. * @old_write_count: The value of @write_count when last checked. @@ -202,6 +208,20 @@ struct efx_tx_buffer { * avoid cache-line ping-pong between the xmit path and the * completion path. * @merge_events: Number of TX merged completion events + * @bytes_compl: Number of bytes completed during this NAPI poll + * (efx_process_channel()). For BQL. + * @pkts_compl: Number of packets completed during this NAPI poll. + * @complete_packets: Number of packets completed since this struct was + * created. Only counts SKB packets, not XDP TX (it accumulates + * the same values that are reported to BQL). + * @complete_bytes: Number of bytes completed since this struct was + * created. For TSO, counts the superframe size, not the sizes of + * generated frames on the wire (i.e. the headers are only counted + * once) + * @complete_xdp_packets: Number of XDP TX packets completed since this + * struct was created. + * @complete_xdp_bytes: Number of XDP TX bytes completed since this + * struct was created. * @completed_timestamp_major: Top part of the most recent tx timestamp. * @completed_timestamp_minor: Low part of the most recent tx timestamp. * @insert_count: Current insert pointer @@ -232,6 +252,7 @@ struct efx_tx_buffer { * @xmit_pending: Are any packets waiting to be pushed to the NIC * @cb_packets: Number of times the TX copybreak feature has been used * @notify_count: Count of notified descriptors to the NIC + * @tx_packets: Number of packets sent since this struct was created * @empty_read_count: If the completion path has seen the queue as empty * and the transmission path has not yet checked this, the value of * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0. @@ -255,6 +276,10 @@ struct efx_tx_queue { bool initialised; bool timestamping; bool xdp_tx; + unsigned long old_complete_packets; + unsigned long old_complete_bytes; + unsigned int old_tso_bursts; + unsigned int old_tso_packets; /* Members used mainly on the completion path */ unsigned int read_count ____cacheline_aligned_in_smp; @@ -262,6 +287,10 @@ struct efx_tx_queue { unsigned int merge_events; unsigned int bytes_compl; unsigned int pkts_compl; + unsigned long complete_packets; + unsigned long complete_bytes; + unsigned long complete_xdp_packets; + unsigned long complete_xdp_bytes; u32 completed_timestamp_major; u32 completed_timestamp_minor; @@ -370,6 +399,10 @@ struct efx_rx_page_state { * @recycle_count: RX buffer recycle counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). * @grant_work: workitem used to grant credits to the MAE if @grant_credits + * @rx_packets: Number of packets received since this struct was created + * @rx_bytes: Number of bytes received since this struct was created + * @old_rx_packets: Value of @rx_packets as of last efx_init_rx_queue() + * @old_rx_bytes: Value of @rx_bytes as of last efx_init_rx_queue() * @xdp_rxq_info: XDP specific RX queue information. * @xdp_rxq_info_valid: Is xdp_rxq_info valid data?. */ @@ -406,6 +439,9 @@ struct efx_rx_queue { struct work_struct grant_work; /* Statistics to supplement MAC stats */ unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long old_rx_packets; + unsigned long old_rx_bytes; struct xdp_rxq_info xdp_rxq_info; bool xdp_rxq_info_valid; }; @@ -451,10 +487,8 @@ enum efx_sync_events_state { * @filter_work: Work item for efx_filter_rfs_expire() * @rps_flow_id: Flow IDs of filters allocated for accelerated RFS, * indexed by filter ID - * @n_rx_tobe_disc: Count of RX_TOBE_DISC errors * @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors * @n_rx_tcp_udp_chksum_err: Count of RX TCP and UDP checksum errors - * @n_rx_mcast_mismatch: Count of unmatched multicast frames * @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun @@ -468,6 +502,10 @@ enum efx_sync_events_state { * @n_rx_xdp_redirect: Count of RX packets redirected to a different NIC by XDP * @n_rx_mport_bad: Count of RX packets dropped because their ingress mport was * not recognised + * @old_n_rx_hw_drops: Count of all RX packets dropped for any reason as of last + * efx_start_channels() + * @old_n_rx_hw_drop_overruns: Value of @n_rx_nodesc_trunc as of last + * efx_start_channels() * @rx_pkt_n_frags: Number of fragments in next packet to be delivered by * __efx_rx_packet(), or zero if there is none * @rx_pkt_index: Ring index of first buffer for next packet to be delivered @@ -511,7 +549,6 @@ struct efx_channel { u32 *rps_flow_id; #endif - unsigned int n_rx_tobe_disc; unsigned int n_rx_ip_hdr_chksum_err; unsigned int n_rx_tcp_udp_chksum_err; unsigned int n_rx_outer_ip_hdr_chksum_err; @@ -519,7 +556,6 @@ struct efx_channel { unsigned int n_rx_inner_ip_hdr_chksum_err; unsigned int n_rx_inner_tcp_udp_chksum_err; unsigned int n_rx_eth_crc_err; - unsigned int n_rx_mcast_mismatch; unsigned int n_rx_frm_trunc; unsigned int n_rx_overlength; unsigned int n_skbuff_leaks; @@ -532,6 +568,9 @@ struct efx_channel { unsigned int n_rx_xdp_redirect; unsigned int n_rx_mport_bad; + unsigned int old_n_rx_hw_drops; + unsigned int old_n_rx_hw_drop_overruns; + unsigned int rx_pkt_n_frags; unsigned int rx_pkt_index; @@ -1369,7 +1408,7 @@ struct efx_nic_type { int (*fini_dmaq)(struct efx_nic *efx); void (*prepare_flr)(struct efx_nic *efx); void (*finish_flr)(struct efx_nic *efx); - size_t (*describe_stats)(struct efx_nic *efx, u8 *names); + size_t (*describe_stats)(struct efx_nic *efx, u8 **names); size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats, struct rtnl_link_stats64 *core_stats); size_t (*update_stats_atomic)(struct efx_nic *efx, u64 *full_stats, diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index a33ed473cc8a..80aa5e9c732a 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -299,18 +299,15 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf) * bits in the first @count bits of @mask for which a name is defined. */ size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names) + const unsigned long *mask, u8 **names) { size_t visible = 0; size_t index; for_each_set_bit(index, mask, count) { if (desc[index].name) { - if (names) { - strscpy(names, desc[index].name, - ETH_GSTRING_LEN); - names += ETH_GSTRING_LEN; - } + if (names) + ethtool_puts(names, desc[index].name); ++visible; } } diff --git a/drivers/net/ethernet/sfc/nic_common.h b/drivers/net/ethernet/sfc/nic_common.h index 7ec4ac7b7ff5..821d91efda19 100644 --- a/drivers/net/ethernet/sfc/nic_common.h +++ b/drivers/net/ethernet/sfc/nic_common.h @@ -241,7 +241,7 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf); #define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) size_t efx_nic_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names); + const unsigned long *mask, u8 **names); int efx_nic_copy_stats(struct efx_nic *efx, __le64 *dest); void efx_nic_update_stats(const struct efx_hw_stat_desc *desc, size_t count, const unsigned long *mask, u64 *stats, diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index aaacdcfa54ae..4c7222bf26be 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -399,7 +399,7 @@ static const unsigned long efx_ptp_stat_mask[] = { [0 ... BITS_TO_LONGS(PTP_STAT_COUNT) - 1] = ~0UL, }; -size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 *strings) +size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 **strings) { if (!efx->ptp_data) return 0; @@ -1800,11 +1800,6 @@ int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) return NETDEV_TX_OK; } -int efx_ptp_get_mode(struct efx_nic *efx) -{ - return efx->ptp_data->mode; -} - int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, unsigned int new_mode) { diff --git a/drivers/net/ethernet/sfc/ptp.h b/drivers/net/ethernet/sfc/ptp.h index 6946203499ef..cb9b077921e8 100644 --- a/drivers/net/ethernet/sfc/ptp.h +++ b/drivers/net/ethernet/sfc/ptp.h @@ -26,12 +26,11 @@ int efx_ptp_get_ts_config(struct efx_nic *efx, void efx_ptp_get_ts_info(struct efx_nic *efx, struct kernel_ethtool_ts_info *ts_info); bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); -int efx_ptp_get_mode(struct efx_nic *efx); int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, unsigned int new_mode); int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); -size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 *strings); +size_t efx_ptp_describe_stats(struct efx_nic *efx, u8 **strings); size_t efx_ptp_update_stats(struct efx_nic *efx, u64 *stats); void efx_time_sync_event(struct efx_channel *channel, efx_qword_t *ev); void __efx_rx_skb_attach_timestamp(struct efx_channel *channel, diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index f77a2d3ef37e..ffca82207e47 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -125,8 +125,6 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_rx_buffer *rx_buf; - rx_queue->rx_packets++; - rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->flags |= flags; @@ -394,6 +392,9 @@ void __efx_rx_packet(struct efx_channel *channel) goto out; } + rx_queue->rx_packets++; + rx_queue->rx_bytes += rx_buf->len; + if (!efx_do_xdp(efx, channel, rx_buf, &eh)) goto out; diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c index 0b7dc75c40f9..ab358fe13e1d 100644 --- a/drivers/net/ethernet/sfc/rx_common.c +++ b/drivers/net/ethernet/sfc/rx_common.c @@ -241,6 +241,9 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue) rx_queue->page_recycle_failed = 0; rx_queue->page_recycle_full = 0; + rx_queue->old_rx_packets = rx_queue->rx_packets; + rx_queue->old_rx_bytes = rx_queue->rx_bytes; + /* Initialise limit fields */ max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; max_trigger = diff --git a/drivers/net/ethernet/sfc/siena/ethtool_common.c b/drivers/net/ethernet/sfc/siena/ethtool_common.c index 075fef64de68..eeee676fdca7 100644 --- a/drivers/net/ethernet/sfc/siena/ethtool_common.c +++ b/drivers/net/ethernet/sfc/siena/ethtool_common.c @@ -395,7 +395,7 @@ fail: test->flags |= ETH_TEST_FL_FAILED; } -static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) +static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 **strings) { size_t n_stats = 0; struct efx_channel *channel; @@ -403,24 +403,22 @@ static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) efx_for_each_channel(channel, efx) { if (efx_channel_has_tx_queues(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "tx-%u.tx_packets", - channel->tx_queue[0].queue / - EFX_MAX_TXQ_PER_CHANNEL); + if (!strings) + continue; - strings += ETH_GSTRING_LEN; - } + ethtool_sprintf(strings, "tx-%u.tx_packets", + channel->tx_queue[0].queue / + EFX_MAX_TXQ_PER_CHANNEL); } } efx_for_each_channel(channel, efx) { if (efx_channel_has_rx_queue(channel)) { n_stats++; - if (strings != NULL) { - snprintf(strings, ETH_GSTRING_LEN, - "rx-%d.rx_packets", channel->channel); - strings += ETH_GSTRING_LEN; - } + if (!strings) + continue; + + ethtool_sprintf(strings, "rx-%d.rx_packets", + channel->channel); } } if (efx->xdp_tx_queue_count && efx->xdp_tx_queues) { @@ -428,11 +426,11 @@ static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) for (xdp = 0; xdp < efx->xdp_tx_queue_count; xdp++) { n_stats++; - if (strings) { - snprintf(strings, ETH_GSTRING_LEN, - "tx-xdp-cpu-%hu.tx_packets", xdp); - strings += ETH_GSTRING_LEN; - } + if (!strings) + continue; + + ethtool_sprintf(strings, "tx-xdp-cpu-%hu.tx_packets", + xdp); } } @@ -464,15 +462,11 @@ void efx_siena_ethtool_get_strings(struct net_device *net_dev, switch (string_set) { case ETH_SS_STATS: - strings += (efx->type->describe_stats(efx, strings) * - ETH_GSTRING_LEN); + efx->type->describe_stats(efx, &strings); for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) - strscpy(strings + i * ETH_GSTRING_LEN, - efx_sw_stat_desc[i].name, ETH_GSTRING_LEN); - strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN; - strings += (efx_describe_per_queue_stats(efx, strings) * - ETH_GSTRING_LEN); - efx_siena_ptp_describe_stats(efx, strings); + ethtool_puts(&strings, efx_sw_stat_desc[i].name); + efx_describe_per_queue_stats(efx, &strings); + efx_siena_ptp_describe_stats(efx, &strings); break; case ETH_SS_TEST: efx_ethtool_fill_self_tests(efx, NULL, strings, NULL); diff --git a/drivers/net/ethernet/sfc/siena/net_driver.h b/drivers/net/ethernet/sfc/siena/net_driver.h index 3fa7c652ae9b..9785eff10607 100644 --- a/drivers/net/ethernet/sfc/siena/net_driver.h +++ b/drivers/net/ethernet/sfc/siena/net_driver.h @@ -1307,7 +1307,7 @@ struct efx_nic_type { void (*finish_flush)(struct efx_nic *efx); void (*prepare_flr)(struct efx_nic *efx); void (*finish_flr)(struct efx_nic *efx); - size_t (*describe_stats)(struct efx_nic *efx, u8 *names); + size_t (*describe_stats)(struct efx_nic *efx, u8 **names); size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats, struct rtnl_link_stats64 *core_stats); size_t (*update_stats_atomic)(struct efx_nic *efx, u64 *full_stats, diff --git a/drivers/net/ethernet/sfc/siena/nic.c b/drivers/net/ethernet/sfc/siena/nic.c index 0ea0433a6230..32fce70085e3 100644 --- a/drivers/net/ethernet/sfc/siena/nic.c +++ b/drivers/net/ethernet/sfc/siena/nic.c @@ -449,20 +449,20 @@ void efx_siena_get_regs(struct efx_nic *efx, void *buf) * Returns the number of visible statistics, i.e. the number of set * bits in the first @count bits of @mask for which a name is defined. */ -size_t efx_siena_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names) +size_t efx_siena_describe_stats(const struct efx_hw_stat_desc *desc, + size_t count, const unsigned long *mask, + u8 **names) { size_t visible = 0; size_t index; for_each_set_bit(index, mask, count) { if (desc[index].name) { - if (names) { - strscpy(names, desc[index].name, - ETH_GSTRING_LEN); - names += ETH_GSTRING_LEN; - } ++visible; + if (!names) + continue; + + ethtool_puts(names, desc[index].name); } } diff --git a/drivers/net/ethernet/sfc/siena/nic_common.h b/drivers/net/ethernet/sfc/siena/nic_common.h index 3af0405eeaa4..b7fbe198008d 100644 --- a/drivers/net/ethernet/sfc/siena/nic_common.h +++ b/drivers/net/ethernet/sfc/siena/nic_common.h @@ -239,8 +239,9 @@ void efx_siena_get_regs(struct efx_nic *efx, void *buf); #define EFX_MC_STATS_GENERATION_INVALID ((__force __le64)(-1)) -size_t efx_siena_describe_stats(const struct efx_hw_stat_desc *desc, size_t count, - const unsigned long *mask, u8 *names); +size_t efx_siena_describe_stats(const struct efx_hw_stat_desc *desc, + size_t count, const unsigned long *mask, + u8 **names); void efx_siena_update_stats(const struct efx_hw_stat_desc *desc, size_t count, const unsigned long *mask, u64 *stats, const void *dma_buf, bool accumulate); diff --git a/drivers/net/ethernet/sfc/siena/ptp.c b/drivers/net/ethernet/sfc/siena/ptp.c index 85005196b4c5..062c77c92077 100644 --- a/drivers/net/ethernet/sfc/siena/ptp.c +++ b/drivers/net/ethernet/sfc/siena/ptp.c @@ -393,7 +393,7 @@ static const unsigned long efx_ptp_stat_mask[] = { [0 ... BITS_TO_LONGS(PTP_STAT_COUNT) - 1] = ~0UL, }; -size_t efx_siena_ptp_describe_stats(struct efx_nic *efx, u8 *strings) +size_t efx_siena_ptp_describe_stats(struct efx_nic *efx, u8 **strings) { if (!efx->ptp_data) return 0; diff --git a/drivers/net/ethernet/sfc/siena/ptp.h b/drivers/net/ethernet/sfc/siena/ptp.h index b6133e7c5608..54840036ab67 100644 --- a/drivers/net/ethernet/sfc/siena/ptp.h +++ b/drivers/net/ethernet/sfc/siena/ptp.h @@ -28,7 +28,7 @@ int efx_siena_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, unsigned int new_mode); int efx_siena_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); void efx_siena_ptp_event(struct efx_nic *efx, efx_qword_t *ev); -size_t efx_siena_ptp_describe_stats(struct efx_nic *efx, u8 *strings); +size_t efx_siena_ptp_describe_stats(struct efx_nic *efx, u8 **strings); size_t efx_siena_ptp_update_stats(struct efx_nic *efx, u64 *stats); void efx_siena_time_sync_event(struct efx_channel *channel, efx_qword_t *ev); void __efx_siena_rx_skb_attach_timestamp(struct efx_channel *channel, diff --git a/drivers/net/ethernet/sfc/siena/siena.c b/drivers/net/ethernet/sfc/siena/siena.c index ca33dc08e555..49f0c8a1a90a 100644 --- a/drivers/net/ethernet/sfc/siena/siena.c +++ b/drivers/net/ethernet/sfc/siena/siena.c @@ -545,7 +545,7 @@ static const unsigned long siena_stat_mask[] = { [0 ... BITS_TO_LONGS(SIENA_STAT_COUNT) - 1] = ~0UL, }; -static size_t siena_describe_nic_stats(struct efx_nic *efx, u8 *names) +static size_t siena_describe_nic_stats(struct efx_nic *efx, u8 **names) { return efx_siena_describe_stats(siena_stat_desc, SIENA_STAT_COUNT, siena_stat_mask, names); diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index fe2d476028e7..4dff19b6ef17 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -49,14 +49,6 @@ static inline u8 *efx_tx_get_copy_buffer(struct efx_tx_queue *tx_queue, return (u8 *)page_buf->addr + offset; } -u8 *efx_tx_get_copy_buffer_limited(struct efx_tx_queue *tx_queue, - struct efx_tx_buffer *buffer, size_t len) -{ - if (len > EFX_TX_CB_SIZE) - return NULL; - return efx_tx_get_copy_buffer(tx_queue, buffer); -} - static void efx_tx_maybe_stop_queue(struct efx_tx_queue *txq1) { /* We need to consider all queues that the net core sees as one */ @@ -553,6 +545,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, void efx_xmit_done_single(struct efx_tx_queue *tx_queue) { + unsigned int xdp_pkts_compl = 0, xdp_bytes_compl = 0; unsigned int pkts_compl = 0, bytes_compl = 0; unsigned int efv_pkts_compl = 0; unsigned int read_ptr; @@ -577,7 +570,8 @@ void efx_xmit_done_single(struct efx_tx_queue *tx_queue) if (buffer->flags & EFX_TX_BUF_SKB) finished = true; efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl, - &efv_pkts_compl); + &efv_pkts_compl, &xdp_pkts_compl, + &xdp_bytes_compl); ++tx_queue->read_count; read_ptr = tx_queue->read_count & tx_queue->ptr_mask; @@ -585,6 +579,8 @@ void efx_xmit_done_single(struct efx_tx_queue *tx_queue) tx_queue->pkts_compl += pkts_compl; tx_queue->bytes_compl += bytes_compl; + tx_queue->complete_xdp_packets += xdp_pkts_compl; + tx_queue->complete_xdp_bytes += xdp_bytes_compl; EFX_WARN_ON_PARANOID(pkts_compl + efv_pkts_compl != 1); diff --git a/drivers/net/ethernet/sfc/tx.h b/drivers/net/ethernet/sfc/tx.h index f2c4d2f89919..f882749af8c3 100644 --- a/drivers/net/ethernet/sfc/tx.h +++ b/drivers/net/ethernet/sfc/tx.h @@ -15,9 +15,6 @@ unsigned int efx_tx_limit_len(struct efx_tx_queue *tx_queue, dma_addr_t dma_addr, unsigned int len); -u8 *efx_tx_get_copy_buffer_limited(struct efx_tx_queue *tx_queue, - struct efx_tx_buffer *buffer, size_t len); - /* What TXQ type will satisfy the checksum offloads required for this skb? */ static inline unsigned int efx_tx_csum_type_skb(struct sk_buff *skb) { diff --git a/drivers/net/ethernet/sfc/tx_common.c b/drivers/net/ethernet/sfc/tx_common.c index 2adb132b2f7e..a22a0d634ffc 100644 --- a/drivers/net/ethernet/sfc/tx_common.c +++ b/drivers/net/ethernet/sfc/tx_common.c @@ -86,6 +86,11 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) tx_queue->completed_timestamp_major = 0; tx_queue->completed_timestamp_minor = 0; + tx_queue->old_complete_packets = tx_queue->complete_packets; + tx_queue->old_complete_bytes = tx_queue->complete_bytes; + tx_queue->old_tso_bursts = tx_queue->tso_bursts; + tx_queue->old_tso_packets = tx_queue->tso_packets; + tx_queue->xdp_tx = efx_channel_is_xdp_tx(tx_queue->channel); tx_queue->tso_version = 0; @@ -109,12 +114,14 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) /* Free any buffers left in the ring */ while (tx_queue->read_count != tx_queue->write_count) { + unsigned int xdp_pkts_compl = 0, xdp_bytes_compl = 0; unsigned int pkts_compl = 0, bytes_compl = 0; unsigned int efv_pkts_compl = 0; buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask]; efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl, - &efv_pkts_compl); + &efv_pkts_compl, &xdp_pkts_compl, + &xdp_bytes_compl); ++tx_queue->read_count; } @@ -150,7 +157,9 @@ void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct efx_tx_buffer *buffer, unsigned int *pkts_compl, unsigned int *bytes_compl, - unsigned int *efv_pkts_compl) + unsigned int *efv_pkts_compl, + unsigned int *xdp_pkts, + unsigned int *xdp_bytes) { if (buffer->unmap_len) { struct device *dma_dev = &tx_queue->efx->pci_dev->dev; @@ -195,6 +204,10 @@ void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, tx_queue->queue, tx_queue->read_count); } else if (buffer->flags & EFX_TX_BUF_XDP) { xdp_return_frame_rx_napi(buffer->xdpf); + if (xdp_pkts) + (*xdp_pkts)++; + if (xdp_bytes) + (*xdp_bytes) += buffer->xdpf->len; } buffer->len = 0; @@ -210,7 +223,9 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, unsigned int index, unsigned int *pkts_compl, unsigned int *bytes_compl, - unsigned int *efv_pkts_compl) + unsigned int *efv_pkts_compl, + unsigned int *xdp_pkts, + unsigned int *xdp_bytes) { struct efx_nic *efx = tx_queue->efx; unsigned int stop_index, read_ptr; @@ -230,7 +245,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, } efx_dequeue_buffer(tx_queue, buffer, pkts_compl, bytes_compl, - efv_pkts_compl); + efv_pkts_compl, xdp_pkts, xdp_bytes); ++tx_queue->read_count; read_ptr = tx_queue->read_count & tx_queue->ptr_mask; @@ -253,15 +268,18 @@ void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue) int efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) { unsigned int fill_level, pkts_compl = 0, bytes_compl = 0; + unsigned int xdp_pkts_compl = 0, xdp_bytes_compl = 0; unsigned int efv_pkts_compl = 0; struct efx_nic *efx = tx_queue->efx; EFX_WARN_ON_ONCE_PARANOID(index > tx_queue->ptr_mask); efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl, - &efv_pkts_compl); + &efv_pkts_compl, &xdp_pkts_compl, &xdp_bytes_compl); tx_queue->pkts_compl += pkts_compl; tx_queue->bytes_compl += bytes_compl; + tx_queue->complete_xdp_packets += xdp_pkts_compl; + tx_queue->complete_xdp_bytes += xdp_bytes_compl; if (pkts_compl + efv_pkts_compl > 1) ++tx_queue->merge_events; @@ -290,6 +308,8 @@ int efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) void efx_enqueue_unwind(struct efx_tx_queue *tx_queue, unsigned int insert_count) { + unsigned int xdp_bytes_compl = 0; + unsigned int xdp_pkts_compl = 0; unsigned int efv_pkts_compl = 0; struct efx_tx_buffer *buffer; unsigned int bytes_compl = 0; @@ -300,7 +320,8 @@ void efx_enqueue_unwind(struct efx_tx_queue *tx_queue, --tx_queue->insert_count; buffer = __efx_tx_queue_get_insert_buffer(tx_queue); efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl, - &efv_pkts_compl); + &efv_pkts_compl, &xdp_pkts_compl, + &xdp_bytes_compl); } } diff --git a/drivers/net/ethernet/sfc/tx_common.h b/drivers/net/ethernet/sfc/tx_common.h index 1e9f42938aac..039eefafba23 100644 --- a/drivers/net/ethernet/sfc/tx_common.h +++ b/drivers/net/ethernet/sfc/tx_common.h @@ -20,7 +20,9 @@ void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct efx_tx_buffer *buffer, unsigned int *pkts_compl, unsigned int *bytes_compl, - unsigned int *efv_pkts_compl); + unsigned int *efv_pkts_compl, + unsigned int *xdp_pkts, + unsigned int *xdp_bytes); static inline bool efx_tx_buffer_in_use(struct efx_tx_buffer *buffer) { |