Exemplo n.º 1
0
static int pic32_eth_start(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct pic32eth_dev *priv = dev_get_priv(dev);

	/* controller */
	pic32_ctrl_reset(priv);

	/* reset MAC */
	pic32_mac_reset(priv);

	/* configure PHY */
	phy_config(priv->phydev);

	/* initialize MAC */
	pic32_mac_init(priv, &pdata->enetaddr[0]);

	/* init RX descriptor; TX descriptors are handled in xmit */
	pic32_rx_desc_init(priv);

	/* Start up & update link status of PHY */
	phy_startup(priv->phydev);

	/* adjust mac with phy link status */
	return pic32_mac_adjust_link(priv);
}
Exemplo n.º 2
0
static int ll_temac_init(struct eth_device *dev, bd_t *bis)
{
	struct ll_temac *ll_temac = dev->priv;
	int ret;

	printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n",
		dev->name, dev->index, dev->iobase);

	if (!ll_temac_setup_ctrl(dev))
		return -1;

	/* Start up the PHY */
	ret = phy_startup(ll_temac->phydev);
	if (ret) {
		printf("%s: Could not initialize PHY %s\n",
		       dev->name, ll_temac->phydev->dev->name);
		return ret;
	}

	if (!ll_temac_adjust_link(dev)) {
		ll_temac_halt(dev);
		return -1;
	}

	/* If there's no link, fail */
	return ll_temac->phydev->link ? 0 : -1;
}
Exemplo n.º 3
0
static int mvneta_start(struct udevice *dev)
{
	struct mvneta_port *pp = dev_get_priv(dev);
	struct phy_device *phydev;

	mvneta_port_power_up(pp, pp->phy_interface);

	if (!pp->init || pp->link == 0) {
		/* Set phy address of the port */
		mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
		phydev = phy_connect(pp->bus, pp->phyaddr, dev,
				     pp->phy_interface);

		pp->phydev = phydev;
		phy_config(phydev);
		phy_startup(phydev);
		if (!phydev->link) {
			printf("%s: No link.\n", phydev->dev->name);
			return -1;
		}

		/* Full init on first call */
		mvneta_init(dev);
		pp->init = 1;
	} else {
		/* Upon all following calls, this is enough */
		mvneta_port_up(pp);
		mvneta_port_enable(pp);
	}

	return 0;
}
Exemplo n.º 4
0
int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
{
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	unsigned int start;
	int ret;

	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);

	start = get_timer(0);
	while (readl(&dma_p->busmode) & DMAMAC_SRST) {
		if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {
			printf("DMA reset timeout\n");
			return -ETIMEDOUT;
		}

		mdelay(100);
	};

	/*
	 * Soft reset above clears HW address registers.
	 * So we have to set it here once again.
	 */
	_dw_write_hwaddr(priv, enetaddr);

	rx_descs_init(priv);
	tx_descs_init(priv);

	writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);

#ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE
	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
	       &dma_p->opmode);
#else
	writel(readl(&dma_p->opmode) | FLUSHTXFIFO,
	       &dma_p->opmode);
#endif

	writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);

#ifdef CONFIG_DW_AXI_BURST_LEN
	writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus);
#endif

	/* Start up the PHY */
	ret = phy_startup(priv->phydev);
	if (ret) {
		printf("Could not initialize PHY %s\n",
		       priv->phydev->dev->name);
		return ret;
	}

	ret = dw_adjust_link(priv, mac_p, priv->phydev);
	if (ret)
		return ret;

	return 0;
}
Exemplo n.º 5
0
static int ks2_eth_start(struct udevice *dev)
{
	struct ks2_eth_priv *priv = dev_get_priv(dev);

#ifdef CONFIG_SOC_K2G
	keystone_rgmii_config(priv->phydev);
#else
	keystone_sgmii_config(priv->phydev, priv->slave_port - 1,
			      priv->sgmii_link_type);
#endif

	udelay(10000);

	/* On chip switch configuration */
	ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);

	qm_init();

	if (ksnav_init(priv->netcp_pktdma, &priv->net_rx_buffs)) {
		error("ksnav_init failed\n");
		goto err_knav_init;
	}

	/*
	 * Streaming switch configuration. If not present this
	 * statement is defined to void in target.h.
	 * If present this is usually defined to a series of register writes
	 */
	hw_config_streaming_switch();

	if (priv->has_mdio) {
		keystone2_mdio_reset(priv->mdio_bus);

		phy_startup(priv->phydev);
		if (priv->phydev->link == 0) {
			error("phy startup failed\n");
			goto err_phy_start;
		}
	}

	emac_gigabit_enable(dev);

	ethss_start();

	priv->emac_open = true;

	return 0;

err_phy_start:
	ksnav_close(priv->netcp_pktdma);
err_knav_init:
	qm_close();

	return -EFAULT;
}
Exemplo n.º 6
0
static int fm_eth_open(struct eth_device *dev, bd_t *bd)
{
	struct fm_eth *fm_eth;
	struct fsl_enet_mac *mac;
#ifdef CONFIG_PHYLIB
	int ret;
#endif

	fm_eth = (struct fm_eth *)dev->priv;
	mac = fm_eth->mac;

	/* setup the MAC address */
	if (dev->enetaddr[0] & 0x01) {
		printf("%s: MacAddress is multcast address\n",	__func__);
		return 1;
	}
	mac->set_mac_addr(mac, dev->enetaddr);

	/* enable bmi Rx port */
	setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN);
	/* enable MAC rx/tx port */
	mac->enable_mac(mac);
	/* enable bmi Tx port */
	setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN);
	/* re-enable transmission of frame */
	fmc_tx_port_graceful_stop_disable(fm_eth);

#ifdef CONFIG_PHYLIB
	if (fm_eth->phydev) {
		ret = phy_startup(fm_eth->phydev);
		if (ret) {
			printf("%s: Could not initialize\n",
			       fm_eth->phydev->dev->name);
			return ret;
		}
	} else {
		return 0;
	}
#else
	fm_eth->phydev->speed = SPEED_1000;
	fm_eth->phydev->link = 1;
	fm_eth->phydev->duplex = DUPLEX_FULL;
