drivers/net/ethernet/chelsio/cxgb3/aq100x.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb3/aq100x.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb3/aq100x.c
Extension
.c
Size
8944 bytes
Lines
355
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

switch (v & 0x6) {
		case 0x6:
			*speed = SPEED_10000;
			break;
		case 0x4:
			*speed = SPEED_1000;
			break;
		case 0x2:
			*speed = SPEED_100;
			break;
		case 0x0:
			*speed = SPEED_10;
			break;
		}
	}

	if (duplex)
		*duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;

	return 0;
}

static const struct cphy_ops aq100x_ops = {
	.reset             = aq100x_reset,
	.intr_enable       = aq100x_intr_enable,
	.intr_disable      = aq100x_intr_disable,
	.intr_clear        = aq100x_intr_clear,
	.intr_handler      = aq100x_intr_handler,
	.autoneg_enable    = aq100x_autoneg_enable,
	.autoneg_restart   = aq100x_autoneg_restart,
	.advertise         = aq100x_advertise,
	.set_loopback      = aq100x_set_loopback,
	.set_speed_duplex  = aq100x_set_speed_duplex,
	.get_link_status   = aq100x_get_link_status,
	.power_down        = aq100x_power_down,
	.mmds 		   = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
};

int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
		       const struct mdio_ops *mdio_ops)
{
	unsigned int v, v2, gpio, wait;
	int err;

	cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
		  SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
		  SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI,
		  "1000/10GBASE-T");

	/*
	 * The PHY has been out of reset ever since the system powered up.  So
	 * we do a hard reset over here.
	 */
	gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
	t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
	msleep(1);
	t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);

	/*
	 * Give it enough time to load the firmware and get ready for mdio.
	 */
	msleep(1000);
	wait = 500; /* in 10ms increments */
	do {
		err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
		if (err || v == 0xffff) {

			/* Allow prep_adapter to succeed when ffff is read */

			CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
				phy_addr, err, v);
			goto done;
		}

		v &= AQ_RESET;
		if (v)
			msleep(10);
	} while (v && --wait);
	if (v) {
		CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
			phy_addr, v);

		goto done; /* let prep_adapter succeed */
	}

	/* Datasheet says 3s max but this has been observed */
	wait = (500 - wait) * 10 + 1000;
	if (wait > 3000)
		CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);

Annotation

Implementation Notes