Beispiel #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);
}
Beispiel #2
0
void ls2085a_handle_phy_interface_sgmii(int dpmac_id)
{
	int lane, slot;
	struct mii_dev *bus;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;

	switch (serdes1_prtcl) {
	}

	switch (serdes2_prtcl) {
	case 0x07:
	case 0x08:
	case 0x49:
		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
							(dpmac_id - 9));
		slot = lane_to_slot_fsm2[lane];

		switch (++slot) {
		case 1:
			break;
		case 3:
			break;
		case 4:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 9]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
			bus = mii_dev_for_muxval(EMI1_SLOT4);
			wriop_set_mdio(dpmac_id, bus);
			dpmac_info[dpmac_id].phydev = phy_connect(
						dpmac_info[dpmac_id].bus,
						dpmac_info[dpmac_id].phy_addr,
						NULL,
						dpmac_info[dpmac_id].enet_if);
			phy_config(dpmac_info[dpmac_id].phydev);
		break;
		case 5:
		break;
		case 6:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 13]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
			bus = mii_dev_for_muxval(EMI1_SLOT6);
			wriop_set_mdio(dpmac_id, bus);
		break;
	}
	break;
	default:
		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
		       serdes2_prtcl);
	break;
	}
}
/*
 * This function initializes the EMAC hardware.
 */
int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
{
	int res;
	struct eth_device *dev;
	struct phy_device *phy_dev;

	dev = malloc(sizeof(struct eth_device));
	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof(struct eth_device));

	strcpy(dev->name, eth_priv->int_name);
	dev->priv = eth_priv;

	keystone2_eth_read_mac_addr(dev);

	dev->iobase		= 0;
	dev->init		= keystone2_eth_open;
	dev->halt		= keystone2_eth_close;
	dev->send		= keystone2_eth_send_packet;
	dev->recv		= keystone2_eth_rcv_packet;
#ifdef CONFIG_MCAST_TFTP
	dev->mcast		= keystone2_eth_bcast_addr;
#endif

	eth_register(dev);

	/* Register MDIO bus if it's not registered yet */
	if (!mdio_bus) {
		mdio_bus	= mdio_alloc();
		mdio_bus->read	= keystone2_mdio_read;
		mdio_bus->write	= keystone2_mdio_write;
		mdio_bus->reset	= keystone2_mdio_reset;
		mdio_bus->priv	= (void *)EMAC_MDIO_BASE_ADDR;
		sprintf(mdio_bus->name, "ethernet-mdio");

		res = mdio_register(mdio_bus);
		if (res)
			return res;
	}

#ifndef CONFIG_SOC_K2G
	keystone2_net_serdes_setup();
#endif

	/* Create phy device and bind it with driver */
#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
	phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
			      dev, eth_priv->phy_if);
	phy_config(phy_dev);
#else
	phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr,
				   eth_priv->phy_if);
	phy_dev->dev = dev;
#endif
	eth_priv->phy_dev = phy_dev;

	return 0;
}
Beispiel #4
0
/* Discover which PHY is attached to the device, and configure it
 * properly.  If the PHY is not recognized, then return 0
 * (failure).  Otherwise, return 1
 */