#endif

	/* set the MAC-PHY mode */
	mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed);

	if (!fm_eth->phydev->link)
		printf("%s: No link.\n", fm_eth->phydev->dev->name);

	return fm_eth->phydev->link ? 0 : -1;
}
Exemplo n.º 7
0
/* Setting axi emac and phy to proper setting */
static int setup_phy(struct udevice *dev)
{
	u32 speed, emmc_reg;
	struct axidma_priv *priv = dev_get_priv(dev);
	struct axi_regs *regs = priv->iobase;
	struct phy_device *phydev = priv->phydev;

	if (phy_startup(phydev)) {
		printf("axiemac: could not initialize PHY %s\n",
		       phydev->dev->name);
		return 0;
	}
	if (!phydev->link) {
		printf("%s: No link.\n", phydev->dev->name);
		return 0;
	}

	switch (phydev->speed) {
	case 1000:
		speed = XAE_EMMC_LINKSPD_1000;
		break;
	case 100:
		speed = XAE_EMMC_LINKSPD_100;
		break;
	case 10:
		speed = XAE_EMMC_LINKSPD_10;
		break;
	default:
		return 0;
	}

	/* Setup the emac for the phy speed */
	emmc_reg = in_be32(&regs->emmc);
	emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
	emmc_reg |= speed;

	/* Write new speed setting out to Axi Ethernet */
	out_be32(&regs->emmc, emmc_reg);

	/*
	* Setting the operating speed of the MAC needs a delay. There
	* doesn't seem to be register to poll, so please consider this
	* during your application design.
	*/
	udelay(1);

	return 1;
}
Exemplo n.º 8
0
static int dw_eth_init(struct eth_device *dev, bd_t *bis)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	unsigned int start;

	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);

	start = get_timer(0);
	while (readl(&dma_p->busmode) & DMAMAC_SRST) {
		if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT)
			return -1;

		mdelay(100);
	};

	/* Soft reset above clears HW address registers.
	 * So we have to set it here once again */
	dw_write_hwaddr(dev);

	rx_descs_init(dev);
	tx_descs_init(dev);

	writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);

	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
	       &dma_p->opmode);

	writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);

	/* Start up the PHY */
	if (phy_startup(priv->phydev)) {
		printf("Could not initialize PHY %s\n",
		       priv->phydev->dev->name);
		return -1;
	}

	dw_adjust_link(mac_p, priv->phydev);

	if (!priv->phydev->link)
		return -1;

	writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);

	return 0;
}
Exemplo n.º 9
0
static int altera_tse_start(struct udevice *dev)
{
	struct altera_tse_priv *priv = dev_get_priv(dev);
	struct alt_tse_mac *mac_dev = priv->mac_dev;
	u32 val;
	int ret;

	/* need to create sgdma */
	debug("Configuring rx desc\n");
	altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN);
	/* start TSE */
	debug("Configuring TSE Mac\n");
	/* Initialize MAC registers */
	writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length);
	writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold);
	writel(0, &mac_dev->rx_sel_full_threshold);
	writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold);
	writel(0, &mac_dev->tx_sel_full_threshold);
	writel(8, &mac_dev->rx_almost_empty_threshold);
	writel(8, &mac_dev->rx_almost_full_threshold);
	writel(8, &mac_dev->tx_almost_empty_threshold);
	writel(3, &mac_dev->tx_almost_full_threshold);

	/* NO Shift */
	writel(0, &mac_dev->rx_cmd_stat);
	writel(0, &mac_dev->tx_cmd_stat);

	/* enable MAC */
	val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK;
	writel(val, &mac_dev->command_config);

	/* Start up the PHY */
	ret = phy_startup(priv->phydev);
	if (ret) {
		debug("Could not initialize PHY %s\n",
		      priv->phydev->dev->name);
		return ret;
	}

	tse_adjust_link(priv, priv->phydev);

	if (!priv->phydev->link)
		return -EIO;

	return 0;
}
Exemplo n.º 10
0
/* Initializes data structures and registers for the controller,
 * and brings the interface up.	 Returns the link status, meaning
 * that it returns success if the link is up, failure otherwise.
 * This allows u-boot to find the first active controller.
 */
