Beispiel #1
0
/*
 * Clock a series of bits through the MII.
 */
void
ste_mii_send(struct ste_softc *sc, u_int32_t bits, int cnt)
{
	int		i;

	MII_CLR(STE_PHYCTL_MCLK);

	for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
                if (bits & i) {
			MII_SET(STE_PHYCTL_MDATA);
                } else {
			MII_CLR(STE_PHYCTL_MDATA);
                }
		DELAY(1);
		MII_CLR(STE_PHYCTL_MCLK);
		DELAY(1);
		MII_SET(STE_PHYCTL_MCLK);
	}
}
Beispiel #2
0
/*
 * Write to a PHY register through the MII.
 */
int
ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame)
{
	int		s;

	s = splnet();
	/*
	 * Set up frame for TX.
	 */

	frame->mii_stdelim = STE_MII_STARTDELIM;
	frame->mii_opcode = STE_MII_WRITEOP;
	frame->mii_turnaround = STE_MII_TURNAROUND;
	
	/*
 	 * Turn on data output.
	 */
	MII_SET(STE_PHYCTL_MDIR);

	ste_mii_sync(sc);

	ste_mii_send(sc, frame->mii_stdelim, 2);
	ste_mii_send(sc, frame->mii_opcode, 2);
	ste_mii_send(sc, frame->mii_phyaddr, 5);
	ste_mii_send(sc, frame->mii_regaddr, 5);
	ste_mii_send(sc, frame->mii_turnaround, 2);
	ste_mii_send(sc, frame->mii_data, 16);

	/* Idle bit. */
	MII_SET(STE_PHYCTL_MCLK);
	DELAY(1);
	MII_CLR(STE_PHYCTL_MCLK);
	DELAY(1);

	/*
	 * Turn off xmit.
	 */
	MII_CLR(STE_PHYCTL_MDIR);

	splx(s);

	return(0);
}
Beispiel #3
0
/*
 * Clock a series of bits through the MII.
 */
static void
rtk_mii_send(struct rtk_softc *sc, uint32_t bits, int cnt)
{
	int i;

	MII_CLR(RTK_MII_CLK);

	for (i = cnt; i > 0; i--) {
		if (bits & (1 << (i - 1))) {
			MII_SET(RTK_MII_DATAOUT);
		} else {
			MII_CLR(RTK_MII_DATAOUT);
		}
		DELAY(1);
		MII_CLR(RTK_MII_CLK);
		DELAY(1);
		MII_SET(RTK_MII_CLK);
	}
}
Beispiel #4
0
/*
 * Sync the PHYs by setting data bit and strobing the clock 32 times.
 */
void
ste_mii_sync(struct ste_softc *sc)
{
	int		i;

	MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA);

	for (i = 0; i < 32; i++) {
		MII_SET(STE_PHYCTL_MCLK);
		DELAY(1);
		MII_CLR(STE_PHYCTL_MCLK);
		DELAY(1);
	}
}
Beispiel #5
0
/*
 * Sync the PHYs by setting data bit and strobing the clock 32 times.
 */
static void
rtk_mii_sync(struct rtk_softc *sc)
{
	int i;

	MII_SET(RTK_MII_DIR|RTK_MII_DATAOUT);

	for (i = 0; i < 32; i++) {
		MII_SET(RTK_MII_CLK);
		DELAY(1);
		MII_CLR(RTK_MII_CLK);
		DELAY(1);
	}
}
Beispiel #6
0
/*
 * Read an PHY register through the MII.
 */
