Example #1
0
/*
 * If we negotiate a 10Mbps mode, we need to check for an alternate
 * PHY and make sure it's enabled and set correctly.
 */
void
mlphy_status(struct mii_softc *sc)
{
    struct mlphy_softc *msc = (struct mlphy_softc *)sc;
    struct mii_data *mii = sc->mii_pdata;
    struct mii_softc *other = NULL;

    /* See if there's another PHY on the bus with us. */
    LIST_FOREACH(other, &mii->mii_phys, mii_list)
    if (other != sc)
        break;

    ukphy_status(sc);

    if (IFM_SUBTYPE(mii->mii_media_active) != IFM_10_T) {
        msc->ml_state = ML_STATE_AUTO_SELF;
        if (other != NULL) {
            mii_phy_reset(other);
            PHY_WRITE(other, MII_BMCR, BMCR_ISO);
        }
    }

    if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
        msc->ml_state = ML_STATE_AUTO_OTHER;
        mlphy_reset(&msc->ml_mii);
        PHY_WRITE(&msc->ml_mii, MII_BMCR, BMCR_ISO);
        if (other != NULL) {
            mii_phy_reset(other);
            mii_phy_auto(other, 1);
        }
    }
}
Example #2
0
int
ieee80211_media2rate(int mword)
{
#define	N(a)	(sizeof(a) / sizeof(a[0]))
	static const int ieeerates[] = {
		-1,		/* IFM_AUTO */
		0,		/* IFM_MANUAL */
		0,		/* IFM_NONE */
		2,		/* IFM_IEEE80211_FH1 */
		4,		/* IFM_IEEE80211_FH2 */
		4,		/* IFM_IEEE80211_DS2 */
		11,		/* IFM_IEEE80211_DS5 */
		22,		/* IFM_IEEE80211_DS11 */
		2,		/* IFM_IEEE80211_DS1 */
		44,		/* IFM_IEEE80211_DS22 */
		12,		/* IFM_IEEE80211_OFDM6 */
		18,		/* IFM_IEEE80211_OFDM9 */
		24,		/* IFM_IEEE80211_OFDM12 */
		36,		/* IFM_IEEE80211_OFDM18 */
		48,		/* IFM_IEEE80211_OFDM24 */
		72,		/* IFM_IEEE80211_OFDM36 */
		96,		/* IFM_IEEE80211_OFDM48 */
		108,		/* IFM_IEEE80211_OFDM54 */
		144,		/* IFM_IEEE80211_OFDM72 */
	};
	return IFM_SUBTYPE(mword) < N(ieeerates) ?
		ieeerates[IFM_SUBTYPE(mword)] : 0;
#undef N
}
Example #3
0
static void
le_dma_nocarrier(struct lance_softc *sc)
{
	struct le_dma_softc *lesc = (struct le_dma_softc *)sc;

	/*
	 * Check if the user has requested a certain cable type, and
	 * if so, honor that request.
	 */

	if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) {
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_5:
		case IFM_AUTO:
			if_printf(sc->sc_ifp, "lost carrier on UTP port, "
			    "switching to AUI port\n");
			le_dma_setaui(sc);
		}
	} else {
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_T:
		case IFM_AUTO:
			if_printf(sc->sc_ifp, "lost carrier on AUI port, "
			    "switching to UTP port\n");
			le_dma_setutp(sc);
		}
	}
}
int
rtems_ifmedia2str (int media, char *buf, int bufsz)
{
  const char *mdesc;
  const char *dupdesc = 0;

  /* only ethernet supported, so far */
  if (IFM_ETHER != IFM_TYPE (media))
    return -1;

  if (!(mdesc = find_desc (IFM_SUBTYPE (media), shared_media_strings)))
    mdesc = find_desc (IFM_SUBTYPE (media), ethern_media_strings);

  if (!mdesc)
    return -1;

  if (IFM_NONE != IFM_SUBTYPE (media))
    dupdesc = IFM_FDX & media ? " full-duplex" : " half-duplex";

  return WHATPRINT (buf, bufsz,
                    "Ethernet [phy instance: %" PRId32 "]: (link %s, autoneg %s) -- media: %s%s",
                    (int32_t) IFM_INST (media),
                    IFM_LINK_OK & media ? "ok" : "down",
                    IFM_ANEG_DIS & media ? "off" : "on",
                    mdesc, dupdesc ? dupdesc : "");
}
Example #5
0
static uint16_t
atphy_anar(struct ifmedia_entry *ife)
{
	uint16_t anar = 0;

	switch (IFM_SUBTYPE(ife->ifm_media)) {
	case IFM_AUTO:
		anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10;
		return anar;

	case IFM_1000_T:
		return anar;

	case IFM_100_TX:
		anar |= ANAR_TX;
		break;

	case IFM_10_T:
		anar |= ANAR_10;
		break;

	default:
		return 0;
	}

	if ((ife->ifm_media & IFM_GMASK) & IFM_FDX) {
		if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX)
			anar |= ANAR_TX_FD;
		else
			anar |= ANAR_10_FD;
	}
	return anar;
}
Example #6
0
File: qe.c Project: ryo/netbsd-src
/*
 * Set media options.
 */
