Skip to content

net: stmmac: tc956x: improve 10G traffic performance - #587

Draft
BigfootACA wants to merge 15 commits into
radxa:linux-7.0.11from
BigfootACA:linux-7.0.11-qps615-10g
Draft

net: stmmac: tc956x: improve 10G traffic performance #587
BigfootACA wants to merge 15 commits into
radxa:linux-7.0.11from
BigfootACA:linux-7.0.11-qps615-10g

Conversation

@BigfootACA

@BigfootACA BigfootACA commented Jul 31, 2026

Copy link
Copy Markdown

No description provided.

strongtz and others added 15 commits July 31, 2026 13:50
Signed-off-by: Xilin Wu <sophon@radxa.com>
There are some discussions about this upstream. Handle 2.5G links with
SGMII to make it work for now.

Signed-off-by: Xilin Wu <sophon@radxa.com>
The TC956x PCI driver currently uses fixed auxiliary device IDs for the GPIO
and XGMAC devices. This works for a single QPS615, but breaks when multiple
QPS615 chips are present because their auxiliary devices are registered with
the same names.

Allocate a per-chip instance ID and include it in the auxiliary device IDs.
Keep the two XGMAC IDs adjacent for each chip and use the same instance ID for
the optional GPIO auxiliary device.

This allows systems with multiple QPS615 chips to probe all TC956x auxiliary
devices without name collisions.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
The TC956x DWMAC driver uses the MAC index as the stmmac bus ID. This is
unique for a single QPS615, but not for systems with multiple QPS615 chips,
where each chip exposes MAC0 and MAC1.

Use the auxiliary device ID instead. The parent TC956x PCI driver assigns
globally unique auxiliary IDs, so this keeps the stmmac bus ID unique across
all QPS615 instances.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Add TC956x MAC programming for USXGMII links. Select the proper EMAC speed
selector for 10M/100M/1G/2.5G/5G/10G, report 10G as the maximum speed for
USXGMII, and keep in-band autonegotiation disabled for this PHY mode.

USXGMII also requires the common SerDes PLL, SGMII clock, reference clock
output, and per-MAC 125 MHz and 312.5 MHz clocks. Enable those clocks only
for USXGMII so the existing SGMII and 2500BASE-X paths are unchanged.

Configure the MAC before releasing reset so the XGMAC, PMA and XPCS come out
of reset with a valid USXGMII mode.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Tune the TC956x stmmac platform data for 10G traffic. Use the maximum DMA
descriptor ring sizes, expose a single RX/TX queue, and give that queue the
available FIFO budget instead of splitting FIFO space across queues.

Also disable AXI LPI and steer the shared MSIGEN interrupt away from the last
online CPU to reduce contention during throughput tests.

This is still a work-in-progress performance tuning patch and needs more
validation before submission.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Some QPS615 designs keep external PHYs in reset through GPIOs described under
the MDIO node. Deassert those reset GPIOs after the TC956x MAC, PMA and XPCS
are enabled, and honor an optional reset-deassert-us delay before handing the
device to stmmac.

This allows the external PHY to be reachable when stmmac registers the MDIO
bus and starts probing PHY devices.

This is still a work-in-progress reset sequencing patch and needs binding and
lifetime review before submission.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Currently, on Wangxun platforms, the XPCS is configured during the call
to xpcs_switch_interface_mode() and, if the need_reset flag is set, the
XPCS is reset and the configuration will be lost. This is harmless at
present because need_reset will never actually be set on these platforms.

Nevertheless having xpcs_switch_interface_mode() on the wrong side of
the reset is an obstacle for future changes where wiping out programmed
configuration with a reset could be harmful.

Reorder xpcs_pre_config() to allow the reset can happen before we
switch interface mode. To make this work we have to hoist the special
case logic for SGMII into the parent function.

Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
Currently the XPCS found on Toshiba TC9564 (a.k.a. Qualcomm QPS615)
is unable to operate at 2500base-X and slower with a PHY connected
using SGMII/2500base-X (in our case a Qualcomm QCA8081).