int
ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame)
{
	int		ack, i, s;

	s = splnet();

	/*
	 * Set up frame for RX.
	 */
	frame->mii_stdelim = STE_MII_STARTDELIM;
	frame->mii_opcode = STE_MII_READOP;
	frame->mii_turnaround = 0;
	frame->mii_data = 0;
	
	CSR_WRITE_2(sc, STE_PHYCTL, 0);
	/*
 	 * Turn on data xmit.
	 */
	MII_SET(STE_PHYCTL_MDIR);

	ste_mii_sync(sc);

	/*
	 * Send command/address info.
	 */
	ste_mii_send(sc, frame->mii_stdelim, 2);
	ste_mii_send(sc, frame->mii_opcode, 2);
	ste_mii_send(sc, frame->mii_phyaddr, 5);
	ste_mii_send(sc, frame->mii_regaddr, 5);

	/* Turn off xmit. */
	MII_CLR(STE_PHYCTL_MDIR);

	/* Idle bit */
	MII_CLR((STE_PHYCTL_MCLK|STE_PHYCTL_MDATA));
	DELAY(1);
	MII_SET(STE_PHYCTL_MCLK);
	DELAY(1);

	/* Check for ack */
	MII_CLR(STE_PHYCTL_MCLK);
	DELAY(1);
	ack = CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA;
	MII_SET(STE_PHYCTL_MCLK);
	DELAY(1);

	/*
	 * Now try reading data bits. If the ack failed, we still
	 * need to clock through 16 cycles to keep the PHY(s) in sync.
	 */
	if (ack) {
		for(i = 0; i < 16; i++) {
			MII_CLR(STE_PHYCTL_MCLK);
			DELAY(1);
			MII_SET(STE_PHYCTL_MCLK);
			DELAY(1);
		}
		goto fail;
	}

	for (i = 0x8000; i; i >>= 1) {
		MII_CLR(STE_PHYCTL_MCLK);
		DELAY(1);
		if (!ack) {
			if (CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA)
				frame->mii_data |= i;
			DELAY(1);
		}
		MII_SET(STE_PHYCTL_MCLK);
		DELAY(1);
	}

fail:

	MII_CLR(STE_PHYCTL_MCLK);
	DELAY(1);
	MII_SET(STE_PHYCTL_MCLK);
	DELAY(1);

	splx(s);

	if (ack)
		return(1);
	return(0);
}
Beispiel #7
0
/*
 * Read an PHY register through the MII.
 */
static int
rtk_mii_readreg(struct rtk_softc *sc, struct rtk_mii_frame *frame)
{
	int i, ack, s;

	s = splnet();

	/*
	 * Set up frame for RX.
	 */
	frame->mii_stdelim = RTK_MII_STARTDELIM;
	frame->mii_opcode = RTK_MII_READOP;
	frame->mii_turnaround = 0;
	frame->mii_data = 0;

	CSR_WRITE_2(sc, RTK_MII, 0);

	/*
	 * Turn on data xmit.
	 */
	MII_SET(RTK_MII_DIR);

	rtk_mii_sync(sc);

	/*
	 * Send command/address info.
	 */
	rtk_mii_send(sc, frame->mii_stdelim, 2);
	rtk_mii_send(sc, frame->mii_opcode, 2);
	rtk_mii_send(sc, frame->mii_phyaddr, 5);
	rtk_mii_send(sc, frame->mii_regaddr, 5);

	/* Idle bit */
	MII_CLR((RTK_MII_CLK|RTK_MII_DATAOUT));
	DELAY(1);
	MII_SET(RTK_MII_CLK);
	DELAY(1);

	/* Turn off xmit. */
	MII_CLR(RTK_MII_DIR);

	/* Check for ack */
	MII_CLR(RTK_MII_CLK);
	DELAY(1);
	ack = CSR_READ_2(sc, RTK_MII) & RTK_MII_DATAIN;
	MII_SET(RTK_MII_CLK);
	DELAY(1);

	/*
	 * Now try reading data bits. If the ack failed, we still
	 * need to clock through 16 cycles to keep the PHY(s) in sync.
	 */
	if (ack) {
		for (i = 0; i < 16; i++) {
			MII_CLR(RTK_MII_CLK);
			DELAY(1);
			MII_SET(RTK_MII_CLK);
			DELAY(1);
		}
		goto fail;
	}

	for (i = 16; i > 0; i--) {
		MII_CLR(RTK_MII_CLK);
		DELAY(1);
		if (!ack) {
			if (CSR_READ_2(sc, RTK_MII) & RTK_MII_DATAIN)
				frame->mii_data |= 1 << (i - 1);
			DELAY(1);
		}
		MII_SET(RTK_MII_CLK);
		DELAY(1);
	}

 fail:
	MII_CLR(RTK_MII_CLK);
	DELAY(1);
	MII_SET(RTK_MII_CLK);
	DELAY(1);

	splx(s);

	if (ack)
		return 1;
	return 0;
}