static int tsec_init(struct eth_device *dev, bd_t * bd)
{
	uint tempval;
	char tmpbuf[MAC_ADDR_LEN];
	int i;
	struct tsec_private *priv = (struct tsec_private *)dev->priv;
	tsec_t *regs = priv->regs;

	/* Make sure the controller is stopped */
	tsec_halt(dev);

	/* Init MACCFG2.  Defaults to GMII */
	out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);

	/* Init ECNTRL */
	out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);

	/* Copy the station address into the address registers.
	 * Backwards, because little endian MACS are dumb */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];

	tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) |
		  tmpbuf[3];

	out_be32(&regs->macstnaddr1, tempval);

	tempval = *((uint *) (tmpbuf + 4));

	out_be32(&regs->macstnaddr2, tempval);

	/* Clear out (for the most part) the other registers */
	init_registers(regs);

	/* Ready the device for tx/rx */
	startup_tsec(dev);

	/* Start up the PHY */
	phy_startup(priv->phydev);

	adjust_link(priv, priv->phydev);

	/* If there's no link, fail */
	return priv->phydev->link ? 0 : -1;
}
Exemplo n.º 11
0
static int bcm_sf2_eth_open(struct eth_device *dev, bd_t *bt)
{
	struct eth_info *eth = (struct eth_info *)(dev->priv);
	struct eth_dma *dma = &(eth->dma);
	int i;

	debug("Enabling BCM SF2 Ethernet.\n");

	/* Set MAC address from env */
	if (bcm_sf2_eth_write_hwaddr(dev) != 0) {
		error("%s: MAC set error when opening !\n", __func__);
		return -1;
	}

	eth->enable_mac();

	/* enable tx and rx DMA */
	dma->enable_dma(dma, MAC_DMA_RX);
	dma->enable_dma(dma, MAC_DMA_TX);

	/*
	 * Need to start PHY here because link speed can change
	 * before each ethernet operation
	 */
	for (i = 0; i < eth->port_num; i++) {
		if (phy_startup(eth->port[i])) {
			error("%s: PHY %d startup failed!\n", __func__, i);
			if (i == CONFIG_BCM_SF2_ETH_DEFAULT_PORT) {
				error("%s: No default port %d!\n", __func__, i);
				return -1;
			}
		}
	}

	/* Set MAC speed using default port */
	i = CONFIG_BCM_SF2_ETH_DEFAULT_PORT;
	debug("PHY %d: speed:%d, duplex:%d, link:%d\n", i,
	      eth->port[i]->speed, eth->port[i]->duplex, eth->port[i]->link);
	eth->set_mac_speed(eth->port[i]->speed, eth->port[i]->duplex);

	debug("Enable Ethernet Done.\n");

	return 0;
}
Exemplo n.º 12
0
static int pch_gbe_start(struct udevice *dev)
{
	struct pch_gbe_priv *priv = dev_get_priv(dev);
	struct pch_gbe_regs *mac_regs = priv->mac_regs;

	if (pch_gbe_reset(dev))
		return -1;

	pch_gbe_rx_descs_init(dev);
	pch_gbe_tx_descs_init(dev);

	/* Enable frame bursting */
	writel(PCH_GBE_MODE_FR_BST, &mac_regs->mode);
	/* Disable TCP/IP accelerator */
	writel(PCH_GBE_RX_TCPIPACC_OFF, &mac_regs->tcpip_acc);
	/* Disable RX flow control */
	writel(0, &mac_regs->rx_fctrl);
	/* Configure RX/TX mode */
	writel(PCH_GBE_RH_ALM_EMP_16 | PCH_GBE_RH_ALM_FULL_16 |
	       PCH_GBE_RH_RD_TRG_32, &mac_regs->rx_mode);
	writel(PCH_GBE_TM_TH_TX_STRT_32 | PCH_GBE_TM_TH_ALM_EMP_16 |
	       PCH_GBE_TM_TH_ALM_FULL_32 | PCH_GBE_TM_ST_AND_FD |
	       PCH_GBE_TM_SHORT_PKT, &mac_regs->tx_mode);

	/* Start up the PHY */
	if (phy_startup(priv->phydev)) {
		printf("Could not initialize PHY %s\n",
		       priv->phydev->dev->name);
		return -1;
	}

	pch_gbe_adjust_link(mac_regs, priv->phydev);

	if (!priv->phydev->link)
		return -1;

	/* Enable TX & RX */
	writel(PCH_GBE_RX_DMA_EN | PCH_GBE_TX_DMA_EN, &mac_regs->dma_ctrl);
	writel(PCH_GBE_MRE_MAC_RX_EN, &mac_regs->mac_rx_en);

	return 0;
}
Exemplo n.º 13
0
static int ethoc_init_common(struct ethoc *priv)
{
	int ret = 0;

	priv->num_tx = 1;
	priv->num_rx = PKTBUFSRX;
	ethoc_write(priv, TX_BD_NUM, priv->num_tx);
	ethoc_init_ring(priv);
	ethoc_reset(priv);

#ifdef CONFIG_PHYLIB
	ret = phy_startup(priv->phydev);
	if (ret) {
		printf("Could not initialize PHY %s\n",
		       priv->phydev->dev->name);
		return ret;
	}
#endif
	return ret;
}
Exemplo n.º 14
0
int mvgbe_phylib_init(struct eth_device *dev, int phyid)
{
	struct mii_dev *bus;
	struct phy_device *phydev;
	int ret;

	bus = mdio_alloc();
	if (!bus) {
		printf("mdio_alloc failed\n");
		return -ENOMEM;
	}
	bus->read = mvgbe_phy_read;
	bus->write = mvgbe_phy_write;
	sprintf(bus->name, dev->name);

	ret = mdio_register(bus);
	if (ret) {
		printf("mdio_register failed\n");
		free(bus);
		return -ENOMEM;
	}

	/* Set phy address of the port */
	mvgbe_phy_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);

	phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
	if (!phydev) {
		printf("phy_connect failed\n");
		return -ENODEV;
	}

	phy_config(phydev);
	phy_startup(phydev);

	return 0;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
{
	int port = eth->port, ret = 0;
	u32 val;
	struct sh_eth_info *port_info = &eth->port_info[port];
	struct eth_device *dev = port_info->dev;
	struct phy_device *phy;

	/* Configure e-dmac registers */
	sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | EDMR_EL,
		     EDMR);
	sh_eth_write(eth, 0, EESIPR);
	sh_eth_write(eth, 0, TRSCER);
	sh_eth_write(eth, 0, TFTR);
	sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR);
	sh_eth_write(eth, RMCR_RST, RMCR);
#if defined(SH_ETH_TYPE_GETHER)
	sh_eth_write(eth, 0, RPADIR);
#endif
	sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR);

	/* Configure e-mac registers */
	sh_eth_write(eth, 0, ECSIPR);

	/* Set Mac address */
	val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 |
	    dev->enetaddr[2] << 8 | dev->enetaddr[3];
	sh_eth_write(eth, val, MAHR);

	val = dev->enetaddr[4] << 8 | dev->enetaddr[5];
	sh_eth_write(eth, val, MALR);

	sh_eth_write(eth, RFLR_RFL_MIN, RFLR);
#if defined(SH_ETH_TYPE_GETHER)
	sh_eth_write(eth, 0, PIPR);
	sh_eth_write(eth, APR_AP, APR);
	sh_eth_write(eth, MPR_MP, MPR);
	sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER);
#endif

#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740)
	sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII);
#endif
	/* Configure phy */
	ret = sh_eth_phy_config(eth);
	if (ret) {
		printf(SHETHER_NAME ": phy config timeout\n");
		goto err_phy_cfg;
	}
	phy = port_info->phydev;
	ret = phy_startup(phy);
	if (ret) {
		printf(SHETHER_NAME ": phy startup failure\n");
		return ret;
	}

	val = 0;

	/* Set the transfer speed */
	if (phy->speed == 100) {
		printf(SHETHER_NAME ": 100Base/");
#if defined(SH_ETH_TYPE_GETHER)
		sh_eth_write(eth, GECMR_100B, GECMR);
#elif defined(CONFIG_CPU_SH7757)
		sh_eth_write(eth, 1, RTRATE);
#elif defined(CONFIG_CPU_SH7724)
		val = ECMR_RTM;
#endif
	} else if (phy->speed == 10) {
		printf(SHETHER_NAME ": 10Base/");
#if defined(SH_ETH_TYPE_GETHER)
		sh_eth_write(eth, GECMR_10B, GECMR);
#elif defined(CONFIG_CPU_SH7757)
		sh_eth_write(eth, 0, RTRATE);
#endif
	}
#if defined(SH_ETH_TYPE_GETHER)
	else if (phy->speed == 1000) {
		printf(SHETHER_NAME ": 1000Base/");
		sh_eth_write(eth, GECMR_1000B, GECMR);
	}
#endif

	/* Check if full duplex mode is supported by the phy */
	if (phy->duplex) {
		printf("Full\n");
		sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM),
			     ECMR);
	} else {
		printf("Half\n");
		sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR);
	}

	return ret;

err_phy_cfg:
	return ret;
}
Exemplo n.º 17
0
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
{
	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
	struct dpni_queue_attr rx_queue_attr;
	uint8_t mac_addr[6];
	int err;

	if (net_dev->state == ETH_STATE_ACTIVE)
		return 0;

	/* DPNI initialization */
	err = ldpaa_dpni_setup(priv);
	if (err < 0)
		goto err_dpni_setup;

	err = ldpaa_dpbp_setup();
	if (err < 0)
		goto err_dpbp_setup;

	/* DPNI binding DPBP */
	err = ldpaa_dpni_bind(priv);
	if (err)
		goto err_bind;

	err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle,
					mac_addr);
	if (err) {
		printf("dpni_get_primary_mac_addr() failed\n");
		return err;
	}

	memcpy(net_dev->enetaddr, mac_addr, 0x6);

	/* setup the MAC address */
	if (net_dev->enetaddr[0] & 0x01) {
		printf("%s: MacAddress is multcast address\n",	__func__);
		return 1;
	}

