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; }
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); }
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; }
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; }
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; }