drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c
Extension
.c
Size
7575 bytes
Lines
305
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 (phydev->link) {
			switch (phydev->speed) {
			case SPEED_10:
				speed = HBG_PORT_MODE_SGMII_10M;
				break;
			case SPEED_100:
				speed = HBG_PORT_MODE_SGMII_100M;
				break;
			case SPEED_1000:
				speed = HBG_PORT_MODE_SGMII_1000M;
				break;
			default:
				return;
			}

			priv->mac.speed = speed;
			priv->mac.duplex = phydev->duplex;
			priv->mac.autoneg = phydev->autoneg;
			hbg_hw_adjust_link(priv, speed, phydev->duplex);
			hbg_flowctrl_cfg(priv);
		}

		priv->mac.link_status = phydev->link;
		phy_print_status(phydev);
	}
}

static void hbg_phy_disconnect(void *data)
{
	phy_disconnect((struct phy_device *)data);
}

static int hbg_phy_connect(struct hbg_priv *priv)
{
	struct phy_device *phydev = priv->mac.phydev;
	struct device *dev = &priv->pdev->dev;
	int ret;

	ret = phy_connect_direct(priv->netdev, phydev, hbg_phy_adjust_link,
				 PHY_INTERFACE_MODE_SGMII);
	if (ret)
		return dev_err_probe(dev, ret, "failed to connect phy\n");

	ret = devm_add_action_or_reset(dev, hbg_phy_disconnect, phydev);
	if (ret)
		return ret;

	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
	phy_support_asym_pause(phydev);
	phy_attached_info(phydev);

	return 0;
}

void hbg_phy_start(struct hbg_priv *priv)
{
	phy_start(priv->mac.phydev);
}

void hbg_phy_stop(struct hbg_priv *priv)
{
	phy_stop(priv->mac.phydev);
}

static void hbg_fixed_phy_uninit(void *data)
{
	fixed_phy_unregister((struct phy_device *)data);
}

static int hbg_fixed_phy_init(struct hbg_priv *priv)
{
	struct fixed_phy_status hbg_fixed_phy_status = {
		.link = 1,
		.speed = SPEED_1000,
		.duplex = DUPLEX_FULL,
		.pause = 1,
		.asym_pause = 1,
	};
	struct device *dev = &priv->pdev->dev;
	struct phy_device *phydev;
	int ret;

	phydev = fixed_phy_register(&hbg_fixed_phy_status, NULL);
	if (IS_ERR(phydev)) {
		dev_err_probe(dev, PTR_ERR(phydev),
			      "failed to register fixed PHY device\n");
		return PTR_ERR(phydev);
	}

	ret = devm_add_action_or_reset(dev, hbg_fixed_phy_uninit, phydev);

Annotation

Implementation Notes