static int init_phy(struct eth_device *dev)
{
	struct tsec_private *priv = (struct tsec_private *)dev->priv;
	struct phy_device *phydev;
	tsec_t *regs = priv->regs;
	u32 supported = (SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full);

	if (priv->flags & TSEC_GIGABIT)
		supported |= SUPPORTED_1000baseT_Full;

	/* Assign a Physical address to the TBI */
	out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);

	priv->interface = tsec_get_interface(priv);

	if (priv->interface == PHY_INTERFACE_MODE_SGMII)
		tsec_configure_serdes(priv);

	phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);

	phydev->supported &= supported;
	phydev->advertising = phydev->supported;

	priv->phydev = phydev;

	phy_config(phydev);

	return 1;
}
Beispiel #5
0
static int bcm_sf2_eth_init(struct eth_device *dev)
{
	struct eth_info *eth = (struct eth_info *)(dev->priv);
	struct eth_dma *dma = &(eth->dma);
	struct phy_device *phydev;
	int rc = 0;
	int i;

	rc = eth->mac_init(dev);
	if (rc) {
		error("%s: Couldn't cofigure MAC!\n", __func__);
		return rc;
	}

	/* disable DMA */
	dma->disable_dma(dma, MAC_DMA_RX);
	dma->disable_dma(dma, MAC_DMA_TX);

	eth->port_num = 0;
	debug("Connecting PHY 0...\n");
	phydev = phy_connect(miiphy_get_dev_by_name(dev->name),
			     0, dev, eth->phy_interface);
	if (phydev != NULL) {
		eth->port[0] = phydev;
		eth->port_num += 1;
	} else {
		debug("No PHY found for port 0\n");
	}

	for (i = 0; i < eth->port_num; i++)
		phy_config(eth->port[i]);

	return rc;
}
Beispiel #6
0
static int zynq_phy_init(struct udevice *dev)
{
	int ret;
	struct zynq_gem_priv *priv = dev_get_priv(dev);
	struct zynq_gem_regs *regs = priv->iobase;
	const u32 supported = SUPPORTED_10baseT_Half |
			SUPPORTED_10baseT_Full |
			SUPPORTED_100baseT_Half |
			SUPPORTED_100baseT_Full |
			SUPPORTED_1000baseT_Half |
			SUPPORTED_1000baseT_Full;

	/* Enable only MDIO bus */
	writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->nwctrl);

	if (priv->interface != PHY_INTERFACE_MODE_SGMII) {
		ret = phy_detection(dev);
		if (ret) {
			printf("GEM PHY init failed\n");
			return ret;
		}
	}

	priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,
				   priv->interface);
	if (!priv->phydev)
		return -ENODEV;

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

	return 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;
}
Beispiel #8
0
static void fec_eth_phy_config(struct eth_device *dev)
{
#ifdef CONFIG_PHYLIB
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
	struct phy_device *phydev;

	phydev = phy_connect(fec->bus, fec->phy_id, dev,
			PHY_INTERFACE_MODE_RGMII);
	if (phydev) {
		fec->phydev = phydev;
		phy_config(phydev);
	}
#endif
}
void init_host_phys(struct mii_dev *bus)
{
	uint k;

	for (k = 0; k < 2; ++k) {
		struct phy_device *phydev;

		phydev = phy_find_by_mask(bus, 1 << k,
					  PHY_INTERFACE_MODE_SGMII);

		if (phydev)
			phy_config(phydev);
	}
}
Beispiel #10
0
static int sh_eth_phy_config(struct sh_eth_dev *eth)
{
	int port = eth->port, ret = 0;
	struct sh_eth_info *port_info = &eth->port_info[port];
	struct eth_device *dev = port_info->dev;
	struct phy_device *phydev;

	phydev = phy_connect(miiphy_get_dev_by_name(dev->name),
			port_info->phy_addr, dev, PHY_INTERFACE_MODE_MII);
	port_info->phydev = phydev;
	phy_config(phydev);

	return ret;
}
Beispiel #11
0
static int init_phy(struct eth_device *dev)
{
	struct fm_eth *fm_eth = dev->priv;
#ifdef CONFIG_PHYLIB
	struct phy_device *phydev = NULL;
	u32 supported;
#endif

	if (fm_eth->type == FM_ETH_1G_E)
		dtsec_init_phy(dev);

#ifdef CONFIG_PHYLIB
	if (fm_eth->bus) {
		phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev,
					fm_eth->enet_if);
		if (!phydev) {
			printf("Failed to connect\n");
			return -1;
		}
	} else {
		return 0;
	}

	if (fm_eth->type == FM_ETH_1G_E) {
		supported = (SUPPORTED_10baseT_Half |
				SUPPORTED_10baseT_Full |
				SUPPORTED_100baseT_Half |
				SUPPORTED_100baseT_Full |
				SUPPORTED_1000baseT_Full);
	} else {
		supported = SUPPORTED_10000baseT_Full;

		if (tgec_is_fibre(dev))
			phydev->port = PORT_FIBRE;
	}

	phydev->supported &= supported;
	phydev->advertising = phydev->supported;

	fm_eth->phydev = phydev;

	phy_config(phydev);