int
qe_ifmedia_upd(struct ifnet *ifp)
{
	struct qe_softc *sc = ifp->if_softc;
	struct ifmedia *ifm = &sc->sc_ifmedia;
	bus_space_tag_t t = sc->sc_bustag;
	bus_space_handle_t mr = sc->sc_mr;
	int newmedia = ifm->ifm_media;
	uint8_t plscc, phycc;

#if defined(SUN4U) || defined(__GNUC__)
	(void)&t;
#endif
	if (IFM_TYPE(newmedia) != IFM_ETHER)
		return (EINVAL);

	plscc = bus_space_read_1(t, mr, QE_MRI_PLSCC) & ~QE_MR_PLSCC_PORTMASK;
	phycc = bus_space_read_1(t, mr, QE_MRI_PHYCC) & ~QE_MR_PHYCC_ASEL;

	if (IFM_SUBTYPE(newmedia) == IFM_AUTO)
		phycc |= QE_MR_PHYCC_ASEL;
	else if (IFM_SUBTYPE(newmedia) == IFM_10_T)
		plscc |= QE_MR_PLSCC_TP;
	else if (IFM_SUBTYPE(newmedia) == IFM_10_5)
		plscc |= QE_MR_PLSCC_AUI;

	bus_space_write_1(t, mr, QE_MRI_PLSCC, plscc);
	bus_space_write_1(t, mr, QE_MRI_PHYCC, phycc);

	return (0);
}
Example #7
0
static void
lenocarrier(struct lance_softc *sc)
{
	struct le_softc *lesc = (struct le_softc *)sc;

	/*
	 * Check if the user has requested a certain cable type, and
	 * if so, honor that request.
	 */
	printf("%s: lost carrier on ", device_xname(sc->sc_dev));

	if (L64854_GCSR(lesc->sc_dma) & E_TP_AUI) {
		printf("UTP port");
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_5:
		case IFM_AUTO:
			printf(", switching to AUI port");
			lesetaui(sc);
		}
	} else {
		printf("AUI port");
		switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
		case IFM_10_T:
		case IFM_AUTO:
			printf(", switching to UTP port");
			lesetutp(sc);
		}
	}
	printf("\n");
}
Example #8
0
void
mii_phy_setmedia(struct mii_softc *sc)
{
	struct mii_data *mii = sc->mii_pdata;
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
	int bmcr, anar, gtcr;

	if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
		/*
		 * Force renegotiation if MIIF_DOPAUSE or MIIF_FORCEANEG.
		 * The former is necessary as we might switch from flow-
		 * control advertisment being off to on or vice versa.
		 */
		if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 ||
		    (sc->mii_flags & (MIIF_DOPAUSE | MIIF_FORCEANEG)) != 0)
			(void)mii_phy_auto(sc);
		return;
	}

	/*
	 * Table index is stored in the media entry.
	 */

	KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA,
	    ("invalid ife->ifm_data (0x%x) in mii_phy_setmedia",
	    ife->ifm_data));

	anar = mii_media_table[ife->ifm_data].mm_anar;
	bmcr = mii_media_table[ife->ifm_data].mm_bmcr;
	gtcr = mii_media_table[ife->ifm_data].mm_gtcr;

	if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
		gtcr |= GTCR_MAN_MS;
		if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
			gtcr |= GTCR_ADV_MS;
	}

	if ((ife->ifm_media & IFM_GMASK) == (IFM_FDX | IFM_FLOW) ||
	    (sc->mii_flags & MIIF_FORCEPAUSE) != 0) {
		if ((sc->mii_flags & MIIF_IS_1000X) != 0)
			anar |= ANAR_X_PAUSE_TOWARDS;
		else {
			anar |= ANAR_FC;
			/* XXX Only 1000BASE-T has PAUSE_ASYM? */
			if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0 &&
			    (sc->mii_extcapabilities &
			    (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0)
				anar |= ANAR_X_PAUSE_ASYM;
		}
	}

	if ((ife->ifm_media & IFM_LOOP) != 0)
		bmcr |= BMCR_LOOP;

	PHY_WRITE(sc, MII_ANAR, anar);
	PHY_WRITE(sc, MII_BMCR, bmcr);
	if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0)
		PHY_WRITE(sc, MII_100T2CR, gtcr);
}
Example #9
0
static int
smcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
        struct	ifmedia_entry *ife;
        int	reg;

	ife = mii->mii_media.ifm_cur;

        switch (cmd) {
        case MII_POLLSTAT:
                break;

        case MII_MEDIACHG:
		switch (IFM_SUBTYPE(ife->ifm_media)) {
		case IFM_AUTO:
			smcphy_auto(sc, ife->ifm_media);
			break;

		default:
                	mii_phy_setmedia(sc);
			break;
		}

                break;

        case MII_TICK:
		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
			break;
		}

		/* I have no idea why BMCR_ISO gets set. */
		reg = PHY_READ(sc, MII_BMCR);
		if (reg & BMCR_ISO) {
			PHY_WRITE(sc, MII_BMCR, reg & ~BMCR_ISO);
		}

		reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
		if (reg & BMSR_LINK) {
			sc->mii_ticks = 0;
			break;
		}

		if (++sc->mii_ticks <= MII_ANEGTICKS) {
			break;
		}

		sc->mii_ticks = 0;
		PHY_RESET(sc);
		smcphy_auto(sc, ife->ifm_media);
                break;
        }

        /* Update the media status. */
        PHY_STATUS(sc);

        /* Callback if something changed. */
        mii_phy_update(sc, cmd);
        return (0);
}
Example #10
0
void
vte_miibus_statchg(struct device *dev)
{
	struct vte_softc *sc = (struct vte_softc *)dev;
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	struct mii_data *mii;
	uint16_t val;

	if ((ifp->if_flags & IFF_RUNNING) == 0)
		return;

	mii = &sc->sc_miibus;

	sc->vte_flags &= ~VTE_FLAG_LINK;
	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
	    (IFM_ACTIVE | IFM_AVALID)) {
		switch (IFM_SUBTYPE(mii->mii_media_active)) {
		case IFM_10_T:
		case IFM_100_TX:
			sc->vte_flags |= VTE_FLAG_LINK;
			break;
		default:
			break;
		}
	}

	/* Stop RX/TX MACs. */
	vte_stop_mac(sc);
	/* Program MACs with resolved duplex and flow control. */
	if ((sc->vte_flags & VTE_FLAG_LINK) != 0) {
		/*
		 * Timer waiting time : (63 + TIMER * 64) MII clock.
		 * MII clock : 25MHz(100Mbps) or 2.5MHz(10Mbps).
		 */
		if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
			val = 18 << VTE_IM_TIMER_SHIFT;
		else
			val = 1 << VTE_IM_TIMER_SHIFT;
		sc->vte_int_rx_mod = VTE_IM_RX_BUNDLE_DEFAULT;
		val |= sc->vte_int_rx_mod << VTE_IM_BUNDLE_SHIFT;
		/* 48.6us for 100Mbps, 50.8us for 10Mbps */
		CSR_WRITE_2(sc, VTE_MRICR, val);

		if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
			val = 18 << VTE_IM_TIMER_SHIFT;
		else
			val = 1 << VTE_IM_TIMER_SHIFT;
		sc->vte_int_tx_mod = VTE_IM_TX_BUNDLE_DEFAULT;
		val |= sc->vte_int_tx_mod << VTE_IM_BUNDLE_SHIFT;
		/* 48.6us for 100Mbps, 50.8us for 10Mbps */
		CSR_WRITE_2(sc, VTE_MTICR, val);

		vte_mac_config(sc);
		vte_start_mac(sc);
	}
}
Example #11
0
const char     *
get_media_subtype_string(uint64_t mword)
{
	const struct ifmedia_description *desc;

	for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL;
	     desc++) {
		if (IFM_TYPE_MATCH(desc->ifmt_word, mword) &&
		    IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(mword))
			return (desc->ifmt_string);
	}
	return ("<unknown subtype>");
}
Example #12
0
static int
truephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
	int bmcr;

	switch (cmd) {
	case MII_POLLSTAT:
		break;

	case MII_MEDIACHG:
		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
			bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_AUTOEN;
			PHY_WRITE(sc, MII_BMCR, bmcr);
			PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_PDOWN);
		}

		mii_phy_setmedia(sc);

		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
			bmcr = PHY_READ(sc, MII_BMCR) & ~BMCR_PDOWN;
			PHY_WRITE(sc, MII_BMCR, bmcr);

			if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
				PHY_WRITE(sc, MII_BMCR,
				    bmcr | BMCR_AUTOEN | BMCR_STARTNEG);
			}
		}
		break;

	case MII_TICK:
		if (mii_phy_tick(sc) == EJUSTRETURN)
			return (0);
		break;
	}

	/* Update the media status. */
	PHY_STATUS(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}
