The DesignWare EMAC IP in the ADSP-SC846 has a hardware-automatic flow control (EHFC) feature controlled by the EMAC_RQ0_OPMODE.EHFC bit. When enabled, the MAC monitors the Rx FIFO fill-level and automatically transmits IEEE 802.3 pause frames when the level crosses the RFA (Receive Flow Activate) threshold.
From the HRM (Section 28, "Transmit Flow Control"):
┌──────┬─────┬────┬──────────────────────────────────────────────────────────────────────────────────────────────┐
│ EHFC │ TFE │ DM │ Description │
├──────┼─────┼────┼──────────────────────────────────────────────────────────────────────────────────────────────┤
│ 1 │ 1 │ 1 │ MAC sends pause frames on software trigger AND when Rx queue level crosses the RFA threshold │
└──────┴─────┴────┴──────────────────────────────────────────────────────────────────────────────────────────────┘
When the ARM core stalls and stops servicing the EMAC Rx FIFO, the FIFO fills up, triggering EHFC to continuously emit pause frames with maximum pause time (0xFFFF). A non-compliant switch forwards these frames to all devices, disrupting the entire network segment.
In drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c, function dwmac4_dma_rx_chan_op_mode():
if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
mtl_rx_op |= MTL_OP_MODE_EHFC; /* BIT(7) */
...
}
This unconditionally enables EHFC whenever the Rx FIFO is ≥ 4 KiB, which is the case for the ADSP-SC846.
Proposed solution:
- include/linux/stmmac.h — New flag STMMAC_FLAG_DISABLE_HW_FLOW_CTRL (BIT(14))
- drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c — The EHFC/RFA/RFD programming block now checks the flag and skips when it's set
- drivers/net/ethernet/stmicro/stmmac/dwmac-adi.c — Sets the flag in dwmac_adi_probe() before calling stmmac_dvr_probe()
This prevents the ADSP-SC846 EMAC from ever setting the EHFC bit in EMAC_RQ0_OPMODE, so no automatic pause frames will be transmitted regardless of Rx FIFO state. Software-triggered flow control (via TFE/phylink) remains available if ever needed in the future.
This is a follow-up to analogdevicesinc/system-level#559 (comment).
This is a follow-up to analogdevicesinc/system-level#559 (comment).