#endif

	return 0;
}
/*
 * Discover which PHY is attached to the device, and configure it
 * properly.  If the PHY is not recognized, then return 0
 * (failure).  Otherwise, return 1
 */
static int ll_temac_phy_init(struct eth_device *dev)
{
	struct ll_temac *ll_temac = dev->priv;
	struct phy_device *phydev;
	unsigned int supported = PHY_GBIT_FEATURES;

	/* interface - look at driver/net/tsec.c */
	phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr,
			dev, PHY_INTERFACE_MODE_NONE);

	phydev->supported &= supported;
	phydev->advertising = phydev->supported;

	ll_temac->phydev = phydev;

	phy_config(phydev);

	return 1;
}
static int axiemac_phy_init(struct udevice *dev)
{
	u16 phyreg;
	u32 i, ret;
	struct axidma_priv *priv = dev_get_priv(dev);
	struct axi_regs *regs = priv->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;

	/* Set default MDIO divisor */
	writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, &regs->mdio_mc);

	if (priv->phyaddr == -1) {
		/* Detect the PHY address */
		for (i = 31; i >= 0; i--) {
			ret = phyread(priv, 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",
				      i);
				break;
			}
		}
	}

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

	phydev->supported &= supported;
	phydev->advertising = phydev->supported;
	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}
Beispiel #14
0
static int fec_phy_init(struct fec_priv *priv, struct udevice *dev)
{
	struct phy_device *phydev;
	int mask = 0xffffffff;

#ifdef CONFIG_PHYLIB
	mask = 1 << CONFIG_FEC_MXC_PHYADDR;
#endif

	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
	if (!phydev)
		return -ENODEV;

	phy_connect_dev(phydev, dev);

	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}
Beispiel #15
0
static int init_phy(struct eth_device *dev)
{
	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
	struct phy_device *phydev = NULL;
	struct mii_dev *bus;

	bus = wriop_get_mdio(priv->dpmac_id);
	if (bus == NULL)
		return 0;

	phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
			     dev, wriop_get_enet_if(priv->dpmac_id));
	if (!phydev) {
		printf("Failed to connect\n");
		return -1;
	}

	priv->phydev = phydev;

	return phy_config(phydev);
}
Beispiel #16
0
static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
{
	struct phy_device *phydev;
	unsigned int mask = 0xffffffff;

	if (priv->phyaddr)
		mask = 1 << priv->phyaddr;

	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
	if (!phydev)
		return -ENODEV;

	phy_connect_dev(phydev, dev);

	phydev->supported &= PHY_GBIT_FEATURES;
	phydev->advertising = phydev->supported;

	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}
Beispiel #17
0
static int ftgmac100_phy_init(struct udevice *dev)
{
	struct ftgmac100_data *priv = dev_get_priv(dev);
	struct phy_device *phydev;
	int ret;

	phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode);
	if (!phydev)
		return -ENODEV;

	phydev->supported &= PHY_GBIT_FEATURES;
	if (priv->max_speed) {
		ret = phy_set_supported(phydev, priv->max_speed);
		if (ret)
			return ret;
	}
	phydev->advertising = phydev->supported;
	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}