Example #13
0
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);
}
Example #14
0
int
ieee80211_media2rate(uint64_t mword)
{
	int i;
	static const struct {
		uint64_t subtype;
		int rate;
	} ieeerates[] = {
		{ IFM_AUTO,		-1	},
		{ IFM_MANUAL,		0	},
		{ IFM_NONE,		0	},
		{ IFM_IEEE80211_DS1,	2	},
		{ IFM_IEEE80211_DS2,	4	},
		{ IFM_IEEE80211_DS5,	11	},
		{ IFM_IEEE80211_DS11,	22	},
		{ IFM_IEEE80211_DS22,	44	},
		{ IFM_IEEE80211_OFDM6,	12	},
		{ IFM_IEEE80211_OFDM9,	18	},
		{ IFM_IEEE80211_OFDM12,	24	},
		{ IFM_IEEE80211_OFDM18,	36	},
		{ IFM_IEEE80211_OFDM24,	48	},
		{ IFM_IEEE80211_OFDM36,	72	},
		{ IFM_IEEE80211_OFDM48,	96	},
		{ IFM_IEEE80211_OFDM54,	108	},
		{ IFM_IEEE80211_OFDM72,	144	},
	};
	for (i = 0; i < nitems(ieeerates); i++) {
		if (ieeerates[i].subtype == IFM_SUBTYPE(mword))
			return ieeerates[i].rate;
	}
	return 0;
}
Example #15
0
int
ieee80211_media2rate(int mword)
{
#define	N(a)	(sizeof(a) / sizeof(a[0]))
	int i;
	static const struct {
		int subtype;
		int rate;
	} ieeerates[] = {
		{ IFM_AUTO,		-1	},
		{ IFM_MANUAL,		0	},
		{ IFM_NONE,		0	},
		{ IFM_IEEE80211_DS1,	2	},
		{ IFM_IEEE80211_DS2,	4	},
		{ IFM_IEEE80211_DS5,	11	},
		{ IFM_IEEE80211_DS11,	22	},
		{ IFM_IEEE80211_DS22,	44	},
		{ IFM_IEEE80211_OFDM6,	12	},
		{ IFM_IEEE80211_OFDM9,	18	},
		{ IFM_IEEE80211_OFDM12,	24	},
		{ IFM_IEEE80211_OFDM18,	36	},
		{ IFM_IEEE80211_OFDM24,	48	},
		{ IFM_IEEE80211_OFDM36,	72	},
		{ IFM_IEEE80211_OFDM48,	96	},
		{ IFM_IEEE80211_OFDM54,	108	},
		{ IFM_IEEE80211_OFDM72,	144	},
	};
	for (i = 0; i < N(ieeerates); i++) {
		if (ieeerates[i].subtype == IFM_SUBTYPE(mword))
			return ieeerates[i].rate;
	}
	return 0;
#undef N
}
Example #16
0
static int
axgbe_media_change(struct ifnet *ifp)
{
	struct axgbe_softc *sc;
	int cur_media;

	sc = ifp->if_softc;

	sx_xlock(&sc->prv.an_mutex);
	cur_media = sc->media.ifm_cur->ifm_media;

	switch (IFM_SUBTYPE(cur_media)) {
	case IFM_10G_KR:
		sc->prv.phy.speed = SPEED_10000;
		sc->prv.phy.autoneg = AUTONEG_DISABLE;
		break;
	case IFM_2500_KX:
		sc->prv.phy.speed = SPEED_2500;
		sc->prv.phy.autoneg = AUTONEG_DISABLE;
		break;
	case IFM_1000_KX:
		sc->prv.phy.speed = SPEED_1000;
		sc->prv.phy.autoneg = AUTONEG_DISABLE;
		break;
	case IFM_AUTO:
		sc->prv.phy.autoneg = AUTONEG_ENABLE;
		break;
	}
	sx_xunlock(&sc->prv.an_mutex);

	return (-sc->prv.phy_if.phy_config_aneg(&sc->prv));
}
Example #17
0
int
lemediachange(struct lance_softc *sc)
{
	struct ifmedia *ifm = &sc->sc_media;

	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
		return (EINVAL);

	/*
	 * Switch to the selected media.  If autoselect is
	 * set, we don't really have to do anything.  We'll
	 * switch to the other media when we detect loss of
	 * carrier.
	 */
	switch (IFM_SUBTYPE(ifm->ifm_media)) {
	case IFM_10_T:
		lesetutp(sc);
		break;

	case IFM_10_5:
		lesetaui(sc);
		break;

	case IFM_AUTO:
		break;

	default:
		return (EINVAL);
	}

	return (0);
}
Example #18
0
static int
tr_pcmcia_mediachange(struct tr_softc *sc)
{
	int setspeed = 0;

	if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_TOKEN)
		return EINVAL;

	switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
	case IFM_TOK_STP16:
	case IFM_TOK_UTP16:
		if ((sc->sc_init_status & RSP_16) == 0)
			setspeed = 1;
		break;
	case IFM_TOK_STP4:
	case IFM_TOK_UTP4:
		if ((sc->sc_init_status & RSP_16) != 0)
			setspeed = 1;
		break;
	}
	if (setspeed != 0) {
		tr_stop(sc);
		if (sc->sc_enabled)
			tr_pcmcia_disable(sc);
		sc->sc_init_status ^= RSP_16;		/* XXX 100 Mbit/s */
		if (sc->sc_enabled)
			tr_pcmcia_enable(sc);
	}
	/*
	 * XXX Handle Early Token Release !!!!
	 */

	return 0;
}
Example #19
0
void
tsec_mii_statchg(struct device *self)
{
	struct tsec_softc *sc = (void *)self;
	uint32_t maccfg2, ecntrl;

	ecntrl = tsec_read(sc, TSEC_ECNTRL);
	maccfg2 = tsec_read(sc, TSEC_MACCFG2);
	maccfg2 &= ~TSEC_MACCFG2_IF_MODE;

	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
	case IFM_1000_SX:
	case IFM_1000_LX:
	case IFM_1000_CX:
	case IFM_1000_T:
		maccfg2 |= TSEC_MACCFG2_IF_GMII;
		break;
	case IFM_100_TX:
		ecntrl |= TSEC_ECNTRL_R100M;
		maccfg2 |= TSEC_MACCFG2_IF_MII;
		break;
	case IFM_10_T:
		ecntrl &= ~TSEC_ECNTRL_R100M;
		maccfg2 |= TSEC_MACCFG2_IF_MII;
		break;
	}

	if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
		maccfg2 |= TSEC_MACCFG2_FDX;
	else
		maccfg2 &= ~TSEC_MACCFG2_FDX;

	tsec_write(sc, TSEC_MACCFG2, maccfg2);
	tsec_write(sc, TSEC_ECNTRL, ecntrl);
}
Example #20
0
static void
ed_rtl_get_media(struct ifnet *ifp, struct ifmediareq *imr)
{
	struct ed_softc *sc;

	sc = ifp->if_softc;
	imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;


	if (IFM_SUBTYPE(imr->ifm_active) == IFM_AUTO) {
		ED_LOCK(sc);
		ed_nic_barrier(sc, ED_P0_CR, 1,
		    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
		ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_3 |
			(ed_nic_inb(sc, ED_P0_CR) & (ED_CR_STA | ED_CR_STP)));
		ed_nic_barrier(sc, ED_P0_CR, 1,
		    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);

		switch (ed_nic_inb(sc, ED_RTL80X9_CONFIG0)
				& (sc->chip_type == ED_CHIP_TYPE_RTL8029 ? ED_RTL80X9_CF0_BNC
				: (ED_RTL80X9_CF0_AUI | ED_RTL80X9_CF0_BNC))) {
		case ED_RTL80X9_CF0_BNC:
			imr->ifm_active |= IFM_10_2;
			break;
		case ED_RTL80X9_CF0_AUI:
			imr->ifm_active |= IFM_10_5;
			break;
		default:
			imr->ifm_active |= IFM_10_T;
			break;
		}
		ED_UNLOCK(sc);
	}
	imr->ifm_status = 0;
}
Example #21
0
static int
atphy_setmedia(struct mii_softc *sc, int media)
{
	uint16_t anar;

	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
	if ((IFM_SUBTYPE(media) == IFM_AUTO || (media & IFM_FDX) != 0) &&
	    ((media & IFM_FLOW) != 0 ||
	    (sc->mii_flags & MIIF_FORCEPAUSE) != 0))
		anar |= ANAR_PAUSE_TOWARDS;
	PHY_WRITE(sc, MII_ANAR, anar);
	if ((sc->mii_extcapabilities &
	     (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
		PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX |
		    GTCR_ADV_1000THDX);
	else if (sc->mii_mpd_model == MII_MODEL_xxATHEROS_F1) {
		/*
		 * AR8132 has 10/100 PHY and the PHY uses the same
		 * model number of F1 gigabit PHY.  The PHY has no
		 * ability to establish gigabit link so explicitly
		 * disable 1000baseT configuration for the PHY.
		 * Otherwise, there is a case that atphy(4) could
		 * not establish a link against gigabit link partner
		 * unless the link partner supports down-shifting.
		 */
		PHY_WRITE(sc, MII_100T2CR, 0);
	}
	PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG);

	return (EJUSTRETURN);
}
Example #22
0
static void
kr_link_task(void *arg, int pending)
{
	struct kr_softc		*sc;
	struct mii_data		*mii;
	struct ifnet		*ifp;
	/* int			lfdx, mfdx; */

	sc = (struct kr_softc *)arg;

	KR_LOCK(sc);
	mii = device_get_softc(sc->kr_miibus);
	ifp = sc->kr_ifp;
	if (mii == NULL || ifp == NULL ||
	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
		KR_UNLOCK(sc);
		return;
	}

	if (mii->mii_media_status & IFM_ACTIVE) {
		if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
			sc->kr_link_status = 1;
	} else
		sc->kr_link_status = 0;

	KR_UNLOCK(sc);
}
Example #23
0
static int
jmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;

	switch (cmd) {
	case MII_POLLSTAT:
		break;

	case MII_MEDIACHG:
		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		if (jmphy_setmedia(sc, ife) != EJUSTRETURN)
			return (EINVAL);
		break;

	case MII_TICK:
		/*
		 * Is the interface even up?
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			return (0);

		/*
		 * Only used for autonegotiation.
		 */
		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
			sc->mii_ticks = 0;
			break;
		}

		/* Check for link. */
		if ((PHY_READ(sc, JMPHY_SSR) & JMPHY_SSR_LINK_UP) != 0) {
			sc->mii_ticks = 0;
			break;
		}

		/* Announce link loss right after it happens. */
		if (sc->mii_ticks++ == 0)
			break;
		if (sc->mii_ticks <= sc->mii_anegticks)
			return (0);

		sc->mii_ticks = 0;
		(void)jmphy_setmedia(sc, ife);
		break;
	}

	/* Update the media status. */
	PHY_STATUS(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}
