drivers/net/ethernet/faraday/ftgmac100.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/faraday/ftgmac100.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/faraday/ftgmac100.c
Extension
.c
Size
56212 bytes
Lines
2164
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 ftgmac100_netdev_ops = {
	.ndo_open		= ftgmac100_open,
	.ndo_stop		= ftgmac100_stop,
	.ndo_start_xmit		= ftgmac100_hard_start_xmit,
	.ndo_set_mac_address	= ftgmac100_set_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_eth_ioctl		= phy_do_ioctl,
	.ndo_tx_timeout		= ftgmac100_tx_timeout,
	.ndo_set_rx_mode	= ftgmac100_set_rx_mode,
	.ndo_set_features	= ftgmac100_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= ftgmac100_poll_controller,
#endif
	.ndo_vlan_rx_add_vid	= ncsi_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= ncsi_vlan_rx_kill_vid,
};

static int ftgmac100_setup_mdio(struct net_device *netdev)
{
	struct ftgmac100 *priv = netdev_priv(netdev);
	struct platform_device *pdev = to_platform_device(priv->dev);
	struct device_node *np = pdev->dev.of_node;
	struct device_node *mdio_np;
	int err = 0;
	u32 reg;

	/* initialize mdio bus */
	priv->mii_bus = devm_mdiobus_alloc(priv->dev);
	if (!priv->mii_bus)
		return -EIO;

	if (priv->mac_id == FTGMAC100_AST2400 ||
	    priv->mac_id == FTGMAC100_AST2500) {
		/* The AST2600 has a separate MDIO controller */

		/* For the AST2400 and AST2500 this driver only supports the
		 * old MDIO interface
		 */
		reg = ioread32(priv->base + FTGMAC100_OFFSET_REVR);
		reg &= ~FTGMAC100_REVR_NEW_MDIO_INTERFACE;
		iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR);
	}

	priv->mii_bus->name = "ftgmac100_mdio";
	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d",
		 pdev->name, pdev->id);
	priv->mii_bus->parent = priv->dev;
	priv->mii_bus->priv = priv->netdev;
	priv->mii_bus->read = ftgmac100_mdiobus_read;
	priv->mii_bus->write = ftgmac100_mdiobus_write;

	mdio_np = of_get_child_by_name(np, "mdio");

	err = devm_of_mdiobus_register(priv->dev, priv->mii_bus, mdio_np);
	of_node_put(mdio_np);
	if (err) {
		dev_err(priv->dev, "Cannot register MDIO bus!\n");
		return err;
	}

	return 0;
}

static void ftgmac100_phy_disconnect(struct net_device *netdev)
{
	struct ftgmac100 *priv = netdev_priv(netdev);
	struct phy_device *phydev = netdev->phydev;

	if (!phydev)
		return;

	phy_disconnect(phydev);
	if (of_phy_is_fixed_link(priv->dev->of_node))
		of_phy_deregister_fixed_link(priv->dev->of_node);

	if (priv->use_ncsi)
		fixed_phy_unregister(phydev);
}

static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
{
	if (unlikely(nd->state != ncsi_dev_state_functional))
		return;

	netdev_dbg(nd->dev, "NCSI interface %s\n",
		   nd->link_up ? "up" : "down");
}

static int ftgmac100_setup_clk(struct ftgmac100 *priv)
{

Annotation

Implementation Notes