Ejemplo n.º 1
0
static int mii_probe(struct net_device *dev, int phy_mode)
{
	struct bfin_mac_local *lp = netdev_priv(dev);
	struct phy_device *phydev;
	unsigned short sysctl;
	u32 sclk, mdc_div;

	/* Enable PHY output early */
	if (!(bfin_read_VR_CTL() & CLKBUFOE))
		bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);

	sclk = get_sclk();
	mdc_div = ((sclk / MDC_CLK) / 2) - 1;

	sysctl = bfin_read_EMAC_SYSCTL();
	sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div);
	bfin_write_EMAC_SYSCTL(sysctl);

	phydev = phy_find_first(lp->mii_bus);
	if (!phydev) {
		netdev_err(dev, "no phy device found\n");
		return -ENODEV;
	}

	if (phy_mode != PHY_INTERFACE_MODE_RMII &&
		phy_mode != PHY_INTERFACE_MODE_MII) {
		netdev_err(dev, "invalid phy interface mode\n");
		return -EINVAL;
	}

	phydev = phy_connect(dev, phydev_name(phydev),
			     &bfin_mac_adjust_link, phy_mode);

	if (IS_ERR(phydev)) {
		netdev_err(dev, "could not attach PHY\n");
		return PTR_ERR(phydev);
	}

	/* mask with MAC supported features */
	phydev->supported &= (SUPPORTED_10baseT_Half
			      | SUPPORTED_10baseT_Full
			      | SUPPORTED_100baseT_Half
			      | SUPPORTED_100baseT_Full
			      | SUPPORTED_Autoneg
			      | SUPPORTED_Pause | SUPPORTED_Asym_Pause
			      | SUPPORTED_MII
			      | SUPPORTED_TP);

	phydev->advertising = phydev->supported;

	lp->old_link = 0;
	lp->old_speed = 0;
	lp->old_duplex = -1;
	lp->phydev = phydev;

	phy_attached_print(phydev, "mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n",
			   MDC_CLK, mdc_div, sclk / 1000000);

	return 0;
}
Ejemplo n.º 2
0
void SetupSystemRegs(void)
{
	unsigned int nTimer;

	// Set FER regs to MUX in Ethernet pins
	// MUX these pins to Ethernet
#if (__SILICON_REVISION__ < 0x0001) // Workaround silicon anomaly 05000212
	u32 temp = *pPORTH_FER;
	*pPORTH_FER = 0xffff;
#endif
	*pPORTH_FER = 0xffff;

	// Program EMAC2 System Control Reg
	// set MDC clock divisor (min period is 400 ns)
	// sysctl = EMAC2_MDCDIV(26);	// %54 for 132 MHz SCLK
	// sysctl = EMAC2_MDCDIV(10);	// %22 for  54 MHz SCLK
//	sysctl = SET_MDCDIV(23);		// %23 for  120 MHz SCLK   //KG
	*pEMAC_SYSCTL = ( (SET_MDCDIV(23)) | RXCKS | RXDWA);
	
	WrPHYReg(BR_BUB_PHYADD, PHY_CNTL_REG, PHY_CNTL_RST);
	
//	ulEndTime = (GetTickCount() + 10000);
//	do{
//		asm("nop;");
//	}while( (PHY_CNTL_RST & RdPHYReg(BR_BUB_PHYADD, PHY_CNTL_REG)) && (GetTickCount() < ulEndTime) );


	nTimer = SetTimeout(10000);
	if( ((unsigned int)-1) != nTimer )
	{
		do{
			asm("nop;");
		}while( (PHY_CNTL_RST & RdPHYReg(BR_BUB_PHYADD, PHY_CNTL_REG)) && (!IsTimedout(nTimer)) );
	}
	
	ClearTimeout(nTimer);

	
	// The status register (reg 1) should read 0x7809 to show no link detected
	// Program PHY registers
	WrPHYReg(BR_BUB_PHYADD, PHY_CNTL_REG, (PHY_CNTL_DPLX|PHY_CNTL_ANEG_RST|PHY_CNTL_SPEED) );
	
	// stay here until the link is detected
//	ulEndTime = (GetTickCount() + 10000);
//	do{
//		asm("nop;");
//	}while ( ((PHY_STAT_LINK & RdPHYReg(BR_BUB_PHYADD, PHY_STAT_REG)) == 0) && (GetTickCount() < ulEndTime) );
	
	nTimer = SetTimeout(10000);
	if( ((unsigned int)-1) != nTimer )
	{
		do{
			asm("nop;");
		}while ( ((PHY_STAT_LINK & RdPHYReg(BR_BUB_PHYADD, PHY_STAT_REG)) == 0) && (!IsTimedout(nTimer)) );
	}
	
	ClearTimeout(nTimer);
}
Ejemplo n.º 3
0
static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
{
	const unsigned short pins[] = CONFIG_BFIN_MAC_PINS;
	u16 phydat;
	size_t count;

	/* Enable PHY output */
	bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);

	/* Set all the pins to peripheral mode */
	peripheral_request_list(pins, "bfin_mac");

	/* Odd word alignment for Receive Frame DMA word */
	/* Configure checksum support and rcve frame word alignment */
	bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));

	/* turn on auto-negotiation and wait for link to come up */
	bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE);
	count = 0;
	while (1) {
		++count;
		if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat))
			return -1;
		if (phydat & BMSR_LSTATUS)
			break;
		if (count > 30000) {
			printf("%s: link down, check cable\n", dev->name);
			return -1;
		}
		udelay(100);
	}

	/* see what kind of link we have */
	if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat))
		return -1;
	if (phydat & LPA_DUPLEX)
		*opmode = FDMODE;
	else
		*opmode = 0;

	bfin_write_EMAC_MMC_CTL(RSTC | CROLL);

	/* Initialize the TX DMA channel registers */
	bfin_write_DMA2_X_COUNT(0);
	bfin_write_DMA2_X_MODIFY(4);
	bfin_write_DMA2_Y_COUNT(0);
	bfin_write_DMA2_Y_MODIFY(0);

	/* Initialize the RX DMA channel registers */
	bfin_write_DMA1_X_COUNT(0);
	bfin_write_DMA1_X_MODIFY(4);
	bfin_write_DMA1_Y_COUNT(0);
	bfin_write_DMA1_Y_MODIFY(0);

	return 0;
}
Ejemplo n.º 4
0
static int mii_probe(struct net_device *dev)
{
	struct bfin_mac_local *lp = netdev_priv(dev);
	struct phy_device *phydev = NULL;
	unsigned short sysctl;
	int i;
	u32 sclk, mdc_div;

	/* Enable PHY output early */
	if (!(bfin_read_VR_CTL() & PHYCLKOE))
		bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);

	sclk = get_sclk();
	mdc_div = ((sclk / MDC_CLK) / 2) - 1;

	sysctl = bfin_read_EMAC_SYSCTL();
	sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div);
	bfin_write_EMAC_SYSCTL(sysctl);

	/* search for connect PHY device */
	for (i = 0; i < PHY_MAX_ADDR; i++) {
		struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i];

		if (!tmp_phydev)
			continue; /* no PHY here... */

		phydev = tmp_phydev;
		break; /* found it */
	}

	/* now we are supposed to have a proper phydev, to attach to... */
	if (!phydev) {
		printk(KERN_INFO "%s: Don't found any phy device at all\n",
			dev->name);
		return -ENODEV;
	}