Example #24
0
static int
acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
	int reg;

	/*
	 * If we're not selected, then do nothing, just isolate and power
	 * down, if changing media.
	 */
	if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
		if (cmd == MII_MEDIACHG) {
			reg = PHY_READ(sc, MII_BMCR);
			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO | BMCR_PDOWN);
		}

		return (0);
	}

	switch (cmd) {
	case MII_POLLSTAT:
		break;

	case MII_MEDIACHG:
		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		mii_phy_set_media(sc);
		break;

	case MII_TICK:
		/*
		 * Is the interface even up?
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			return (0);

		/*
		 * Only used for autonegotiation.
		 */
		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
			break;

		/*
		 * This PHY's autonegotiation doesn't need to be kicked.
		 */
		break;
	}

	/* Update the media status. */
	acphy_status(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}
Example #25
0
static int
lxtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
	int reg;

	switch (cmd) {
	case MII_POLLSTAT:
		/*
		 * If we're not polling our PHY instance, just return.
		 */
		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
			return (0);
		break;

	case MII_MEDIACHG:
		/*
		 * If the media indicates a different PHY instance,
		 * isolate ourselves.
		 */
		if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
			reg = PHY_READ(sc, MII_BMCR);
			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
			return (0);
		}

		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_FX)
			lxtphy_set_fx(sc);
		else
			lxtphy_set_tp(sc);

		mii_phy_setmedia(sc);
		break;

	case MII_TICK:
		/*
		 * If we're not currently selected, just return.
		 */
		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
			return (0);
		if (mii_phy_tick(sc) == EJUSTRETURN)
			return (0);
		break;
	}

	/* Update the media status. */
	lxtphy_status(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}
