Esempio n. 1
0
void __mii_init(void)
{
	FEC_INFO_T *info;
	volatile FEC_T *fecp;
	struct eth_device *dev;
	int miispd = 0, i = 0;
	u16 status = 0;
	u16 linkgood = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	fecp = (FEC_T *) info->miibase;

	fecpin_setclear(dev, 1);

	mii_reset(info);

	/* We use strictly polling mode only */
	fecp->eimr = 0;

	/* Clear any pending interrupt */
	fecp->eir = 0xffffffff;

	/* Set MII speed */
	miispd = (gd->bus_clk / 1000000) / 5;
	fecp->mscr = miispd << 1;

	info->phy_addr = mii_discover_phy(dev);

	while (i < MCFFEC_TOUT_LOOP) {
		status = 0;
		i++;
		/* Read PHY control register */
		miiphy_read(dev->name, info->phy_addr, MII_BMCR, &status);

		/* If phy set to autonegotiate, wait for autonegotiation done,
		 * if phy is not autonegotiating, just wait for link up.
		 */
		if ((status & BMCR_ANENABLE) == BMCR_ANENABLE) {
			linkgood = (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
		} else {
			linkgood = BMSR_LSTATUS;
		}
		/* Read PHY status register */
		miiphy_read(dev->name, info->phy_addr, MII_BMSR, &status);
		if ((status & linkgood) == linkgood)
			break;

		udelay(1);
	}
	if (i >= MCFFEC_TOUT_LOOP) {
		printf("Link UP timeout\n");
	}

	/* adapt to the duplex and speed settings of the phy */
	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}
Esempio n. 2
0
void __mii_init(void)
{
	volatile fec_t *fecp;
	struct fec_info_s *info;
	struct eth_device *dev;
	int miispd = 0, i = 0;
	u16 autoneg = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	fecp = (fec_t *) info->miibase;

	fecpin_setclear(dev, 1);

	mii_reset(info);

	/* We use strictly polling mode only */
	fecp->eimr = 0;

	/* Clear any pending interrupt */
	fecp->eir = 0xffffffff;

	/* Set MII speed */
	miispd = (gd->bus_clk / 1000000) / 5;
	fecp->mscr = miispd << 1;

	info->phy_addr = mii_discover_phy(dev);

#define AUTONEGLINK		(PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)
	while (i < MCFFEC_TOUT_LOOP) {
		autoneg = 0;
		miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &autoneg);
		i++;

		if ((autoneg & AUTONEGLINK) == AUTONEGLINK)
			break;

		udelay(500);
	}
	if (i >= MCFFEC_TOUT_LOOP) {
		printf("Auto Negotiation not complete\n");
	}

	/* adapt to the half/full speed settings */
	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}
Esempio n. 3
0
void __mii_init(void)
{
	FEC_INFO_T *info;
	volatile FEC_T *fecp;
	struct eth_device *dev;
	int miispd = 0, i = 0;
	u16 status = 0;
	u16 linkgood = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	fecp = (FEC_T *) info->miibase;

	fecpin_setclear(dev, 1);

	mii_reset(info);

	/* We use strictly polling mode only */
	fecp->eimr = 0;

	/* Clear any pending interrupt */
	fecp->eir = 0xffffffff;

	/* Set MII speed */
#ifdef CONFIG_M68K
	miispd = (gd->bus_clk / 1000000) / 5;
#else
	/*
	 * The MSCR[MII_SPEED] bit field is minus 1 encoded.
	 *
	 * We round the value in MSCR[MII_SPEED] up, so that the MDC frequency
	 * never exceeds CONFIG_MCFFEC_MII_SPEED_LIMIT.
	 */
	miispd =
		(CONFIG_MCFFEC_MAC_CLK - 1) /
		(2 * CONFIG_MCFFEC_MII_SPEED_LIMIT);
#endif /* CONFIG_M68K */
	if (miispd > MCFFEC_MII_SPEED_MAX)
		miispd = MCFFEC_MII_SPEED_MAX;

	fecp->mscr = miispd << 1;

	info->phy_addr = mii_discover_phy(dev);

	while (i < MCFFEC_TOUT_LOOP) {
		status = 0;
		i++;
		/* Read PHY control register */
		miiphy_read(dev->name, info->phy_addr, PHY_BMCR, &status);

		/* If phy set to autonegotiate, wait for autonegotiation done,
		 * if phy is not autonegotiating, just wait for link up.
		 */
		if ((status & PHY_BMCR_AUTON) == PHY_BMCR_AUTON) {
			linkgood = (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS);
		} else {
			linkgood = PHY_BMSR_LS;
		}
		/* Read PHY status register */
		miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &status);
		if ((status & linkgood) == linkgood)
			break;

		udelay(1);
	}
	if (i >= MCFFEC_TOUT_LOOP) {
		printf("Link UP timeout\n");
	}

	/* adapt to the duplex and speed settings of the phy */
	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}
