drivers/net/phy/dp83tg720.c

Source file repositories/reference/linux-study-clean/drivers/net/phy/dp83tg720.c

File Facts

System
Linux kernel
Corpus path
drivers/net/phy/dp83tg720.c
Extension
.c
Size
20704 bytes
Lines
679
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 dp83tg720_stats {
	u64 link_loss_cnt;
	u64 tx_pkt_cnt;
	u64 tx_err_pkt_cnt;
	u64 rx_pkt_cnt;
	u64 rx_err_pkt_cnt;
};

struct dp83tg720_priv {
	struct dp83tg720_stats stats;
	unsigned long last_link_down_jiffies;
};

/**
 * dp83tg720_update_stats - Update the PHY statistics for the DP83TD510 PHY.
 * @phydev: Pointer to the phy_device structure.
 *
 * The function reads the PHY statistics registers and updates the statistics
 * structure.
 *
 * Returns: 0 on success or a negative error code on failure.
 */
static int dp83tg720_update_stats(struct phy_device *phydev)
{
	struct dp83tg720_priv *priv = phydev->priv;
	u32 count;
	int ret;

	/* Read the link loss count */
	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LINK_QUAL_3);
	if (ret < 0)
		return ret;
	/* link_loss_cnt */
	count = FIELD_GET(DP83TG720S_LINK_LOSS_CNT_MASK, ret);
	priv->stats.link_loss_cnt += count;

	/* The DP83TG720S_PKT_STAT registers are divided into two groups:
	 * - Group 1 (TX stats): DP83TG720S_PKT_STAT_1 to DP83TG720S_PKT_STAT_3
	 * - Group 2 (RX stats): DP83TG720S_PKT_STAT_4 to DP83TG720S_PKT_STAT_6
	 *
	 * Registers in each group are cleared only after reading them in a
	 * plain sequence (e.g., 1, 2, 3 for Group 1 or 4, 5, 6 for Group 2).
	 * Any deviation from the sequence, such as reading 1, 2, 1, 2, 3, will
	 * prevent the group from being cleared. Additionally, the counters
	 * for a group are frozen as soon as the first register in that group
	 * is accessed.
	 */
	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_1);
	if (ret < 0)
		return ret;
	/* tx_pkt_cnt_15_0 */
	count = ret;

	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_2);
	if (ret < 0)
		return ret;
	/* tx_pkt_cnt_31_16 */
	count |= ret << 16;
	priv->stats.tx_pkt_cnt += count;

	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_3);
	if (ret < 0)
		return ret;
	/* tx_err_pkt_cnt */
	priv->stats.tx_err_pkt_cnt += ret;

	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_4);
	if (ret < 0)
		return ret;
	/* rx_pkt_cnt_15_0 */
	count = ret;

	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_5);
	if (ret < 0)
		return ret;
	/* rx_pkt_cnt_31_16 */
	count |= ret << 16;
	priv->stats.rx_pkt_cnt += count;

	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_6);
	if (ret < 0)
		return ret;
	/* rx_err_pkt_cnt */
	priv->stats.rx_err_pkt_cnt += ret;

	return 0;
}

static int dp83tg720_soft_reset(struct phy_device *phydev)
{

Annotation

Implementation Notes