#ifdef CONFIG_PHYLIB
	/* TODO Check this path */
	err = phy_startup(priv->phydev);
	if (err) {
		printf("%s: Could not initialize\n", priv->phydev->dev->name);
		return err;
	}
#else
	priv->phydev->speed = SPEED_1000;
	priv->phydev->link = 1;
	priv->phydev->duplex = DUPLEX_FULL;
#endif

	err = dpni_enable(dflt_mc_io, priv->dpni_handle);
	if (err < 0) {
		printf("dpni_enable() failed\n");
		return err;
	}

	/* TODO: support multiple Rx flows */
	err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0,
			       &rx_queue_attr);
	if (err) {
		printf("dpni_get_rx_flow() failed\n");
		goto err_rx_flow;
	}

	priv->rx_dflt_fqid = rx_queue_attr.fqid;

	err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid);
	if (err) {
		printf("dpni_get_qdid() failed\n");
		goto err_qdid;
	}

	if (!priv->phydev->link)
		printf("%s: No link.\n", priv->phydev->dev->name);

	return priv->phydev->link ? 0 : -1;

err_qdid:
err_rx_flow:
	dpni_disable(dflt_mc_io, priv->dpni_handle);
err_bind:
	ldpaa_dpbp_free();
err_dpbp_setup:
	dpni_close(dflt_mc_io, priv->dpni_handle);
err_dpni_setup:
	return err;
}
Exemplo n.º 18
0
/* Setting axi emac and phy to proper setting */
static int setup_phy(struct udevice *dev)
{
	u16 temp;
	u32 speed, emmc_reg, ret;
	struct axidma_priv *priv = dev_get_priv(dev);
	struct axi_regs *regs = priv->iobase;
	struct phy_device *phydev = priv->phydev;

	if (priv->interface == PHY_INTERFACE_MODE_SGMII) {
		/*
		 * In SGMII cases the isolate bit might set
		 * after DMA and ethernet resets and hence
		 * check and clear if set.
		 */
		ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp);
		if (ret)
			return 0;
		if (temp & BMCR_ISOLATE) {
			temp &= ~BMCR_ISOLATE;
			ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp);
			if (ret)
				return 0;
		}
	}

	if (phy_startup(phydev)) {
		printf("axiemac: could not initialize PHY %s\n",
		       phydev->dev->name);
		return 0;
	}
	if (!phydev->link) {
		printf("%s: No link.\n", phydev->dev->name);
		return 0;
	}

	switch (phydev->speed) {
	case 1000:
		speed = XAE_EMMC_LINKSPD_1000;
		break;
	case 100:
		speed = XAE_EMMC_LINKSPD_100;
		break;
	case 10:
		speed = XAE_EMMC_LINKSPD_10;
		break;
	default:
		return 0;
	}

	/* Setup the emac for the phy speed */
	emmc_reg = readl(&regs->emmc);
	emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
	emmc_reg |= speed;

	/* Write new speed setting out to Axi Ethernet */
	writel(emmc_reg, &regs->emmc);

	/*
	* Setting the operating speed of the MAC needs a delay. There
	* doesn't seem to be register to poll, so please consider this
	* during your application design.
	*/
	udelay(1);

	return 1;
}
Exemplo n.º 19
0
static int ftgmac100_start(struct udevice *dev)
{
	struct eth_pdata *plat = dev_get_platdata(dev);
	struct ftgmac100_data *priv = dev_get_priv(dev);
	struct ftgmac100 *ftgmac100 = priv->iobase;
	struct phy_device *phydev = priv->phydev;
	unsigned int maccr;
	ulong start, end;
	int ret;
	int i;

	debug("%s()\n", __func__);

	ftgmac100_reset(priv);

	/* set the ethernet address */
	ftgmac100_set_mac(priv, plat->enetaddr);

	/* disable all interrupts */
	writel(0, &ftgmac100->ier);

	/* initialize descriptors */
	priv->tx_index = 0;
	priv->rx_index = 0;

	for (i = 0; i < PKTBUFSTX; i++) {
		priv->txdes[i].txdes3 = 0;
		priv->txdes[i].txdes0 = 0;
	}
	priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;

	start = (ulong)&priv->txdes[0];
	end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN);
	flush_dcache_range(start, end);

	for (i = 0; i < PKTBUFSRX; i++) {
		priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
		priv->rxdes[i].rxdes0 = 0;
	}
	priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;

	start = (ulong)&priv->rxdes[0];
	end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN);
	flush_dcache_range(start, end);

	/* transmit ring */
	writel((u32)priv->txdes, &ftgmac100->txr_badr);

	/* receive ring */
	writel((u32)priv->rxdes, &ftgmac100->rxr_badr);

	/* poll receive descriptor automatically */
	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);

	/* config receive buffer size register */
	writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr);

	/* enable transmitter, receiver */
	maccr = FTGMAC100_MACCR_TXMAC_EN |
		FTGMAC100_MACCR_RXMAC_EN |
		FTGMAC100_MACCR_TXDMA_EN |
		FTGMAC100_MACCR_RXDMA_EN |
		FTGMAC100_MACCR_CRC_APD |
		FTGMAC100_MACCR_FULLDUP |
		FTGMAC100_MACCR_RX_RUNT |
		FTGMAC100_MACCR_RX_BROADPKT;

	writel(maccr, &ftgmac100->maccr);

	ret = phy_startup(phydev);
	if (ret) {
		dev_err(phydev->dev, "Could not start PHY\n");
		return ret;
	}

	ret = ftgmac100_phy_adjust_link(priv);
	if (ret) {
		dev_err(phydev->dev,  "Could not adjust link\n");
		return ret;
	}

	printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name,
	       phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr);

	return 0;
}
Exemplo n.º 20
0
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
{
	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
	struct dpni_queue_attr rx_queue_attr;
	struct dpmac_link_state	dpmac_link_state = { 0 };
#ifdef DEBUG
	struct dpni_link_state link_state;
#endif
	int err = 0;
	struct mii_dev *bus;
	phy_interface_t enet_if;

	if (net_dev->state == ETH_STATE_ACTIVE)
		return 0;

	if (get_mc_boot_status() != 0) {
		printf("ERROR (MC is not booted)\n");
		return -ENODEV;
	}

	if (get_dpl_apply_status() == 0) {
		printf("ERROR (DPL is deployed. No device available)\n");
		return -ENODEV;
	}

	/* DPMAC initialization */
	err = ldpaa_dpmac_setup(priv);
	if (err < 0)
		goto err_dpmac_setup;

#ifdef CONFIG_PHYLIB
	if (priv->phydev)
		err = phy_startup(priv->phydev);
		if (err) {
			printf("%s: Could not initialize\n",
			       priv->phydev->dev->name);
			goto err_dpamc_bind;
		}
#else
	priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
	memset(priv->phydev, 0, sizeof(struct phy_device));

	priv->phydev->speed = SPEED_1000;
	priv->phydev->link = 1;
	priv->phydev->duplex = DUPLEX_FULL;
#endif

	bus = wriop_get_mdio(priv->dpmac_id);
	enet_if = wriop_get_enet_if(priv->dpmac_id);
	if ((bus == NULL) &&
	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
		priv->phydev = (struct phy_device *)
				malloc(sizeof(struct phy_device));
		memset(priv->phydev, 0, sizeof(struct phy_device));

		priv->phydev->speed = SPEED_10000;
		priv->phydev->link = 1;
		priv->phydev->duplex = DUPLEX_FULL;
	}

	if (!priv->phydev->link) {
		printf("%s: No link.\n", priv->phydev->dev->name);
		err = -1;
		goto err_dpamc_bind;
	}

	/* DPMAC binding DPNI */
	err = ldpaa_dpmac_bind(priv);
	if (err)
		goto err_dpamc_bind;

	/* DPNI initialization */
	err = ldpaa_dpni_setup(priv);
	if (err < 0)
		goto err_dpni_setup;

	err = ldpaa_dpbp_setup();
	if (err < 0)
		goto err_dpbp_setup;

	/* DPNI binding DPBP */
	err = ldpaa_dpni_bind(priv);
	if (err)
		goto err_dpni_bind;

	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
				dflt_dpni->dpni_handle, net_dev->enetaddr);
	if (err) {
		printf("dpni_add_mac_addr() failed\n");
		return err;
	}

	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
	if (err < 0) {
		printf("dpni_enable() failed\n");
		return err;
	}

	dpmac_link_state.rate = priv->phydev->speed;

	if (priv->phydev->autoneg == AUTONEG_DISABLE)
		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
	else
		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;

	if (priv->phydev->duplex == DUPLEX_HALF)
		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;

	dpmac_link_state.up = priv->phydev->link;

	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
				  priv->dpmac_handle, &dpmac_link_state);
	if (err < 0) {
		printf("dpmac_set_link_state() failed\n");
		return err;
	}

