static int emaclite_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { u32 ret; u16 val = 0; ret = phyread(bus->priv, addr, reg, &val); debug("emaclite: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg, val, ret); return val; }
static int axiemac_miiphy_read(const char *devname, uchar addr, uchar reg, ushort *val) { struct eth_device *dev = eth_get_dev(); u32 ret; ret = phyread(dev, addr, reg, val); debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val); return ret; }
static int zynq_gem_miiphyread(const char *devname, uchar addr, uchar reg, ushort *val) { struct eth_device *dev = eth_get_dev(); int ret; ret = phyread(dev, addr, reg, val); debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); return ret; }
static int axiemac_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { int ret; u16 value; ret = phyread(bus->priv, addr, reg, &value); debug("axiemac: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg, value, ret); return value; }
static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { struct zynq_gem_priv *priv = bus->priv; int ret; u16 val; ret = phyread(priv, addr, reg, &val); debug("%s 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val, ret); return val; }
static int phy_detection(struct udevice *dev) { int i; u16 phyreg; struct zynq_gem_priv *priv = dev->priv; if (priv->phyaddr != -1) { phyread(priv, priv->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", priv->phyaddr); return 0; } else { debug("PHY address is not setup correctly %d\n", priv->phyaddr); priv->phyaddr = -1; } } debug("detecting phy address\n"); if (priv->phyaddr == -1) { /* detect the PHY address */ for (i = 31; i >= 0; i--) { phyread(priv, i, PHY_DETECT_REG, &phyreg); if ((phyreg != 0xFFFF) && ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { /* Found a valid PHY address */ priv->phyaddr = i; debug("Found valid phy address, %d\n", i); return 0; } } } printf("PHY is not detected\n"); 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, ®s->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; }
void at91rm9200_emac_init_hw(at91rm9200_emac_softc_t *sc) { int i; /* Configure shared pins for Ethernet, not GPIO */ PIOA_REG(PIO_PDR) = ( BIT7 | /* tx clock */ BIT8 | /* tx enable */ BIT9 | /* tx data 0 */ BIT10 | /* tx data 1 */ BIT11 | /* carrier sense */ BIT12 | /* rx data 0 */ BIT13 | /* rx data 1 */ BIT14 | /* rx error */ BIT15 | /* MII clock */ BIT16 ); /* MII data */ PIOB_REG(PIO_PDR) = ( BIT12 | /* tx data 2 */ BIT13 | /* tx data 3 */ BIT14 | /* tx error */ BIT15 | /* rx data 2 */ BIT16 | /* rx data 3 */ BIT17 | /* rx data valid */ BIT18 | /* rx collistion */ BIT19 ); /* rx clock */ PIOB_REG(PIO_BSR) = ( BIT12 | /* tx data 2 */ BIT13 | /* tx data 3 */ BIT14 | /* tx error */ BIT15 | /* rx data 2 */ BIT16 | /* rx data 3 */ BIT17 | /* rx data valid */ BIT18 | /* rx collistion */ BIT19 ); /* rx clock */ /* Enable the clock to the EMAC */ PMC_REG(PMC_PCER) |= PMC_PCR_PID_EMAC; /* initialize our receive buffer descriptors */ for (i = 0; i < NUM_RXBDS-1; i++) { rxbuf_hdrs[i].address = (unsigned long)(&rxbuf[i * RX_BUFFER_SIZE]); rxbuf_hdrs[i].status = 0x00000000; } /* last one needs the wrapbit set as well */ rxbuf_hdrs[i].address = ((unsigned long)(&rxbuf[i * RX_BUFFER_SIZE]) | RXBUF_ADD_WRAP); rxbuf_hdrs[i].status = 0x00000000; /* point to our receive buffer queue */ EMAC_REG(EMAC_RBQP) = (unsigned long)rxbuf_hdrs; /* clear any left over status bits */ EMAC_REG(EMAC_RSR) &= ~(EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA); /* set the MII clock divder to MCK/64 */ EMAC_REG(EMAC_CFG) &= EMAC_CFG_CLK_MASK; EMAC_REG(EMAC_CFG) = (EMAC_CFG_CLK_64 | EMAC_CFG_BIG | EMAC_CFG_FD); /* enable the MII interface */ EMAC_REG(EMAC_CTL) = EMAC_CTL_MPE; #if csb637 { int timeout; uint32_t emac_link_status; #if defined(PHY_DBG) printk("EMAC: Getting Link Status.\n"); #endif /* read the PHY ID registers */ emac_link_status = phyread(0x02); emac_link_status = phyread(0x03); /* Get the link status - wait for done with a timeout */ for (timeout = 10000 ; timeout ; ) { for (i = 0; i < 100; i++) ; emac_link_status = phyread(0x01); if (!(emac_link_status & PHY_STAT_AUTO_NEG_ABLE)) { #if defined(PHY_DBG) printk("EMAC: PHY is unable to Auto-Negotatiate!\n"); #endif timeout = 0; break; } if (emac_link_status & PHY_STAT_AUTO_NEG_DONE) { #if defined(PHY_DBG) printk("EMAC: Auto-Negotiate Complete, Link = "); #endif break; } timeout-- ; } if (!timeout) { #if defined(PHY_DBG) printk( "EMAC: Auto-Negotatiate Failed, Status = 0x%04lx!\n" "EMAC: Initialization Halted.\n", emac_link_status ); #endif /* if autonegotiation fails, just force to 10HD... */ emac_link_status = PHY_STAT_10BASE_HDX; } /* Set SPD and FD based on the return link status */ if (emac_link_status & (PHY_STAT_100BASE_X_FDX | PHY_STAT_100BASE_X_HDX)){ EMAC_REG(EMAC_CFG) |= EMAC_CFG_SPD; #if defined(PHY_DBG) printk("100MBIT, "); #endif } else { EMAC_REG(EMAC_CFG) &= ~EMAC_CFG_SPD; #if defined(PHY_DBG) printk("10MBIT, "); #endif } if (emac_link_status & (PHY_STAT_100BASE_X_FDX | PHY_STAT_10BASE_FDX)) { EMAC_REG(EMAC_CFG) |= EMAC_CFG_FD; #if defined(PHY_DBG) printk("Full Duplex.\n"); #endif } else { EMAC_REG(EMAC_CFG) &= ~EMAC_CFG_FD; #if defined(PHY_DBG) printk("Half Duplex.\n"); #endif } /* Set PHY LED modes. Traffic Meter Mode for ACTLED * Set Bit 6 - Traffic Mode on */ phywrite(0x1b, PHY_AUX_MODE2_TRAFFIC_LED); } #else /* must be csb337 */ /* Set PHY LED2 to combined Link/Activity and enable pulse stretching */ phywrite( 18, 0x0d0a ); #endif #if 0 EMAC_REG(EMAC_MAN) = (0x01 << 30 | /* Start of Frame Delimiter */ 0x01 << 28 | /* Operation, 0x01 = Write */ 0x00 << 23 | /* Phy Number */ 0x14 << 18 | /* Phy Register */ 0x02 << 16 | /* must be 0x02 */ 0x0D0A); /* Write data (0x0000 if read) */ #endif } /* at91rm9200_emac_init_hw() */
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; }
/* 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(®s->emmc); emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; emmc_reg |= speed; /* Write new speed setting out to Axi Ethernet */ out_be32(®s->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; }
/* 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(®s->emmc); emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; emmc_reg |= speed; /* Write new speed setting out to Axi Ethernet */ writel(emmc_reg, ®s->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; }