Example #26
0
static int
pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;

	switch (cmd) {
	case MII_POLLSTAT:
		break;

	case MII_MEDIACHG:
		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		switch (IFM_SUBTYPE(ife->ifm_media)) {
		case IFM_AUTO:
			/* NWAY is busted on this chip */
		case IFM_100_T4:
			/*
			 * XXX Not supported as a manual setting right now.
			 */
			return (EINVAL);
		case IFM_100_TX:
			mii->mii_media_active = IFM_ETHER | IFM_100_TX;
			if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
				mii->mii_media_active |= IFM_FDX;
			MIIBUS_STATCHG(sc->mii_dev);
			return (0);
		case IFM_10_T:
			mii->mii_media_active = IFM_ETHER | IFM_10_T;
			if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
				mii->mii_media_active |= IFM_FDX;
			MIIBUS_STATCHG(sc->mii_dev);
			return (0);
		default:
			return (EINVAL);
		}
		break;

	case MII_TICK:
		/*
		 * Is the interface even up?
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			return (0);

		break;
	}

	/* Update the media status. */
	pnphy_status(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}
void
mii_phy_setmedia(struct mii_softc *sc)
{
	struct mii_data *mii = sc->mii_pdata;
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
	int bmcr, anar, gtcr;

	if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
		if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 ||
		    (sc->mii_flags & MIIF_FORCEANEG))
			(void) mii_phy_auto(sc, 1);
		return;
	}

	/*
	 * Table index is stored in the media entry.
	 */