#ifdef DEBUG
	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
				  dflt_dpni->dpni_handle, &link_state);
	if (err < 0) {
		printf("dpni_get_link_state() failed\n");
		return err;
	}

	printf("link status: %d - ", link_state.up);
	link_state.up == 0 ? printf("down\n") :
	link_state.up == 1 ? printf("up\n") : printf("error state\n");
#endif

	/* TODO: support multiple Rx flows */
	err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
			       dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
	if (err) {
		printf("dpni_get_rx_flow() failed\n");
		goto err_rx_flow;
	}

	priv->rx_dflt_fqid = rx_queue_attr.fqid;

	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
			    &priv->tx_qdid);
	if (err) {
		printf("dpni_get_qdid() failed\n");
		goto err_qdid;
	}

	return priv->phydev->link;

err_qdid:
err_rx_flow:
	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
err_dpni_bind:
	ldpaa_dpbp_free();
err_dpbp_setup:
	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
err_dpni_setup:
err_dpamc_bind:
	dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
err_dpmac_setup:
	return err;
}
Exemplo n.º 21
0
/* Eth device open */
static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
{
	struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
	struct phy_device *phy_dev = eth_priv->phy_dev;

	debug("+ emac_open\n");

	net_rx_buffs.rx_flow	= eth_priv->rx_flow;

	sys_has_mdio =
		(eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;

	if (sys_has_mdio)
		keystone2_mdio_reset(mdio_bus);

#ifdef CONFIG_SOC_K2G
	keystone_rgmii_config(phy_dev);
#else
	keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1,
			      eth_priv->sgmii_link_type);
#endif

	udelay(10000);

	/* On chip switch configuration */
	ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);

	/* TODO: add error handling code */
	if (qm_init()) {
		printf("ERROR: qm_init()\n");
		return -1;
	}
	if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) {
		qm_close();
		printf("ERROR: netcp_init()\n");
		return -1;
	}

	/*
	 * Streaming switch configuration. If not present this
	 * statement is defined to void in target.h.
	 * If present this is usually defined to a series of register writes
	 */
	hw_config_streaming_switch();

	if (sys_has_mdio) {
		keystone2_mdio_reset(mdio_bus);

		phy_startup(phy_dev);
		if (phy_dev->link == 0) {
			ksnav_close(&netcp_pktdma);
			qm_close();
			return -1;
		}
	}

	emac_gigabit_enable(dev);

	ethss_start();

	debug("- emac_open\n");

	emac_open = 1;

	return 0;
}
Exemplo n.º 22
0
static int setup_phy(struct udevice *dev)
{
	int i, ret;
	u16 phyreg;
	struct xemaclite *emaclite = dev_get_priv(dev);
	struct phy_device *phydev;

	u32 supported = SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full;

	if (emaclite->phyaddr != -1) {
		phyread(emaclite, emaclite->phyaddr, PHY_DETECT_REG, &phyreg);
		if ((phyreg != 0xFFFF) &&
		    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
			/* Found a valid PHY address */
			debug("Default phy address %d is valid\n",
			      emaclite->phyaddr);
		} else {
			debug("PHY address is not setup correctly %d\n",
			      emaclite->phyaddr);
			emaclite->phyaddr = -1;
		}
	}

	if (emaclite->phyaddr == -1) {
		/* detect the PHY address */
		for (i = 31; i >= 0; i--) {
			phyread(emaclite, i, PHY_DETECT_REG, &phyreg);
			if ((phyreg != 0xFFFF) &&
			    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
				/* Found a valid PHY address */
				emaclite->phyaddr = i;
				debug("emaclite: Found valid phy address, %d\n",
				      i);
				break;
			}
		}
	}

	/* interface - look at tsec */
	phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev,
			     PHY_INTERFACE_MODE_MII);
	/*
	 * Phy can support 1000baseT but device NOT that's why phydev->supported
	 * must be setup for 1000baseT. phydev->advertising setups what speeds
	 * will be used for autonegotiation where 1000baseT must be disabled.
	 */
	phydev->supported = supported | SUPPORTED_1000baseT_Half |
						SUPPORTED_1000baseT_Full;
	phydev->advertising = supported;
	emaclite->phydev = phydev;
	phy_config(phydev);
	ret = phy_startup(phydev);
	if (ret)
		return ret;

	if (!phydev->link) {
		printf("%s: No link.\n", phydev->dev->name);
		return 0;
	}

	/* Do not setup anything */
	return 1;
}
Exemplo n.º 23
0
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
{
	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
	struct dpni_queue_attr rx_queue_attr;
	struct dpmac_link_state	dpmac_link_state = { 0 };
#ifdef DEBUG
	struct dpni_link_state link_state;
#endif
	int err;

	if (net_dev->state == ETH_STATE_ACTIVE)
		return 0;

	if (get_mc_boot_status() != 0) {
		printf("ERROR (MC is not booted)\n");
		return -ENODEV;
	}

	if (get_dpl_apply_status() == 0) {
		printf("ERROR (DPL is deployed. No device available)\n");
		return -ENODEV;
	}
	/* DPMAC initialization */
	err = ldpaa_dpmac_setup(priv);
	if (err < 0)
		goto err_dpmac_setup;

	/* DPMAC binding DPNI */
	err = ldpaa_dpmac_bind(priv);
	if (err)
		goto err_dpamc_bind;

	/* DPNI initialization */
	err = ldpaa_dpni_setup(priv);
	if (err < 0)
		goto err_dpni_setup;

	err = ldpaa_dpbp_setup();
	if (err < 0)
		goto err_dpbp_setup;

	/* DPNI binding DPBP */
	err = ldpaa_dpni_bind(priv);
	if (err)
		goto err_dpni_bind;

	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
				dflt_dpni->dpni_handle, net_dev->enetaddr);
	if (err) {
		printf("dpni_add_mac_addr() failed\n");
		return err;
	}