Beispiel #18
0
static int pch_gbe_phy_init(struct eth_device *dev)
{
	struct pch_gbe_priv *priv = dev->priv;
	struct phy_device *phydev;
	int mask = 0xffffffff;

	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
	if (!phydev) {
		printf("pch_gbe: cannot find the phy\n");
		return -1;
	}

	phy_connect_dev(phydev, dev);

	phydev->supported &= PHY_GBIT_FEATURES;
	phydev->advertising = phydev->supported;

	priv->phydev = phydev;
	phy_config(phydev);

	return 1;
}
Beispiel #19
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;
}
static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
		struct mii_dev *bus, int phy_id)
#endif
{
	struct eth_device *edev;
	struct fec_priv *fec;
	unsigned char ethaddr[6];
	uint32_t start;
	int ret = 0;

	/* create and fill edev struct */
	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
	if (!edev) {
		puts("fec_mxc: not enough malloc memory for eth_device\n");
		ret = -ENOMEM;
		goto err1;
	}

	fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
	if (!fec) {
		puts("fec_mxc: not enough malloc memory for fec_priv\n");
		ret = -ENOMEM;
		goto err2;
	}

	memset(edev, 0, sizeof(*edev));
	memset(fec, 0, sizeof(*fec));

	ret = fec_alloc_descs(fec);
	if (ret)
		goto err3;

	edev->priv = fec;
	edev->init = fec_init;
	edev->send = fec_send;
	edev->recv = fec_recv;
	edev->halt = fec_halt;
	edev->write_hwaddr = fec_set_hwaddr;

	fec->eth = (struct ethernet_regs *)base_addr;
	fec->bd = bd;

	fec->xcv_type = CONFIG_FEC_XCV_TYPE;

	/* Reset chip. */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
	start = get_timer(0);
	while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
			printf("FEC MXC: Timeout reseting chip\n");
			goto err4;
		}
		udelay(10);
	}

	fec_reg_setup(fec);
	fec_set_dev_name(edev->name, dev_id);
	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
	fec->bus = bus;
	fec_mii_setspeed(bus->priv);
#ifdef CONFIG_PHYLIB
	fec->phydev = phydev;
	phy_connect_dev(phydev, edev);
	/* Configure phy */
	phy_config(phydev);
#else
	fec->phy_id = phy_id;
#endif
	eth_register(edev);

	if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
		debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
		memcpy(edev->enetaddr, ethaddr, 6);
		if (!getenv("ethaddr"))
			eth_setenv_enetaddr("ethaddr", ethaddr);
	}
	return ret;
err4:
	fec_free_descs(fec);
err3:
	free(fec);
err2:
	free(edev);
err1:
	return ret;
}
Beispiel #21
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;
}
Beispiel #22
0
static int macb_phy_init(struct macb_device *macb, const char *name)
#endif
{
#ifdef CONFIG_DM_ETH
	struct macb_device *macb = dev_get_priv(dev);
#endif
	u32 ncfgr;
	u16 phy_id, status, adv, lpa;
	int media, speed, duplex;
	int i;

	arch_get_mdio_control(name);
	/* Auto-detect phy_addr */
	if (!macb_phy_find(macb, name))
		return 0;

	/* Check if the PHY is up to snuff... */
	phy_id = macb_mdio_read(macb, MII_PHYSID1);
	if (phy_id == 0xffff) {
		printf("%s: No PHY present\n", name);
		return 0;
	}

#ifdef CONFIG_PHYLIB
#ifdef CONFIG_DM_ETH
	macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
			     macb->phy_interface);
#else
	/* need to consider other phy interface mode */
	macb->phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev,
			     PHY_INTERFACE_MODE_RGMII);
#endif
	if (!macb->phydev) {
		printf("phy_connect failed\n");
		return -ENODEV;
	}

	phy_config(macb->phydev);
