示例#1
0
文件: brgphy.c 项目: AmirAbrams/haiku
static void
brgphy_setmedia(struct mii_softc *sc, int media)
{
	int bmcr = 0, gig;

	switch (IFM_SUBTYPE(media)) {
	case IFM_2500_SX:
		break;
	case IFM_1000_SX:
	case IFM_1000_T:
		bmcr = BRGPHY_S1000;
		break;
	case IFM_100_TX:
		bmcr = BRGPHY_S100;
		break;
	case IFM_10_T:
	default:
		bmcr = BRGPHY_S10;
		break;
	}

	if ((media & IFM_FDX) != 0) {
		bmcr |= BRGPHY_BMCR_FDX;
		gig = BRGPHY_1000CTL_AFD;
	} else {
		gig = BRGPHY_1000CTL_AHD;
	}

	/* Force loopback to disconnect PHY from Ethernet medium. */
	brgphy_enable_loopback(sc);

	PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0);
	PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE);

	if (IFM_SUBTYPE(media) != IFM_1000_T &&
	    IFM_SUBTYPE(media) != IFM_1000_SX) {
		PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr);
		return;
	}

	if (IFM_SUBTYPE(media) == IFM_1000_T) {
		gig |= BRGPHY_1000CTL_MSE;
		if ((media & IFM_ETH_MASTER) != 0)
			gig |= BRGPHY_1000CTL_MSC;
	}
	PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig);
	PHY_WRITE(sc, BRGPHY_MII_BMCR,
	    bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG);
}
示例#2
0
static void
brgphy_setmedia(struct mii_softc *sc, int media, int master)
{
	struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
	int bmcr = 0, gig;

	/* Calculate the value for the BMCR register. */
	switch (IFM_SUBTYPE(media)) {
	case IFM_2500_SX:
		break;
	case IFM_1000_SX:
	case IFM_1000_T:
		bmcr = BRGPHY_S1000;
		break;
	case IFM_100_TX:
		bmcr = BRGPHY_S100;
		break;
	case IFM_10_T:
	default:
		bmcr = BRGPHY_S10;
		break;
	}

	/* Calculate duplex settings for 1000BasetT/1000BaseX. */
	if ((media & IFM_GMASK) == IFM_FDX) {
		bmcr |= BRGPHY_BMCR_FDX;
		gig = BRGPHY_1000CTL_AFD;
	} else {
		gig = BRGPHY_1000CTL_AHD;
	}

	/* Force loopback to disconnect PHY for Ethernet medium. */
	brgphy_enable_loopback(sc);

	/* Disable 1000BaseT advertisements. */
	PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0);
	/* Disable 10/100 advertisements. */
	PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE);
	/* Write forced link speed. */
	PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr);

	/* If 10/100 only then configuration is complete. */
	if ((IFM_SUBTYPE(media) != IFM_1000_T) && (IFM_SUBTYPE(media) != IFM_1000_SX))
		goto brgphy_setmedia_exit;

	/* Set duplex speed advertisement for 1000BaseT/1000BaseX. */
	PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig);
	/* Restart auto-negotiation for 1000BaseT/1000BaseX. */
	PHY_WRITE(sc, BRGPHY_MII_BMCR,
	    bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG);

	/* If not 5701 PHY then configuration is complete. */
	if (bsc->mii_model != MII_MODEL_xxBROADCOM_BCM5701)
		goto brgphy_setmedia_exit;

	/*
	 * When setting the link manually, one side must be the master and
	 * the other the slave. However ifmedia doesn't give us a good way
	 * to specify this, so we fake it by using one of the LINK flags.
	 * If LINK0 is set, we program the PHY to be a master, otherwise
	 * it's a slave.
	 */
	if (master) {
		PHY_WRITE(sc, BRGPHY_MII_1000CTL,
		    gig | BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC);
	} else {
		PHY_WRITE(sc, BRGPHY_MII_1000CTL,
		    gig | BRGPHY_1000CTL_MSE);
	}

brgphy_setmedia_exit:
	return;
}