#ifdef CONFIG_PHYLIB
	/* TODO Check this path */
	err = phy_startup(priv->phydev);
	if (err) {
		printf("%s: Could not initialize\n", priv->phydev->dev->name);
		return err;
	}
#else
	priv->phydev->speed = SPEED_1000;
	priv->phydev->link = 1;
	priv->phydev->duplex = DUPLEX_FULL;
#endif

	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
	if (err < 0) {
		printf("dpni_enable() failed\n");
		return err;
	}

	dpmac_link_state.rate = SPEED_1000;
	dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG;
	dpmac_link_state.up = 1;
	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
				  priv->dpmac_handle, &dpmac_link_state);
	if (err < 0) {
		printf("dpmac_set_link_state() failed\n");
		return err;
	}

#ifdef DEBUG
	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
				  dflt_dpni->dpni_handle, &link_state);
	if (err < 0) {
		printf("dpni_get_link_state() failed\n");
		return err;
	}

	printf("link status: %d - ", link_state.up);
	link_state.up == 0 ? printf("down\n") :
	link_state.up == 1 ? printf("up\n") : printf("error state\n");
#endif

	/* TODO: support multiple Rx flows */
	err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
			       dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
	if (err) {
		printf("dpni_get_rx_flow() failed\n");
		goto err_rx_flow;
	}

	priv->rx_dflt_fqid = rx_queue_attr.fqid;

	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
			    &priv->tx_qdid);
	if (err) {
		printf("dpni_get_qdid() failed\n");
		goto err_qdid;
	}

	if (!priv->phydev->link)
		printf("%s: No link.\n", priv->phydev->dev->name);

	return priv->phydev->link ? 0 : -1;

err_qdid:
err_rx_flow:
	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
err_dpni_bind:
	ldpaa_dpbp_free();
err_dpbp_setup:
err_dpamc_bind:
	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
err_dpni_setup:
err_dpmac_setup:
	return err;
}
Exemplo n.º 24
0
/* Setting axi emac and phy to proper setting */
static int setup_phy(struct eth_device *dev)
{
	u16 phyreg;
	u32 i, speed, emmc_reg, ret;
	struct axidma_priv *priv = dev->priv;
	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
	struct phy_device *phydev;

	u32 supported = SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half |
			SUPPORTED_1000baseT_Full;

	if (priv->phyaddr == -1) {
		/* Detect the PHY address */
		for (i = 31; i >= 0; i--) {
			ret = phyread(dev, i, PHY_DETECT_REG, &phyreg);
			if (!ret && (phyreg != 0xFFFF) &&
			((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
				/* Found a valid PHY address */
				priv->phyaddr = i;
				debug("axiemac: Found valid phy address, %x\n",
									phyreg);
				break;
			}
		}
	}

	/* Interface - look at tsec */
	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);

	phydev->supported &= supported;
	phydev->advertising = phydev->supported;
	priv->phydev = phydev;
	phy_config(phydev);
	if (phy_startup(phydev)) {
		printf("axiemac: could not initialize PHY %s\n",
		       phydev->dev->name);
		return 0;
	}

	switch (phydev->speed) {
	case 1000:
		speed = XAE_EMMC_LINKSPD_1000;
		break;
	case 100:
		speed = XAE_EMMC_LINKSPD_100;
		break;
	case 10:
		speed = XAE_EMMC_LINKSPD_10;
		break;
	default:
		return 0;
	}

	/* Setup the emac for the phy speed */
	emmc_reg = in_be32(&regs->emmc);
	emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
	emmc_reg |= speed;

	/* Write new speed setting out to Axi Ethernet */
	out_be32(&regs->emmc, emmc_reg);

	/*
	* Setting the operating speed of the MAC needs a delay. There
	* doesn't seem to be register to poll, so please consider this
	* during your application design.
	*/
	udelay(1);

	return 1;
}
static int dw_eth_init(struct eth_device *dev, bd_t *bis)
{
	struct dw_eth_dev *priv = dev->priv;
	struct eth_mac_regs *mac_p = priv->mac_regs_p;
	struct eth_dma_regs *dma_p = priv->dma_regs_p;
	u32 conf;
#ifdef CONFIG_LARK_BOARD
	int ret;
#endif

	if (priv->phy_configured != 1) {
		int ret = configure_phy(dev);
		if (ret < 0) {
			printf("failed to configure phy: %d\n", ret);
			return ret;
		}
	}

#ifdef CONFIG_LARK_BOARD
	ret = phy_startup(priv->phy_dev);
	if (ret) {
		printf("%s: Could not initialize\n", priv->phy_dev->dev->name);
		return ret;
	}
	if(priv->phy_dev->speed == SPEED_1000){
		priv->speed = _1000BASET;
	}
	else if(priv->phy_dev->speed == SPEED_100){
		priv->speed = _100BASET;
	}
	else if(priv->phy_dev->speed == SPEED_10){
		priv->speed =_10BASET;
		}
#endif

	/* Print link status only once */
	if (!priv->link_printed) {
		printf("ENET Speed is %d Mbps - %s duplex connection\n",
		       priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
		priv->link_printed = 1;
	}

	/* Reset ethernet hardware */
	if (mac_reset(dev) < 0)
		return -1;

	/* Resore the HW MAC address as it has been lost during MAC reset */
	dw_write_hwaddr(dev);

	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
			&dma_p->busmode);

	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD |
		TXSECONDFRAME, &dma_p->opmode);

	conf = FRAMEBURSTENABLE | DISABLERXOWN;

	if (priv->speed != 1000)
		conf |= MII_PORTSELECT;

	if ((priv->interface != PHY_INTERFACE_MODE_MII) &&
		(priv->interface != PHY_INTERFACE_MODE_GMII)) {

		if (priv->speed == 100)
			conf |= FES_100;
	}

	if (priv->duplex == FULL)
		conf |= FULLDPLXMODE;

	writel(conf, &mac_p->conf);

	descs_init(dev);

	/*
	 * Start/Enable xfer at dma as well as mac level
	 */
	writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
	writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);

	writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);

	return 0;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
