drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
Extension
.c
Size
8756 bytes
Lines
275
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*******************************************************************************
  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
  developing this code.

  This contains the functions to handle the dma.

  Copyright (C) 2007-2009  STMicroelectronics Ltd


  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/

#include <linux/io.h>
#include "dwmac1000.h"
#include "dwmac_dma.h"

static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
{
	u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);

	pr_info("dwmac1000: Master AXI performs %s burst length\n",
		!(value & DMA_AXI_UNDEF) ? "fixed" : "any");

	if (axi->axi_lpi_en)
		value |= DMA_AXI_EN_LPI;
	if (axi->axi_xit_frm)
		value |= DMA_AXI_LPI_XIT_FRM;

	value = u32_replace_bits(value, axi->axi_wr_osr_lmt,
				 DMA_AXI_WR_OSR_LMT);
	value = u32_replace_bits(value, axi->axi_rd_osr_lmt,
				 DMA_AXI_RD_OSR_LMT);

	/* Depending on the UNDEF bit the Master AXI will perform any burst
	 * length according to the BLEN programmed (by default all BLEN are
	 * set). Note that the UNDEF bit is readonly, and is the inverse of
	 * Bus Mode bit 16.
	 */
	value = (value & ~DMA_AXI_BLEN_MASK) | axi->axi_blen_regval;

	writel(value, ioaddr + DMA_AXI_BUS_MODE);
}

static void dwmac1000_dma_init_channel(struct stmmac_priv *priv,
				       void __iomem *ioaddr,
				       struct stmmac_dma_cfg *dma_cfg, u32 chan)
{
	int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
	int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
	u32 value;

	value = readl(ioaddr + DMA_CHAN_BUS_MODE(chan));

	/* Set the DMA PBL (Programmable Burst Length) mode.
	 *
	 * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
	 * post 3.5 mode bit acts as 8*PBL.
	 */
	if (dma_cfg->pblx8)
		value |= DMA_BUS_MODE_MAXPBL;
	value |= DMA_BUS_MODE_USP;
	value = u32_replace_bits(value, txpbl, DMA_BUS_MODE_PBL_MASK);
	value = u32_replace_bits(value, rxpbl, DMA_BUS_MODE_RPBL_MASK);

	/* Set the Fixed burst mode */
	if (dma_cfg->fixed_burst)
		value |= DMA_BUS_MODE_FB;

	/* Mixed Burst has no effect when fb is set */
	if (dma_cfg->mixed_burst)
		value |= DMA_BUS_MODE_MB;

	if (dma_cfg->atds)
		value |= DMA_BUS_MODE_ATDS;

	if (dma_cfg->aal)
		value |= DMA_BUS_MODE_AAL;

	writel(value, ioaddr + DMA_CHAN_BUS_MODE(chan));

	/* Mask interrupts by writing to CSR7 */
	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_CHAN_INTR_ENA(chan));
}

static void dwmac1000_dma_init_rx(struct stmmac_priv *priv,
				  void __iomem *ioaddr,
				  struct stmmac_dma_cfg *dma_cfg,
				  dma_addr_t dma_rx_phy, u32 chan)

Annotation

Implementation Notes