drivers/net/ethernet/actions/owl-emac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/actions/owl-emac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/actions/owl-emac.c
Extension
.c
Size
40571 bytes
Lines
1613
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops owl_emac_netdev_ops = {
	.ndo_open		= owl_emac_ndo_open,
	.ndo_stop		= owl_emac_ndo_stop,
	.ndo_start_xmit		= owl_emac_ndo_start_xmit,
	.ndo_set_rx_mode	= owl_emac_ndo_set_rx_mode,
	.ndo_set_mac_address	= owl_emac_ndo_set_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_eth_ioctl		= owl_emac_ndo_eth_ioctl,
	.ndo_tx_timeout         = owl_emac_ndo_tx_timeout,
	.ndo_get_stats		= owl_emac_ndo_get_stats,
};

static void owl_emac_ethtool_get_drvinfo(struct net_device *dev,
					 struct ethtool_drvinfo *info)
{
	strscpy(info->driver, OWL_EMAC_DRVNAME, sizeof(info->driver));
}

static u32 owl_emac_ethtool_get_msglevel(struct net_device *netdev)
{
	struct owl_emac_priv *priv = netdev_priv(netdev);

	return priv->msg_enable;
}

static void owl_emac_ethtool_set_msglevel(struct net_device *ndev, u32 val)
{
	struct owl_emac_priv *priv = netdev_priv(ndev);

	priv->msg_enable = val;
}

static const struct ethtool_ops owl_emac_ethtool_ops = {
	.get_drvinfo		= owl_emac_ethtool_get_drvinfo,
	.get_link		= ethtool_op_get_link,
	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
	.get_msglevel		= owl_emac_ethtool_get_msglevel,
	.set_msglevel		= owl_emac_ethtool_set_msglevel,
};

static int owl_emac_mdio_wait(struct owl_emac_priv *priv)
{
	u32 val;

	/* Wait while data transfer is in progress. */
	return readl_poll_timeout(priv->base + OWL_EMAC_REG_MAC_CSR10,
				  val, !(val & OWL_EMAC_BIT_MAC_CSR10_SB),
				  OWL_EMAC_POLL_DELAY_USEC,
				  OWL_EMAC_MDIO_POLL_TIMEOUT_USEC);
}

static int owl_emac_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
	struct owl_emac_priv *priv = bus->priv;
	u32 data, tmp;
	int ret;

	data = OWL_EMAC_BIT_MAC_CSR10_SB;
	data |= OWL_EMAC_VAL_MAC_CSR10_OPCODE_RD << OWL_EMAC_OFF_MAC_CSR10_OPCODE;

	tmp = addr << OWL_EMAC_OFF_MAC_CSR10_PHYADD;
	data |= tmp & OWL_EMAC_MSK_MAC_CSR10_PHYADD;

	tmp = regnum << OWL_EMAC_OFF_MAC_CSR10_REGADD;
	data |= tmp & OWL_EMAC_MSK_MAC_CSR10_REGADD;

	owl_emac_reg_write(priv, OWL_EMAC_REG_MAC_CSR10, data);

	ret = owl_emac_mdio_wait(priv);
	if (ret)
		return ret;

	data = owl_emac_reg_read(priv, OWL_EMAC_REG_MAC_CSR10);
	data &= OWL_EMAC_MSK_MAC_CSR10_DATA;

	return data;
}

static int
owl_emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
{
	struct owl_emac_priv *priv = bus->priv;
	u32 data, tmp;

	data = OWL_EMAC_BIT_MAC_CSR10_SB;
	data |= OWL_EMAC_VAL_MAC_CSR10_OPCODE_WR << OWL_EMAC_OFF_MAC_CSR10_OPCODE;

	tmp = addr << OWL_EMAC_OFF_MAC_CSR10_PHYADD;
	data |= tmp & OWL_EMAC_MSK_MAC_CSR10_PHYADD;

Annotation

Implementation Notes