static int zynq_gem_init(struct udevice *dev)
{
	u32 i, nwconfig;
	unsigned long clk_rate = 0;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
	struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];

	if (!priv->init) {
		/* Disable all interrupts */
		writel(0xFFFFFFFF, &regs->idr);

		/* Disable the receiver & transmitter */
		writel(0, &regs->nwctrl);
		writel(0, &regs->txsr);
		writel(0, &regs->rxsr);
		writel(0, &regs->phymntnc);

		/* Clear the Hash registers for the mac address
		 * pointed by AddressPtr
		 */
		writel(0x0, &regs->hashl);
		/* Write bits [63:32] in TOP */
		writel(0x0, &regs->hashh);

		/* Clear all counters */
		for (i = 0; i < STAT_SIZE; i++)
			readl(&regs->stat[i]);

		/* Setup RxBD space */
		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));

		for (i = 0; i < RX_BUF; i++) {
			priv->rx_bd[i].status = 0xF0000000;
			priv->rx_bd[i].addr =
					((ulong)(priv->rxbuffers) +
							(i * PKTSIZE_ALIGN));
		}
		/* WRAP bit to last BD */
		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
		/* Write RxBDs to IP */
		writel((ulong)priv->rx_bd, &regs->rxqbase);

		/* Setup for DMA Configuration register */
		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

		/* Setup for Network Control register, MDIO, Rx and Tx enable */
		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);

		/* Disable the second priority queue */
		dummy_tx_bd->addr = 0;
		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
				ZYNQ_GEM_TXBUF_LAST_MASK|
				ZYNQ_GEM_TXBUF_USED_MASK;

		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
				ZYNQ_GEM_RXBUF_NEW_MASK;
		dummy_rx_bd->status = 0;
		flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
				   sizeof(dummy_tx_bd));
		flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
				   sizeof(dummy_rx_bd));

		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
		writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);

		priv->init++;
	}

	phy_startup(priv->phydev);

	if (!priv->phydev->link) {
		printf("%s: No link.\n", priv->phydev->dev->name);
		return -1;
	}

	nwconfig = ZYNQ_GEM_NWCFG_INIT;

	if (priv->interface == PHY_INTERFACE_MODE_SGMII) {
		nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
			    ZYNQ_GEM_NWCFG_PCS_SEL;
#ifdef CONFIG_ARM64
		writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
		       &regs->pcscntrl);
#endif
	}

	switch (priv->phydev->speed) {
	case SPEED_1000:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
		break;
	case SPEED_100:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_100;
		break;
	case SPEED_10:
		clk_rate = ZYNQ_GEM_FREQUENCY_10;
		break;
	}

	/* Change the rclk and clk only not using EMIO interface */
	if (!priv->emio)
		zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
					ZYNQ_GEM_BASEADDR0, clk_rate);

	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
					ZYNQ_GEM_NWCTRL_TXEN_MASK);

	return 0;
}
Exemplo n.º 28
0
static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
{
	int port = eth->port, ret = 0;
	u32 val;
	struct sh_eth_info *port_info = &eth->port_info[port];
	struct eth_device *dev = port_info->dev;
	struct phy_device *phy;

	/* Configure e-dmac registers */
	outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port));
	outl(0, EESIPR(port));
	outl(0, TRSCER(port));
	outl(0, TFTR(port));
	outl((FIFO_SIZE_T | FIFO_SIZE_R), FDR(port));
	outl(RMCR_RST, RMCR(port));
#if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724)
	outl(0, RPADIR(port));
#endif
	outl((FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR(port));

	/* Configure e-mac registers */
#if defined(CONFIG_CPU_SH7757)
	outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP |
		ECSIPR_MPDIP | ECSIPR_ICDIP, ECSIPR(port));
#else
	outl(0, ECSIPR(port));
#endif

	/* Set Mac address */
	val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 |
	    dev->enetaddr[2] << 8 | dev->enetaddr[3];
	outl(val, MAHR(port));

	val = dev->enetaddr[4] << 8 | dev->enetaddr[5];
	outl(val, MALR(port));

	outl(RFLR_RFL_MIN, RFLR(port));
#if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724)
	outl(0, PIPR(port));
#endif
#if !defined(CONFIG_CPU_SH7724)
	outl(APR_AP, APR(port));
	outl(MPR_MP, MPR(port));
#endif
#if defined(CONFIG_CPU_SH7763)
	outl(TPAUSER_TPAUSE, TPAUSER(port));
#elif defined(CONFIG_CPU_SH7757)
	outl(TPAUSER_UNLIMITED, TPAUSER(port));
#endif

	/* Configure phy */
	ret = sh_eth_phy_config(eth);
	if (ret) {
		printf(SHETHER_NAME ": phy config timeout\n");
		goto err_phy_cfg;
	}
	phy = port_info->phydev;
	phy_startup(phy);

	val = 0;

	/* Set the transfer speed */
	if (phy->speed == 100) {
		printf(SHETHER_NAME ": 100Base/");
#ifdef CONFIG_CPU_SH7763
		outl(GECMR_100B, GECMR(port));
#elif defined(CONFIG_CPU_SH7757)
		outl(1, RTRATE(port));
#elif defined(CONFIG_CPU_SH7724)
		val = ECMR_RTM;
#endif
	} else if (phy->speed == 10) {
		printf(SHETHER_NAME ": 10Base/");
#ifdef CONFIG_CPU_SH7763
		outl(GECMR_10B, GECMR(port));
#elif defined(CONFIG_CPU_SH7757)
		outl(0, RTRATE(port));
#endif
	}

	/* Check if full duplex mode is supported by the phy */
	if (phy->duplex) {
		printf("Full\n");
		outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port));
	} else {
		printf("Half\n");
		outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE),  ECMR(port));
	}

	return ret;