#endif

	status = macb_mdio_read(macb, MII_BMSR);
	if (!(status & BMSR_LSTATUS)) {
		/* Try to re-negotiate if we don't have link already. */
		macb_phy_reset(macb, name);

		for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
			status = macb_mdio_read(macb, MII_BMSR);
			if (status & BMSR_LSTATUS)
				break;
			udelay(100);
		}
	}

	if (!(status & BMSR_LSTATUS)) {
		printf("%s: link down (status: 0x%04x)\n",
		       name, status);
		return 0;
	}

	/* First check for GMAC and that it is GiB capable */
	if (gem_is_gigabit_capable(macb)) {
		lpa = macb_mdio_read(macb, MII_STAT1000);

		if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
			duplex = ((lpa & LPA_1000FULL) ? 1 : 0);

			printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
			       name,
			       duplex ? "full" : "half",
			       lpa);

			ncfgr = macb_readl(macb, NCFGR);
			ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
			ncfgr |= GEM_BIT(GBE);

			if (duplex)
				ncfgr |= MACB_BIT(FD);

			macb_writel(macb, NCFGR, ncfgr);

			return 1;
		}
	}

	/* fall back for EMAC checking */
	adv = macb_mdio_read(macb, MII_ADVERTISE);
	lpa = macb_mdio_read(macb, MII_LPA);
	media = mii_nway_result(lpa & adv);
	speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
		 ? 1 : 0);
	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
	printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
	       name,
	       speed ? "100" : "10",
	       duplex ? "full" : "half",
	       lpa);

	ncfgr = macb_readl(macb, NCFGR);
	ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
	if (speed)
		ncfgr |= MACB_BIT(SPD);
	if (duplex)
		ncfgr |= MACB_BIT(FD);
	macb_writel(macb, NCFGR, ncfgr);

	return 1;
}
/* 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;
}
Beispiel #24
0
Datei: macb.c Projekt: DFE/u-boot
static int macb_phy_init(struct macb_device *macb)
{
	struct eth_device *netdev = &macb->netdev;
#ifdef CONFIG_PHYLIB
	struct phy_device *phydev;
#endif
	u32 ncfgr;
	u16 phy_id, status, adv, lpa;
	int media, speed, duplex;
	int i;

	arch_get_mdio_control(netdev->name);
#ifdef CONFIG_MACB_SEARCH_PHY
	/* Auto-detect phy_addr */
	if (!macb_phy_find(macb)) {
		return 0;
	}
#endif /* CONFIG_MACB_SEARCH_PHY */

	/* Check if the PHY is up to snuff... */
	phy_id = macb_mdio_read(macb, MII_PHYSID1);
	if (phy_id == 0xffff) {
		printf("%s: No PHY present\n", netdev->name);
		return 0;
	}

#ifdef CONFIG_PHYLIB
	phydev->bus = macb->bus;
	phydev->dev = netdev;
	phydev->addr = macb->phy_addr;
	phy_config(phydev);