Esempio n. 4
0
/*
 * MII device/info/read/write
 *
 * Syntax:
 *  mii device {devname}
 *  mii info   {addr}
 *  mii read   {addr} {reg}
 *  mii write  {addr} {reg} {data}
 */
int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char		op;
	unsigned char	addr, reg;
	unsigned short	data;
	int		rcode = 0;
	char		*devname;

	if (argc < 2) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

#if defined(CONFIG_8xx) || defined(CONFIG_MCF52x2)
	mii_init ();
#endif

	/*
	 * We use the last specified parameters, unless new ones are
	 * entered.
	 */
	op   = last_op;
	addr = last_addr;
	data = last_data;
	reg  = last_reg;

	if ((flag & CMD_FLAG_REPEAT) == 0) {
		op = argv[1][0];
		if (argc >= 3)
			addr = simple_strtoul (argv[2], NULL, 16);
		if (argc >= 4)
			reg  = simple_strtoul (argv[3], NULL, 16);
		if (argc >= 5)
			data = simple_strtoul (argv[4], NULL, 16);
	}

	/* use current device */
	devname = miiphy_get_current_dev();

	/*
	 * check device/read/write/list.
	 */
	if (op == 'i') {
		unsigned char j, start, end;
		unsigned int oui;
		unsigned char model;
		unsigned char rev;

		/*
		 * Look for any and all PHYs.  Valid addresses are 0..31.
		 */
		if (argc >= 3) {
			start = addr; end = addr + 1;
		} else {
			start = 0; end = 31;
		}

		for (j = start; j < end; j++) {
			if (miiphy_info (devname, j, &oui, &model, &rev) == 0) {
				printf ("PHY 0x%02X: "
					"OUI = 0x%04X, "
					"Model = 0x%02X, "
					"Rev = 0x%02X, "
					"%3dbase%s, %s\n",
					j, oui, model, rev,
					miiphy_speed (devname, j),
					miiphy_is_1000base_x (devname, j)
						? "X" : "T",
					(miiphy_duplex (devname, j) == FULL)
						? "FDX" : "HDX");
			}
		}
	} else if (op == 'r') {
		if (miiphy_read (devname, addr, reg, &data) != 0) {
			puts ("Error reading from the PHY\n");
			rcode = 1;
		} else {
			printf ("%04X\n", data & 0x0000FFFF);
		}
	} else if (op == 'w') {
		if (miiphy_write (devname, addr, reg, data) != 0) {
			puts ("Error writing to the PHY\n");
			rcode = 1;
		}
	} else if (op == 'd') {
		if (argc == 2)
			miiphy_listdev ();
		else
			miiphy_set_current_dev (argv[2]);
	} else {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	/*
	 * Save the parameters for repeats.
	 */
	last_op = op;
	last_addr = addr;
	last_data = data;
	last_reg = reg;

	return rcode;
}
Esempio n. 5
0
/**
 * Start the FEC engine
 * @param[in] dev Our device to handle
 */
static int fec_open(struct eth_device *edev)
{
	struct fec_priv *fec = (struct fec_priv *)edev->priv;

	debug("fec_open: fec_open(dev)\n");
	/* full-duplex, heartbeat disabled */
	writel(1 << 2, &fec->eth->x_cntrl);
	fec->rbd_index = 0;

#if defined(CONFIG_MX6Q)
	/* Enable ENET HW endian SWAP */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
		&fec->eth->ecntrl);
	/* Enable ENET store and forward mode */
	writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
		&fec->eth->x_wmrk);
#endif
	/*
	 * Enable FEC-Lite controller
	 */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
		&fec->eth->ecntrl);
#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
	udelay(100);
	/*
	 * setup the MII gasket for RMII mode
	 */

	/* disable the gasket */
	writew(0, &fec->eth->miigsk_enr);

	/* wait for the gasket to be disabled */
	while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
		udelay(2);

	/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
	writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);

	/* re-enable the gasket */
	writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);

	/* wait until MII gasket is ready */
	int max_loops = 10;
	while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
		if (--max_loops <= 0) {
			printf("WAIT for MII Gasket ready timed out\n");
			break;
		}
	}
#endif

	miiphy_wait_aneg(edev);
	miiphy_speed(edev->name, fec->phy_id);
	miiphy_duplex(edev->name, fec->phy_id);

	/*
	 * Enable SmartDMA receive task
	 */
	fec_rx_task_enable(fec);

	udelay(100000);
	return 0;
}
/**
 * Start the FEC engine
 * @param[in] dev Our device to handle
 */
static int fec_open(struct eth_device *edev)
{
	struct fec_priv *fec = (struct fec_priv *)edev->priv;
	int speed;
	uint32_t addr, size;
	int i;

	debug("fec_open: fec_open(dev)\n");
	/* full-duplex, heartbeat disabled */
	writel(1 << 2, &fec->eth->x_cntrl);
	fec->rbd_index = 0;

	/* Invalidate all descriptors */
	for (i = 0; i < FEC_RBD_NUM - 1; i++)
		fec_rbd_clean(0, &fec->rbd_base[i]);
	fec_rbd_clean(1, &fec->rbd_base[i]);

	/* Flush the descriptors into RAM */
	size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
			ARCH_DMA_MINALIGN);
	addr = (uint32_t)fec->rbd_base;
	flush_dcache_range(addr, addr + size);

