drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c- Extension
.c- Size
- 9713 bytes
- Lines
- 315
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
stmmac.hstmmac_fpe.hdwmac4.hdwmac5.hdwxgmac2.h
Detected Declarations
struct stmmac_fpe_regfunction stmmac_fpe_supportedfunction stmmac_fpe_configure_txfunction stmmac_fpe_configure_pmacfunction stmmac_fpe_send_mpacketfunction stmmac_fpe_event_statusfunction stmmac_fpe_irq_statusfunction stmmac_fpe_initfunction stmmac_fpe_get_add_frag_sizefunction stmmac_fpe_set_add_frag_sizefunction dwmac5_fpe_map_preemption_classfunction dwxgmac3_fpe_map_preemption_class
Annotated Snippet
struct stmmac_fpe_reg {
const u32 mac_fpe_reg; /* offset of MAC_FPE_CTRL_STS */
const u32 mtl_fpe_reg; /* offset of MTL_FPE_CTRL_STS */
const u32 rxq_ctrl1_reg; /* offset of MAC_RxQ_Ctrl1 */
const u32 fprq_mask; /* Frame Preemption Residue Queue */
const u32 int_en_reg; /* offset of MAC_Interrupt_Enable */
const u32 int_en_bit; /* Frame Preemption Interrupt Enable */
};
bool stmmac_fpe_supported(struct stmmac_priv *priv)
{
return priv->dma_cap.fpesel && priv->fpe_cfg.reg &&
priv->hw->mac->fpe_map_preemption_class;
}
static void stmmac_fpe_configure_tx(struct ethtool_mmsv *mmsv, bool tx_enable)
{
struct stmmac_fpe_cfg *cfg = container_of(mmsv, struct stmmac_fpe_cfg, mmsv);
struct stmmac_priv *priv = container_of(cfg, struct stmmac_priv, fpe_cfg);
const struct stmmac_fpe_reg *reg = cfg->reg;
u32 num_rxq = priv->plat->rx_queues_to_use;
void __iomem *ioaddr = priv->ioaddr;
u32 value;
if (tx_enable) {
cfg->fpe_csr = STMMAC_MAC_FPE_CTRL_STS_EFPE;
value = readl(ioaddr + reg->rxq_ctrl1_reg);
value &= ~reg->fprq_mask;
/* Keep this SHIFT, FIELD_PREP() expects a constant mask :-/ */
value |= (num_rxq - 1) << __ffs(reg->fprq_mask);
writel(value, ioaddr + reg->rxq_ctrl1_reg);
} else {
cfg->fpe_csr = 0;
}
writel(cfg->fpe_csr, ioaddr + reg->mac_fpe_reg);
}
static void stmmac_fpe_configure_pmac(struct ethtool_mmsv *mmsv, bool pmac_enable)
{
struct stmmac_fpe_cfg *cfg = container_of(mmsv, struct stmmac_fpe_cfg, mmsv);
struct stmmac_priv *priv = container_of(cfg, struct stmmac_priv, fpe_cfg);
const struct stmmac_fpe_reg *reg = cfg->reg;
void __iomem *ioaddr = priv->ioaddr;
unsigned long flags;
u32 value;
spin_lock_irqsave(&priv->hw->irq_ctrl_lock, flags);
value = readl(ioaddr + reg->int_en_reg);
if (pmac_enable) {
if (!(value & reg->int_en_bit)) {
/* Dummy read to clear any pending masked interrupts */
readl(ioaddr + reg->mac_fpe_reg);
value |= reg->int_en_bit;
}
} else {
value &= ~reg->int_en_bit;
}
writel(value, ioaddr + reg->int_en_reg);
spin_unlock_irqrestore(&priv->hw->irq_ctrl_lock, flags);
}
static void stmmac_fpe_send_mpacket(struct ethtool_mmsv *mmsv,
enum ethtool_mpacket type)
{
struct stmmac_fpe_cfg *cfg = container_of(mmsv, struct stmmac_fpe_cfg, mmsv);
struct stmmac_priv *priv = container_of(cfg, struct stmmac_priv, fpe_cfg);
const struct stmmac_fpe_reg *reg = cfg->reg;
void __iomem *ioaddr = priv->ioaddr;
u32 value = cfg->fpe_csr;
if (type == ETHTOOL_MPACKET_VERIFY)
value |= STMMAC_MAC_FPE_CTRL_STS_SVER;
else if (type == ETHTOOL_MPACKET_RESPONSE)
value |= STMMAC_MAC_FPE_CTRL_STS_SRSP;
writel(value, ioaddr + reg->mac_fpe_reg);
}
static const struct ethtool_mmsv_ops stmmac_mmsv_ops = {
.configure_tx = stmmac_fpe_configure_tx,
.configure_pmac = stmmac_fpe_configure_pmac,
.send_mpacket = stmmac_fpe_send_mpacket,
};
static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status)
{
struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;
Annotation
- Immediate include surface: `stmmac.h`, `stmmac_fpe.h`, `dwmac4.h`, `dwmac5.h`, `dwxgmac2.h`.
- Detected declarations: `struct stmmac_fpe_reg`, `function stmmac_fpe_supported`, `function stmmac_fpe_configure_tx`, `function stmmac_fpe_configure_pmac`, `function stmmac_fpe_send_mpacket`, `function stmmac_fpe_event_status`, `function stmmac_fpe_irq_status`, `function stmmac_fpe_init`, `function stmmac_fpe_get_add_frag_size`, `function stmmac_fpe_set_add_frag_size`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.