drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c
Extension
.c
Size
16270 bytes
Lines
607
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

if (!(done & BUSY_MASK)) {
			data = xgene_enet_rd_mac(p, MII_MGMT_STATUS_ADDR);
			xgene_enet_wr_mac(p, MII_MGMT_COMMAND_ADDR, 0);

			return data;
		}
		usleep_range(10, 20);
	}

	netdev_err(p->ndev, "MII_MGMT read failed\n");

	return 0;
}

static void xgene_sgmac_reset(struct xgene_enet_pdata *p)
{
	xgene_enet_wr_mac(p, MAC_CONFIG_1_ADDR, SOFT_RESET1);
	xgene_enet_wr_mac(p, MAC_CONFIG_1_ADDR, 0);
}

static void xgene_sgmac_set_mac_addr(struct xgene_enet_pdata *p)
{
	const u8 *dev_addr = p->ndev->dev_addr;
	u32 addr0, addr1;

	addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
		(dev_addr[1] << 8) | dev_addr[0];
	xgene_enet_wr_mac(p, STATION_ADDR0_ADDR, addr0);

	addr1 = xgene_enet_rd_mac(p, STATION_ADDR1_ADDR);
	addr1 |= (dev_addr[5] << 24) | (dev_addr[4] << 16);
	xgene_enet_wr_mac(p, STATION_ADDR1_ADDR, addr1);
}

static u32 xgene_enet_link_status(struct xgene_enet_pdata *p)
{
	u32 data;

	data = xgene_mii_phy_read(p, INT_PHY_ADDR,
				  SGMII_BASE_PAGE_ABILITY_ADDR >> 2);

	if (LINK_SPEED(data) == PHY_SPEED_1000)
		p->phy_speed = SPEED_1000;
	else if (LINK_SPEED(data) == PHY_SPEED_100)
		p->phy_speed = SPEED_100;
	else
		p->phy_speed = SPEED_10;

	return data & LINK_UP;
}

static void xgene_sgmii_configure(struct xgene_enet_pdata *p)
{
	xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2,
			    0x8000);
	xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_CONTROL_ADDR >> 2, 0x9000);
	xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0);
}

static void xgene_sgmii_tbi_control_reset(struct xgene_enet_pdata *p)
{
	xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2,
			    0x8000);
	xgene_mii_phy_write(p, INT_PHY_ADDR, SGMII_TBI_CONTROL_ADDR >> 2, 0);
}

static void xgene_sgmii_reset(struct xgene_enet_pdata *p)
{
	u32 value;

	if (p->phy_speed == SPEED_UNKNOWN)
		return;

	value = xgene_mii_phy_read(p, INT_PHY_ADDR,
				   SGMII_BASE_PAGE_ABILITY_ADDR >> 2);
	if (!(value & LINK_UP))
		xgene_sgmii_tbi_control_reset(p);
}

static void xgene_sgmac_set_speed(struct xgene_enet_pdata *p)
{
	u32 icm0_addr, icm2_addr, debug_addr;
	u32 icm0, icm2, intf_ctl;
	u32 mc2, value;

	xgene_sgmii_reset(p);

	if (p->enet_id == XGENE_ENET1) {
		icm0_addr = ICM_CONFIG0_REG_0_ADDR + p->port_id * OFFSET_8;
		icm2_addr = ICM_CONFIG2_REG_0_ADDR + p->port_id * OFFSET_4;

Annotation

Implementation Notes