#if defined(CONFIG_BFIN_MAC_RMII)
	phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
			0, PHY_INTERFACE_MODE_RMII);
#else
	phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
			0, PHY_INTERFACE_MODE_MII);
#endif

	if (IS_ERR(phydev)) {
		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
		return PTR_ERR(phydev);
	}

	/* mask with MAC supported features */
	phydev->supported &= (SUPPORTED_10baseT_Half
			      | SUPPORTED_10baseT_Full
			      | SUPPORTED_100baseT_Half
			      | SUPPORTED_100baseT_Full
			      | SUPPORTED_Autoneg
			      | SUPPORTED_Pause | SUPPORTED_Asym_Pause
			      | SUPPORTED_MII
			      | SUPPORTED_TP);

	phydev->advertising = phydev->supported;

	lp->old_link = 0;
	lp->old_speed = 0;
	lp->old_duplex = -1;
	lp->phydev = phydev;

	printk(KERN_INFO "%s: attached PHY driver [%s] "
	       "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
	       "@sclk=%dMHz)\n",
	       DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
	       MDC_CLK, mdc_div, sclk/1000000);

	return 0;
}
Ejemplo n.º 5
0
static int mii_probe(struct net_device *dev, int phy_mode)
{
	struct bfin_mac_local *lp = netdev_priv(dev);
	struct phy_device *phydev = NULL;
	unsigned short sysctl;
	int i;
	u32 sclk, mdc_div;

	
	if (!(bfin_read_VR_CTL() & CLKBUFOE))
		bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);

	sclk = get_sclk();
	mdc_div = ((sclk / MDC_CLK) / 2) - 1;

	sysctl = bfin_read_EMAC_SYSCTL();
	sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div);
	bfin_write_EMAC_SYSCTL(sysctl);

	
	for (i = 0; i < PHY_MAX_ADDR; ++i) {
		struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i];

		if (!tmp_phydev)
			continue; 

		phydev = tmp_phydev;
		break; 
	}

	
	if (!phydev) {
		netdev_err(dev, "no phy device found\n");
		return -ENODEV;
	}

	if (phy_mode != PHY_INTERFACE_MODE_RMII &&
		phy_mode != PHY_INTERFACE_MODE_MII) {
		netdev_err(dev, "invalid phy interface mode\n");
		return -EINVAL;
	}

	phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
			0, phy_mode);

	if (IS_ERR(phydev)) {
		netdev_err(dev, "could not attach PHY\n");
		return PTR_ERR(phydev);
	}

	
	phydev->supported &= (SUPPORTED_10baseT_Half
			      | SUPPORTED_10baseT_Full
			      | SUPPORTED_100baseT_Half
			      | SUPPORTED_100baseT_Full
			      | SUPPORTED_Autoneg
			      | SUPPORTED_Pause | SUPPORTED_Asym_Pause
			      | SUPPORTED_MII
			      | SUPPORTED_TP);

	phydev->advertising = phydev->supported;

	lp->old_link = 0;
	lp->old_speed = 0;
	lp->old_duplex = -1;
	lp->phydev = phydev;

	pr_info("attached PHY driver [%s] "
	        "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n",
	        phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
	        MDC_CLK, mdc_div, sclk/1000000);

	return 0;
}