static int phy_autoneg(struct net_device *dev) { struct tangox_enet_priv *priv; int loop; unsigned int val = 0; priv = netdev_priv(dev); /* reset phy */ val = enet_mdio_read(dev, priv->mii.phy_id, MII_BMCR); enet_mdio_write(dev, priv->mii.phy_id, MII_BMCR, val | BMCR_ANENABLE|BMCR_ANRESTART); udelay(100); loop = 10000; while (loop) { if (enet_mdio_read(dev, priv->mii.phy_id, MII_BMSR) & BMSR_ANEGCOMPLETE) break; mdelay(1); loop--; } if (!loop) { printk(KERN_ERR "%s: PHY autonegotiation does not complete...\n", priv->name); return -EBUSY; } return 0; }
static int phy_reset(struct net_device *dev) { struct tangox_enet_priv *priv; int loop; unsigned int val = 0; priv = netdev_priv(dev); /* reset phy */ val = enet_mdio_read(dev, priv->mii.phy_id, MII_BMCR); enet_mdio_write(dev, priv->mii.phy_id, MII_BMCR, val | BMCR_RESET); /* wait for the reset bit to clear */ udelay(100); loop = 100; while (loop) { if (!(enet_mdio_read(dev, priv->mii.phy_id, MII_BMCR) & BMCR_RESET)) break; mdelay(1); loop--; } if (!loop) { printk(KERN_ERR "%s: PHY reset does not complete...\n", priv->name); return -EBUSY; } return 0; }
static void enet_mac_config(struct net_device *dev) { struct tangox_enet_priv *priv; unsigned char val; int speed; priv = netdev_priv(dev); if(priv->rgmii == 0) { /* 100 baseT, realtek*/ val = enet_readb(ENET_MAC_MODE(priv->enet_mac_base)); if(val & (GMAC_MODE | RGMII_MODE)){ val &= ~(GMAC_MODE | RGMII_MODE); /*disable Gigabit mode for now*/ //val |= /*LB_EN |*/ BST_EN; /*loopback off, burst on*/ enet_writeb(ENET_MAC_MODE(priv->enet_mac_base), val); } return; } /*set RGMII skew timing compensation enable */ /* This added 2ns delay to RX_CLK and TX_CLK*/ val = enet_mdio_read(dev, priv->mii.phy_id, MII_RESV1); enet_mdio_write(dev, priv->mii.phy_id, MII_RESV1 , val | (1<<8)); val = enet_readl(ENET_MAC_MODE(priv->enet_mac_base)); speed = enet_get_speed(dev); if(speed == 1000 ){ if((val & RGMII_MODE) && (val & GMAC_MODE)) return; /* configured for gigabit */ val |= RGMII_MODE; val |= GMAC_MODE; enet_writeb(ENET_MAC_MODE(priv->enet_mac_base), val); //printk("set 1000mbps val=0x%x\n", val); }else if(speed == 100){ if((val & RGMII_MODE) && !(val & GMAC_MODE)) return; /* configured for 100mbps*/ val |= RGMII_MODE; val &= ~GMAC_MODE; enet_writeb(ENET_MAC_MODE(priv->enet_mac_base), val); //printk("set 100mbps val=0x%x\n", val); }else /*TODO*/ ; //printk("set 10 mbps or other val=0x%x\n", val); /*set threshold for internal clock 0x1*/ enet_writeb(ENET_IC_THRESHOLD(priv->enet_mac_base), (speed==1000 ? 3:1)); /*set slot time 0x7f for 10/100Mbps*/ enet_writeb(ENET_SLOT_TIME(priv->enet_mac_base), (speed==1000 ? 0xff : 0x7f)); //phy_autoneg(dev); }
int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr, uint16_t data) { return enet_mdio_write((struct enet*)bus->priv, phyAddr, regAddr, data); }