#ifdef FEC_QUIRK_ENET_MAC
	/* Enable ENET HW endian SWAP */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
		&fec->eth->ecntrl);
	/* Enable ENET store and forward mode */
	writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
		&fec->eth->x_wmrk);
#endif
	/*
	 * Enable FEC-Lite controller
	 */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
		&fec->eth->ecntrl);
#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
	udelay(100);
	/*
	 * setup the MII gasket for RMII mode
	 */

	/* disable the gasket */
	writew(0, &fec->eth->miigsk_enr);

	/* wait for the gasket to be disabled */
	while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
		udelay(2);

	/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
	writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);

	/* re-enable the gasket */
	writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);

	/* wait until MII gasket is ready */
	int max_loops = 10;
	while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
		if (--max_loops <= 0) {
			printf("WAIT for MII Gasket ready timed out\n");
			break;
		}
	}
#endif

#ifdef CONFIG_PHYLIB
	{
		/* Start up the PHY */
		int ret = phy_startup(fec->phydev);

		if (ret) {
			printf("Could not initialize PHY %s\n",
			       fec->phydev->dev->name);
			return ret;
		}
		speed = fec->phydev->speed;
	}
#elif CONFIG_FEC_FIXED_SPEED
	speed = CONFIG_FEC_FIXED_SPEED;
#else
	miiphy_wait_aneg(edev);
	speed = miiphy_speed(edev->name, fec->phy_id);
	miiphy_duplex(edev->name, fec->phy_id);
#endif

#ifdef FEC_QUIRK_ENET_MAC
	{
		u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
		u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
		if (speed == _1000BASET)
			ecr |= FEC_ECNTRL_SPEED;
		else if (speed != _100BASET)
			rcr |= FEC_RCNTRL_RMII_10T;
		writel(ecr, &fec->eth->ecntrl);
		writel(rcr, &fec->eth->r_cntrl);
	}
#endif
	debug("%s:Speed=%i\n", __func__, speed);

	/*
	 * Enable SmartDMA receive task
	 */
	fec_rx_task_enable(fec);

	udelay(100000);
	return 0;
}
Esempio n. 7
0
/**
 * Start the FEC engine
 * @param[in] dev Our device to handle
 */
static int fec_open(struct eth_device *edev)
{
	struct fec_priv *fec = (struct fec_priv *)edev->priv;
	int speed;

	debug("fec_open: fec_open(dev)\n");
	/* full-duplex, heartbeat disabled */
	writel(1 << 2, &fec->eth->x_cntrl);
	fec->rbd_index = 0;

#ifdef FEC_QUIRK_ENET_MAC
	/* Enable ENET HW endian SWAP */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
		&fec->eth->ecntrl);
	/* Enable ENET store and forward mode */
	writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
		&fec->eth->x_wmrk);
#endif
	/*
	 * Enable FEC-Lite controller
	 */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
		&fec->eth->ecntrl);
#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
	udelay(100);
	/*
	 * setup the MII gasket for RMII mode
	 */

	/* disable the gasket */
	writew(0, &fec->eth->miigsk_enr);

	/* wait for the gasket to be disabled */
	while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
		udelay(2);

	/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
	writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);

	/* re-enable the gasket */
	writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);

	/* wait until MII gasket is ready */
	int max_loops = 10;
	while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
		if (--max_loops <= 0) {
			printf("WAIT for MII Gasket ready timed out\n");
			break;
		}
	}
#endif

#ifdef CONFIG_PHYLIB
	if (!fec->phydev)
		fec_eth_phy_config(edev);
	if (fec->phydev) {
		/* Start up the PHY */
		phy_startup(fec->phydev);
		speed = fec->phydev->speed;
	} else {
		speed = _100BASET;
	}
#else
	miiphy_wait_aneg(edev);
	speed = miiphy_speed(edev->name, fec->phy_id);
	miiphy_duplex(edev->name, fec->phy_id);
#endif

#ifdef FEC_QUIRK_ENET_MAC
	{
		u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
		u32 rcr = (readl(&fec->eth->r_cntrl) &
				~(FEC_RCNTRL_RMII | FEC_RCNTRL_RMII_10T)) |
				FEC_RCNTRL_RGMII | FEC_RCNTRL_MII_MODE;
		if (speed == _1000BASET)
			ecr |= FEC_ECNTRL_SPEED;
		else if (speed != _100BASET)
			rcr |= FEC_RCNTRL_RMII_10T;
		writel(ecr, &fec->eth->ecntrl);
		writel(rcr, &fec->eth->r_cntrl);
	}
#endif
	debug("%s:Speed=%i\n", __func__, speed);

	/*
	 * Enable SmartDMA receive task
	 */
	fec_rx_task_enable(fec);

	udelay(100000);
	return 0;
}