drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
Extension
.c
Size
19297 bytes
Lines
686
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct stm32_dwmac {
	struct clk *clk_tx;
	struct clk *clk_rx;
	struct clk *clk_eth_ck;
	struct clk *clk_ethstp;
	struct clk *syscfg_clk;
	int ext_phyclk;
	int enable_eth_ck;
	int eth_clk_sel_reg;
	int eth_ref_clk_sel_reg;
	int irq_pwr_wakeup;
	u32 mode_reg;		 /* MAC glue-logic mode register */
	u32 mode_mask;
	struct regmap *regmap;
	u32 speed;
	const struct stm32_ops *ops;
	struct device *dev;
};

struct stm32_ops {
	int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
	int (*suspend)(struct stm32_dwmac *dwmac);
	void (*resume)(struct stm32_dwmac *dwmac);
	int (*parse_data)(struct stm32_dwmac *dwmac,
			  struct device *dev);
	bool clk_rx_enable_in_suspend;
	bool is_mp13, is_mp2;
	u32 syscfg_clr_off;
};

static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac)
{
	int ret;

	ret = clk_prepare_enable(dwmac->clk_tx);
	if (ret)
		goto err_clk_tx;

	ret = clk_prepare_enable(dwmac->clk_rx);
	if (ret)
		goto err_clk_rx;

	ret = clk_prepare_enable(dwmac->syscfg_clk);
	if (ret)
		goto err_syscfg_clk;

	if (dwmac->enable_eth_ck) {
		ret = clk_prepare_enable(dwmac->clk_eth_ck);
		if (ret)
			goto err_clk_eth_ck;
	}

	return ret;

err_clk_eth_ck:
	clk_disable_unprepare(dwmac->syscfg_clk);
err_syscfg_clk:
	clk_disable_unprepare(dwmac->clk_rx);
err_clk_rx:
	clk_disable_unprepare(dwmac->clk_tx);
err_clk_tx:
	return ret;
}

static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
{
	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
	int ret;

	if (dwmac->ops->set_mode) {
		ret = dwmac->ops->set_mode(plat_dat);
		if (ret)
			return ret;
	}

	return stm32_dwmac_clk_enable(dwmac);
}

static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat)
{
	struct stm32_dwmac *dwmac = plat_dat->bsp_priv;

	switch (plat_dat->phy_interface) {
	case PHY_INTERFACE_MODE_MII:
		dwmac->enable_eth_ck = dwmac->ext_phyclk;
		return 0;
	case PHY_INTERFACE_MODE_GMII:
		dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
				       dwmac->ext_phyclk;
		return 0;

Annotation

Implementation Notes