#ifdef DIAGNOSTIC
	if (ife->ifm_data < 0 || ife->ifm_data >= MII_NMEDIA)
		panic("mii_phy_setmedia");
#endif

	anar = mii_media_table[ife->ifm_data].mm_anar;
	bmcr = mii_media_table[ife->ifm_data].mm_bmcr;
	gtcr = mii_media_table[ife->ifm_data].mm_gtcr;

	if (mii->mii_media.ifm_media & IFM_ETH_MASTER) {
		switch (IFM_SUBTYPE(ife->ifm_media)) {
		case IFM_1000_T:
			gtcr |= GTCR_MAN_MS|GTCR_ADV_MS;
			break;

		default:
			panic("mii_phy_setmedia: MASTER on wrong media");
		}
	}

	if (ife->ifm_media & IFM_LOOP)
		bmcr |= BMCR_LOOP;

	PHY_WRITE(sc, MII_ANAR, anar);
	PHY_WRITE(sc, MII_BMCR, bmcr);
	if (sc->mii_flags & MIIF_HAVE_GTCR)
		PHY_WRITE(sc, MII_100T2CR, gtcr);
}
Example #28
0
static int
le_pci_mediachange(struct lance_softc *sc)
{
	struct ifmedia *ifm = &sc->sc_media;
	uint16_t reg;

	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
		return (EINVAL);

	if (IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1)
		le_pci_wrbcr(sc, LE_BCR49,
		    (le_pci_rdbcr(sc, LE_BCR49) & ~LE_B49_PHYSEL) | 0x1);
	else if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
		le_pci_wrbcr(sc, LE_BCR2,
		    le_pci_rdbcr(sc, LE_BCR2) | LE_B2_ASEL);
	else {
		le_pci_wrbcr(sc, LE_BCR2,
		    le_pci_rdbcr(sc, LE_BCR2) & ~LE_B2_ASEL);

		reg = le_pci_rdcsr(sc, LE_CSR15);
		reg &= ~LE_C15_PORTSEL(LE_PORTSEL_MASK);
		if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T)
			reg |= LE_C15_PORTSEL(LE_PORTSEL_10T);
		else
			reg |= LE_C15_PORTSEL(LE_PORTSEL_AUI);
		le_pci_wrcsr(sc, LE_CSR15, reg);
	}

	reg = le_pci_rdbcr(sc, LE_BCR9);
	if (IFM_OPTIONS(ifm->ifm_media) & IFM_FDX) {
		reg |= LE_B9_FDEN;
		/*
		 * Allow FDX on AUI only if explicitly chosen,
		 * not in autoselect mode.
		 */
		if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_5)
			reg |= LE_B9_AUIFD;
		else
			reg &= ~LE_B9_AUIFD;
	} else
		reg &= ~LE_B9_FDEN;
	le_pci_wrbcr(sc, LE_BCR9, reg);

	return (0);
}
Example #29
0
static int
jmphy_setmedia(struct mii_softc *sc, struct ifmedia_entry *ife)
{
	uint16_t anar, bmcr, gig;

	gig = 0;
	bmcr = PHY_READ(sc, MII_BMCR);
	switch (IFM_SUBTYPE(ife->ifm_media)) {
	case IFM_AUTO:
		gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX;
		break;
	case IFM_1000_T:
		gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX;
		break;
	case IFM_100_TX:
	case IFM_10_T:
		break;
	case IFM_NONE:
		PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_ISO | BMCR_PDOWN);
		return (EJUSTRETURN);
	default:
		return (EINVAL);
	}

	anar = jmphy_anar(ife);
	if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO ||
	    (ife->ifm_media & IFM_FDX) != 0) &&
	    ((ife->ifm_media & IFM_FLOW) != 0 ||
	    (sc->mii_flags & MIIF_FORCEPAUSE) != 0))
		anar |= ANAR_PAUSE_TOWARDS;

	if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) {
		if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
			gig |= GTCR_MAN_MS;
			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
				gig |= GTCR_ADV_MS;
		}
		PHY_WRITE(sc, MII_100T2CR, gig);
	}
	PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA);
	PHY_WRITE(sc, MII_BMCR, bmcr | BMCR_AUTOEN | BMCR_STARTNEG);

	return (EJUSTRETURN);
}
Example #30
0
int
rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;

	/*
	 * Can't isolate the RTL8139 phy, so it has to be the only one.
	 */
	if (IFM_INST(ife->ifm_media) != sc->mii_inst)
		panic("rlphy_service: attempt to isolate phy");

	switch (cmd) {
	case MII_POLLSTAT:
		break;

	case MII_MEDIACHG:
		/*
		 * If the interface is not up, don't do anything.
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			break;

		mii_phy_setmedia(sc);
		break;

	case MII_TICK:
		/*
		 * Is the interface even up?
		 */
		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
			return (0);

		/*
		 * Only used for autonegotiation.
		 */
		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
			break;

		/*
		 * The RealTek PHY's autonegotiation doesn't need to be
		 * kicked; it continues in the background.
		 */
		break;

	case MII_DOWN:
		mii_phy_down(sc);
		return (0);
	}

	/* Update the media status. */
	mii_phy_status(sc);

	/* Callback if something changed. */
	mii_phy_update(sc, cmd);
	return (0);
}