#endif

	status = macb_mdio_read(macb, MII_BMSR);
	if (!(status & BMSR_LSTATUS)) {
		/* Try to re-negotiate if we don't have link already. */
		macb_phy_reset(macb);

		for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) {
			status = macb_mdio_read(macb, MII_BMSR);
			if (status & BMSR_LSTATUS)
				break;
			udelay(100);
		}
	}

	if (!(status & BMSR_LSTATUS)) {
		printf("%s: link down (status: 0x%04x)\n",
		       netdev->name, status);
		return 0;
	}

	/* First check for GMAC */
	if (macb_is_gem(macb)) {
		lpa = macb_mdio_read(macb, MII_STAT1000);
		if (lpa & (1 << 11)) {
			speed = 1000;
			duplex = 1;
		} else {
		       if (lpa & (1 << 10)) {
				speed = 1000;
				duplex = 1;
			} else {
				speed = 0;
			}
		}

		if (speed == 1000) {
			printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n",
			       netdev->name,
			       speed,
			       duplex ? "full" : "half",
			       lpa);

			ncfgr = macb_readl(macb, NCFGR);
			ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD));
			if (speed)
				ncfgr |= GEM_BIT(GBE);
			if (duplex)
				ncfgr |= MACB_BIT(FD);
			macb_writel(macb, NCFGR, ncfgr);

			return 1;
		}
	}

	/* fall back for EMAC checking */
	adv = macb_mdio_read(macb, MII_ADVERTISE);
	lpa = macb_mdio_read(macb, MII_LPA);
	media = mii_nway_result(lpa & adv);
	speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
		 ? 1 : 0);
	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
	printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
	       netdev->name,
	       speed ? "100" : "10",
	       duplex ? "full" : "half",
	       lpa);

	ncfgr = macb_readl(macb, NCFGR);
	ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
	if (speed)
		ncfgr |= MACB_BIT(SPD);
	if (duplex)
		ncfgr |= MACB_BIT(FD);
	macb_writel(macb, NCFGR, ncfgr);

	return 1;
}
Beispiel #25
0
static int ks2_eth_probe(struct udevice *dev)
{
	struct ks2_eth_priv *priv = dev_get_priv(dev);
	struct mii_dev *mdio_bus;
	int ret;

	priv->dev = dev;

	/* These clock enables has to be moved to common location */
	if (cpu_is_k2g())
		writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG);

	/* By default, select PA PLL clock as PA clock source */
#ifndef CONFIG_SOC_K2G
	if (psc_enable_module(KS2_LPSC_PA))
		return -EACCES;
#endif
	if (psc_enable_module(KS2_LPSC_CPGMAC))
		return -EACCES;
	if (psc_enable_module(KS2_LPSC_CRYPTO))
		return -EACCES;

	if (cpu_is_k2e() || cpu_is_k2l())
		pll_pa_clk_sel();


	priv->net_rx_buffs.buff_ptr = rx_buffs;
	priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS;
	priv->net_rx_buffs.buff_len = RX_BUFF_LEN;

	if (priv->slave_port == 1) {
		/*
		 * Register MDIO bus for slave 0 only, other slave have
		 * to re-use the same
		 */
		mdio_bus = mdio_alloc();
		if (!mdio_bus) {
			error("MDIO alloc failed\n");
			return -ENOMEM;
		}
		priv->mdio_bus = mdio_bus;
		mdio_bus->read	= keystone2_mdio_read;
		mdio_bus->write	= keystone2_mdio_write;
		mdio_bus->reset	= keystone2_mdio_reset;
		mdio_bus->priv	= priv->mdio_base;
		sprintf(mdio_bus->name, "ethernet-mdio");

		ret = mdio_register(mdio_bus);
		if (ret) {
			error("MDIO bus register failed\n");
			return ret;
		}
	} else {
		/* Get the MDIO bus from slave 0 device */
		struct ks2_eth_priv *parent_priv;

		parent_priv = dev_get_priv(dev->parent);
		priv->mdio_bus = parent_priv->mdio_bus;
	}

#ifndef CONFIG_SOC_K2G
	keystone2_net_serdes_setup();
