drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c
Extension
.c
Size
10260 bytes
Lines
399
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 (cause & MV88E1XXX_INTR_LINK_CHNG) {
			(void) simple_mdio_read(cphy,
				MV88E1XXX_SPECIFIC_STATUS_REGISTER, &status);

			if (status & MV88E1XXX_INTR_LINK_CHNG)
				cphy->state |= PHY_LINK_UP;
			else {
				cphy->state &= ~PHY_LINK_UP;
				if (cphy->state & PHY_AUTONEG_EN)
					cphy->state &= ~PHY_AUTONEG_RDY;
				cphy_cause |= cphy_cause_link_change;
			}
		}

		if (cause & MV88E1XXX_INTR_AUTONEG_DONE)
			cphy->state |= PHY_AUTONEG_RDY;

		if ((cphy->state & (PHY_LINK_UP | PHY_AUTONEG_RDY)) ==
			(PHY_LINK_UP | PHY_AUTONEG_RDY))
				cphy_cause |= cphy_cause_link_change;
	}
	return cphy_cause;
}

static void mv88e1xxx_destroy(struct cphy *cphy)
{
	kfree(cphy);
}

static const struct cphy_ops mv88e1xxx_ops = {
	.destroy              = mv88e1xxx_destroy,
	.reset                = mv88e1xxx_reset,
	.interrupt_enable     = mv88e1xxx_interrupt_enable,
	.interrupt_disable    = mv88e1xxx_interrupt_disable,
	.interrupt_clear      = mv88e1xxx_interrupt_clear,
	.interrupt_handler    = mv88e1xxx_interrupt_handler,
	.autoneg_enable       = mv88e1xxx_autoneg_enable,
	.autoneg_disable      = mv88e1xxx_autoneg_disable,
	.autoneg_restart      = mv88e1xxx_autoneg_restart,
	.advertise            = mv88e1xxx_advertise,
	.set_loopback         = mv88e1xxx_set_loopback,
	.set_speed_duplex     = mv88e1xxx_set_speed_duplex,
	.get_link_status      = mv88e1xxx_get_link_status,
};

static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr,
					 const struct mdio_ops *mdio_ops)
{
	struct adapter *adapter = netdev_priv(dev);
	struct cphy *cphy = kzalloc_obj(*cphy);

	if (!cphy)
		return NULL;

	cphy_init(cphy, dev, phy_addr, &mv88e1xxx_ops, mdio_ops);

	/* Configure particular PHY's to run in a different mode. */
	if ((board_info(adapter)->caps & SUPPORTED_TP) &&
	    board_info(adapter)->chip_phy == CHBT_PHY_88E1111) {
		/*
		 * Configure the PHY transmitter as class A to reduce EMI.
		 */
		(void) simple_mdio_write(cphy,
				MV88E1XXX_EXTENDED_ADDR_REGISTER, 0xB);
		(void) simple_mdio_write(cphy,
				MV88E1XXX_EXTENDED_REGISTER, 0x8004);
	}
	(void) mv88e1xxx_downshift_set(cphy, 1);   /* Enable downshift */

	/* LED */
	if (is_T2(adapter)) {
		(void) simple_mdio_write(cphy,
				MV88E1XXX_LED_CONTROL_REGISTER, 0x1);
	}

	return cphy;
}

static int mv88e1xxx_phy_reset(adapter_t* adapter)
{
	return 0;
}

const struct gphy t1_mv88e1xxx_ops = {
	.create = mv88e1xxx_phy_create,
	.reset =  mv88e1xxx_phy_reset
};

Annotation

Implementation Notes