err_phy_cfg:
	return ret;
}
Exemplo n.º 29
0
static int zynq_gem_init(struct udevice *dev)
{
	u32 i, nwconfig;
	int ret;
	unsigned long clk_rate = 0;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
	struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];

	if (!priv->init) {
		/* Disable all interrupts */
		writel(0xFFFFFFFF, &regs->idr);

		/* Disable the receiver & transmitter */
		writel(0, &regs->nwctrl);
		writel(0, &regs->txsr);
		writel(0, &regs->rxsr);
		writel(0, &regs->phymntnc);

		/* Clear the Hash registers for the mac address
		 * pointed by AddressPtr
		 */
		writel(0x0, &regs->hashl);
		/* Write bits [63:32] in TOP */
		writel(0x0, &regs->hashh);

		/* Clear all counters */
		for (i = 0; i < STAT_SIZE; i++)
			readl(&regs->stat[i]);

		/* Setup RxBD space */
		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));

		for (i = 0; i < RX_BUF; i++) {
			priv->rx_bd[i].status = 0xF0000000;
			priv->rx_bd[i].addr =
					((ulong)(priv->rxbuffers) +
							(i * PKTSIZE_ALIGN));
		}
		/* WRAP bit to last BD */
		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
		/* Write RxBDs to IP */
		writel((ulong)priv->rx_bd, &regs->rxqbase);

		/* Setup for DMA Configuration register */
		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

		/* Setup for Network Control register, MDIO, Rx and Tx enable */
		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);

		/* Disable the second priority queue */
		dummy_tx_bd->addr = 0;
		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
				ZYNQ_GEM_TXBUF_LAST_MASK|
				ZYNQ_GEM_TXBUF_USED_MASK;

		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
				ZYNQ_GEM_RXBUF_NEW_MASK;
		dummy_rx_bd->status = 0;

		writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
		writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);

		priv->init++;
	}

	ret = phy_startup(priv->phydev);
	if (ret)
		return ret;

	if (!priv->phydev->link) {
		printf("%s: No link.\n", priv->phydev->dev->name);
		return -1;
	}

	nwconfig = ZYNQ_GEM_NWCFG_INIT;

	/*
	 * Set SGMII enable PCS selection only if internal PCS/PMA
	 * core is used and interface is SGMII.
	 */
	if (priv->interface == PHY_INTERFACE_MODE_SGMII &&
	    priv->int_pcs) {
		nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
			    ZYNQ_GEM_NWCFG_PCS_SEL;
#ifdef CONFIG_ARM64
		writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
		       &regs->pcscntrl);
#endif
	}

	switch (priv->phydev->speed) {
	case SPEED_1000:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
		break;
	case SPEED_100:
		writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_100;
		break;
	case SPEED_10:
		clk_rate = ZYNQ_GEM_FREQUENCY_10;
		break;
	}

#if !defined(CONFIG_ARCH_VERSAL)
	ret = clk_set_rate(&priv->clk, clk_rate);
	if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
		dev_err(dev, "failed to set tx clock rate\n");
		return ret;
	}

	ret = clk_enable(&priv->clk);
	if (ret && ret != -ENOSYS) {
		dev_err(dev, "failed to enable tx clock\n");
		return ret;
	}
#else
	debug("requested clk_rate %ld\n", clk_rate);
#endif

	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
					ZYNQ_GEM_NWCTRL_TXEN_MASK);

	return 0;
}
Exemplo n.º 30
0
static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
{
	u32 i;
	unsigned long __maybe_unused clk_rate = 0;
	struct phy_device *phydev;
	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
	struct zynq_gem_priv *priv = dev->priv;
	struct emac_bd *dummy_tx_bd = &priv->tx_bd[4];
	struct emac_bd *dummy_rx_bd = &priv->tx_bd[6];
	const u32 supported = SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half |
			SUPPORTED_1000baseT_Full;


	if (!priv->init) {
		/* Disable all interrupts */
		writel(0xFFFFFFFF, &regs->idr);

		/* Disable the receiver & transmitter */
		writel(0, &regs->nwctrl);
		writel(0, &regs->txsr);
		writel(0, &regs->rxsr);
		writel(0, &regs->phymntnc);

		/* Clear the Hash registers for the mac address
		 * pointed by AddressPtr
		 */
		writel(0x0, &regs->hashl);
		/* Write bits [63:32] in TOP */
		writel(0x0, &regs->hashh);

		/* Clear all counters */
		for (i = 0; i < STAT_SIZE; i++)
			readl(&regs->stat[i]);

		/* Setup RxBD space */
		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));

		for (i = 0; i < RX_BUF; i++) {
			priv->rx_bd[i].status = 0xF0000000;
			priv->rx_bd[i].addr =
					((unsigned long)(priv->rxbuffers) +
							(i * PKTSIZE_ALIGN));
		}
		/* WRAP bit to last BD */
		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
		/* Write RxBDs to IP */
		writel((unsigned long)priv->rx_bd, &regs->rxqbase);

		/* Setup for DMA Configuration register */
		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);

		/* Setup for Network Control register, MDIO, Rx and Tx enable */
		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);

		/*
		 * Disable the second priority queue.
		 * FIXME: Consider GEMs with more than 2 queues.
		 */
		dummy_tx_bd->addr = 0;
		dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
				ZYNQ_GEM_TXBUF_LAST_MASK|
				ZYNQ_GEM_TXBUF_USED_MASK;

		dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
				ZYNQ_GEM_RXBUF_NEW_MASK;
		dummy_rx_bd->status = 0;
		flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
				   sizeof(dummy_tx_bd));
		flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
				   sizeof(dummy_rx_bd));

		writel((unsigned long)dummy_tx_bd, &regs->transmit_q1_ptr);
		writel((unsigned long)dummy_rx_bd, &regs->receive_q1_ptr);

		priv->init++;
	}

	phy_detection(dev);

	/* interface - look at tsec */
	phydev = phy_connect(priv->bus, priv->phyaddr, dev,
			     priv->interface);

	phydev->supported = supported | ADVERTISED_Pause |
			    ADVERTISED_Asym_Pause;
	phydev->advertising = phydev->supported;
	priv->phydev = phydev;
	phy_config(phydev);
	phy_startup(phydev);
    phydev->speed = SPEED_1000;

	if (!phydev->link) {
		printf("%s: No link.\n", phydev->dev->name);
		return -1;
	}
    
	switch (phydev->speed) {
	case SPEED_1000:

		writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
		break;
	case SPEED_100:

		writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100,
		       &regs->nwcfg);
		clk_rate = ZYNQ_GEM_FREQUENCY_100;
		break;
	case SPEED_10:

		clk_rate = ZYNQ_GEM_FREQUENCY_10;
		break;
	}

	/* Change the rclk and clk only not using EMIO interface */
	if (!priv->emio) 
		zynq_slcr_gem_clk_setup(dev->iobase !=
					ZYNQ_GEM_BASEADDR0, clk_rate);

	/* set hardware address because of ... */
	if (!is_valid_ethaddr(dev->enetaddr)) {
		printf("%s: mac address is not valid\n", dev->name);
		return -1;
	}

	zynq_gem_setup_mac(dev);

	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
					ZYNQ_GEM_NWCTRL_TXEN_MASK);

	return 0;
}