#endif

	priv->netcp_pktdma = &netcp_pktdma;

	if (priv->has_mdio) {
		priv->phydev = phy_connect(priv->mdio_bus, priv->phy_addr,
					   dev, priv->phy_if);
		phy_config(priv->phydev);
	}

	return 0;
}
Beispiel #26
0
void ls2080a_handle_phy_interface_sgmii(int dpmac_id)
{
	int lane, slot;
	struct mii_dev *bus;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
	int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;

	int *riser_phy_addr;
	char *env_hwconfig = getenv("hwconfig");

	if (hwconfig_f("xqsgmii", env_hwconfig))
		riser_phy_addr = &xqsgii_riser_phy_addr[0];
	else
		riser_phy_addr = &sgmii_riser_phy_addr[0];

	if (dpmac_id > WRIOP1_DPMAC9)
		goto serdes2;

	switch (serdes1_prtcl) {
	case 0x07:

		lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id);
		slot = lane_to_slot_fsm1[lane];

		switch (++slot) {
		case 1:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 1]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
			bus = mii_dev_for_muxval(EMI1_SLOT1);
			wriop_set_mdio(dpmac_id, bus);
			dpmac_info[dpmac_id].phydev = phy_connect(
						dpmac_info[dpmac_id].bus,
						dpmac_info[dpmac_id].phy_addr,
						NULL,
						dpmac_info[dpmac_id].enet_if);
			phy_config(dpmac_info[dpmac_id].phydev);
			break;
		case 2:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 1]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT2;
			bus = mii_dev_for_muxval(EMI1_SLOT2);
			wriop_set_mdio(dpmac_id, bus);
			dpmac_info[dpmac_id].phydev = phy_connect(
						dpmac_info[dpmac_id].bus,
						dpmac_info[dpmac_id].phy_addr,
						NULL,
						dpmac_info[dpmac_id].enet_if);
			phy_config(dpmac_info[dpmac_id].phydev);
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		}
	break;
	default:
		printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n",
		       __func__ , serdes1_prtcl);
	break;
	}

serdes2:
	switch (serdes2_prtcl) {
	case 0x07:
	case 0x08:
	case 0x49:
		lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
							(dpmac_id - 9));
		slot = lane_to_slot_fsm2[lane];

		switch (++slot) {
		case 1:
			break;
		case 3:
			break;
		case 4:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 9]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
			bus = mii_dev_for_muxval(EMI1_SLOT4);
			wriop_set_mdio(dpmac_id, bus);
			dpmac_info[dpmac_id].phydev = phy_connect(
						dpmac_info[dpmac_id].bus,
						dpmac_info[dpmac_id].phy_addr,
						NULL,
						dpmac_info[dpmac_id].enet_if);
			phy_config(dpmac_info[dpmac_id].phydev);
		break;
		case 5:
		break;
		case 6:
			/* Slot housing a SGMII riser card? */
			wriop_set_phy_address(dpmac_id,
					      riser_phy_addr[dpmac_id - 13]);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
			bus = mii_dev_for_muxval(EMI1_SLOT6);
			wriop_set_mdio(dpmac_id, bus);
		break;
	}
	break;
	default:
		printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n",
		       __func__, serdes2_prtcl);
	break;
	}
}
Beispiel #27
0
void ls2080a_handle_phy_interface_qsgmii(int dpmac_id)
{
	int lane = 0, slot;
	struct mii_dev *bus;
	struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
	int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
				FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
		>> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;

	switch (serdes1_prtcl) {
	case 0x33:
		switch (dpmac_id) {
		case 1:
		case 2:
		case 3:
		case 4:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A);
		break;
		case 5:
		case 6:
		case 7:
		case 8:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B);
		break;
		case 9:
		case 10:
		case 11:
		case 12:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C);
		break;
		case 13:
		case 14:
		case 15:
		case 16:
			lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D);
		break;
	}

		slot = lane_to_slot_fsm1[lane];

		switch (++slot) {
		case 1:
			/* Slot housing a QSGMII riser card? */
			wriop_set_phy_address(dpmac_id, dpmac_id - 1);
			dpmac_info[dpmac_id].board_mux = EMI1_SLOT1;
			bus = mii_dev_for_muxval(EMI1_SLOT1);
			wriop_set_mdio(dpmac_id, bus);
			dpmac_info[dpmac_id].phydev = phy_connect(
						dpmac_info[dpmac_id].bus,
						dpmac_info[dpmac_id].phy_addr,
						NULL,
						dpmac_info[dpmac_id].enet_if);

			phy_config(dpmac_info[dpmac_id].phydev);
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
		break;
		case 6:
			break;
	}
	break;
	default:
		printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
		       serdes1_prtcl);
	break;
	}

	qsgmii_configure_repeater(dpmac_id);
}
Beispiel #28
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;
}