The problem arises because this XPCS supports 10Gbase-R. That means that
the reset value of SR_XS_PCS_CTRL2:PCS_TYPE_SEL (0) is valid and this
suppresses the modal switching based on bit 13 of SR_PMA_CTRL1 or
SR_XS_PCS_CTRL1.

A fix for this behaviour is already implemented by
txgbe_xpcs_switch_mode() as part of the quirks for WangXun devices.

Rather than introduce another quirk for TC956x let's attempt so solve
this generically by setting SR_XS_PCS_CTRL2:PCS_TYPE_SEL to a reserved
value when we detect the right we detect the right combination of phy
interface and XPCS feature support.

The generic strategy adopted requires the default value of PCS_TYPE_SEL
to be 0 on devices that support 10Gbase-R. Based on TC9564 documentation
and the logic already implemented for WangXun I believe this is likely
to be the case for currently supported XPCS devices. Sadly I don't have
access to generic XPCS docs to confirm. However I think the benefits
of avoiding a cargo culted quirk outweights the risk of regression.

Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
DW XPCS uses 10GBASE-R PCS as the base mode for USXGMII, but simply selecting
PHY_INTERFACE_MODE_USXGMII does not program the vendor USXGMII enable and baud
mode bits. This can leave the SerDes block-locked while no USXGMII frames are
decoded.

Add USXGMII-specific configuration to select the 10GBASE-R PCS type, enable
USXGMII, select the 10G USXGMII baud mode and apply the setting with a vendor
soft reset.

Also advertise the copper link modes carried over USXGMII so phylink can keep
100M/1G/2.5G/5G/10G full-duplex Base-T modes instead of masking them out during
validation.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Aeonsemi's AS22XXX is the second generation of the AS21xxx family and keeps
the generic PHY ID until firmware has been loaded. Add a dedicated driver
entry for it, load firmware from probe, and wait for the IPC channel to become
ready before continuing.

Handle link, autoneg and speed reporting using the AS22XXX vendor registers.
The new status path reads the AN state register for link completion and the
vendor speed register for 10M/100M/1G/2.5G/5G/10G resolution while reusing the
existing LED control helpers.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Disable ASPM L1 and its substates only when the PCI function node sets
`tc956x,aspm-quirk`, limiting the shared-clock workaround to affected
boards. Document the opt-in property in the TC956x binding while keeping
the AXI rate and lane-strap diagnostics unchanged.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
MSIGEN can steer each of its interrupt sources to any of 32 MSI vectors,
but only if the host grants more than one, so ask for all 32 instead of
one and hand the count to the auxiliary device.  The vector number
replaces the low five bits of the MSI data, so a smaller and less
strictly aligned allocation risks having those bits overwritten.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
Assign each DMA channel a dedicated MSI vector to distribute NAPI load.
Keep hardware TSO disabled because software segmentation is faster.
Increase the RX FIFO from 8KiB to a safe 32KiB.
Set clk_ref_rate so RX interrupt coalescing works correctly.
Fix RX queue-to-DMA mapping and keep one RX/TX queue without RSS.
Do not disable chip-wide SerDes clocks when one MAC stops.

Keep the implementation compatible with the v7.0 stmmac APIs:
fix_mac_speed() takes no phy_interface_t argument, so read the interface
back from the platform data, while default_an_inband lives in
plat->mdio_bus_data rather than plat.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
stmmac_select_queue() sends every skb with a TCP or UDP GSO type to TX
queue 0, on the grounds that queue 0 is the one queue guaranteed to be
TSO capable.  That is sound while the MAC does the segmentation, but
queue selection happens before the stack segments the skb, so on a
device with hardware TSO disabled it means *all* TCP traffic is funnelled
onto a single ring and any multi-queue configuration is pointless.

Only force queue 0 when hardware segmentation is actually in use.  With
hardware TSO off the stack splits the skb after this point anyway, so
there is nothing left to confine.

On TC956X, which caps hardware TSO at ~6.2 Gbit/s and so runs with it
disabled, this lets TX interrupts spread across CPUs and four TX queues
reach 9.41 Gbit/s instead of 2.5.

Signed-off-by: Junhao Xie <bigfoot@radxa.com>
@BigfootACA
BigfootACA marked this pull request as draft July 31, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants