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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
Extension
.c
Size
19399 bytes
Lines
693
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 socfpga_dwmac_ops {
	int (*set_phy_mode)(struct socfpga_dwmac *dwmac_priv,
			    struct device *dev);
	void (*setup_plat_dat)(struct socfpga_dwmac *dwmac_priv);
};

struct socfpga_dwmac {
	u32	reg_offset;
	u32	reg_shift;
	struct plat_stmmacenet_data *plat_dat;
	struct regmap *sys_mgr_base_addr;
	struct reset_control *stmmac_rst;
	struct reset_control *stmmac_ocp_rst;
	void __iomem *splitter_base;
	void __iomem *tse_pcs_base;
	void __iomem *sgmii_adapter_base;
	bool f2h_ptp_ref_clk;
	const struct socfpga_dwmac_ops *ops;
};

static phy_interface_t socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
{
	return dwmac->plat_dat->phy_interface;
}

static void socfpga_sgmii_config(struct socfpga_dwmac *dwmac, bool enable)
{
	u16 val = enable ? SGMII_ADAPTER_ENABLE : SGMII_ADAPTER_DISABLE;

	writew(val, dwmac->sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
}

static void socfpga_dwmac_fix_mac_speed(void *bsp_priv,
					phy_interface_t interface, int speed,
					unsigned int mode)
{
	struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)bsp_priv;
	void __iomem *sgmii_adapter_base = dwmac->sgmii_adapter_base;
	phy_interface_t phymode = socfpga_get_plat_phymode(dwmac);
	void __iomem *splitter_base = dwmac->splitter_base;
	u32 val;

	if (sgmii_adapter_base)
		socfpga_sgmii_config(dwmac, false);

	if (splitter_base) {
		val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
		val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK;

		switch (speed) {
		case 1000:
			val |= EMAC_SPLITTER_CTRL_SPEED_1000;
			break;
		case 100:
			val |= EMAC_SPLITTER_CTRL_SPEED_100;
			break;
		case 10:
			val |= EMAC_SPLITTER_CTRL_SPEED_10;
			break;
		default:
			return;
		}
		writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
	}

	if ((phymode == PHY_INTERFACE_MODE_SGMII ||
	     phymode == PHY_INTERFACE_MODE_1000BASEX) && sgmii_adapter_base)
		socfpga_sgmii_config(dwmac, true);
}

static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct regmap *sys_mgr_base_addr;
	u32 reg_offset, reg_shift;
	int ret, index;
	struct device_node *np_splitter = NULL;
	struct device_node *np_sgmii_adapter = NULL;
	struct resource res_splitter;
	struct resource res_tse_pcs;
	struct resource res_sgmii_adapter;

	sys_mgr_base_addr =
		altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
	if (IS_ERR(sys_mgr_base_addr)) {
		dev_info(dev, "No sysmgr-syscon node found\n");
		return PTR_ERR(sys_mgr_base_addr);
	}

	ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);

Annotation

Implementation Notes