/* Auto-Configure this MII interface */ static MII_CONFIG mii_autoconfigure(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); int i; int val; MII_CONFIG eConfig; TRACE(("mii_autoconfigure\n")); /* enable and restart autonegotiation */ val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR); val |= (BMCR_ANRESTART | BMCR_ANENABLE); mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR, val); /* wait for it to finish */ for (i = 0; i < 1000; i++) { mdelay(1); val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMSR); if (val & BMSR_ANEGCOMPLETE) { break; } } eConfig = mii_getconfig(dev); if (val & BMSR_ANEGCOMPLETE) { eConfig |= MII_AUTONEG; } return eConfig; }
static int32_t mvl_mii_read(const struct gcu_adapter *adapter, uint32_t mphy, uint32_t phy_num, uint32_t reg_addr, uint16_t *phy_data) { int32_t cnt, rc; uint16_t smi_cmd_reg; smi_cmd_reg = gen_mvl_smi_cmd_reg(phy_num, reg_addr, MVL_SMI_READ_OP); rc = mii_write(adapter, mphy, MVL_SMI_CMD_REG, smi_cmd_reg); if (rc < 0) return -1; cnt = 0; do { udelay(0x32); rc = mii_read(adapter, mphy, MVL_SMI_CMD_REG, &smi_cmd_reg); if (rc < 0) return -1; if (cnt++ > 10000) return -1; } while ((smi_cmd_reg & (1 << 15))); rc = mii_read(adapter, mphy, MVL_SMI_DATA_REG, phy_data); if (rc < 0) return -1; return 0; }
/* phy_tuning_mse */ void phy_tuning_mse(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); volatile EmacRegisters *emac = pDevCtrl->emac; int phyaddr; int val; int i = 0; int retry = 0; phyaddr = pDevCtrl->EnetInfo.ucPhyAddress; val = mii_read(dev, phyaddr, MII_BRCM_TEST); val |= MII_BRCM_TEST_SHADOW_ENABLE; mii_write(dev, phyaddr, MII_BRCM_TEST, val); // enabled shadow mode do { i++; val = mii_read(dev, phyaddr, MII_AUX_STATUS3); // read the MSE value if ((val & MII_AUX_STATUS3_MSE_MASK) >= 0x4000) { val = mii_read(dev, phyaddr, MII_TX_CONTROL); val &= ~MII_TX_CONTROL_PGA_FIX_ENABLE; mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix disable udelay(100); /* wait ~100usec */ val |= MII_TX_CONTROL_PGA_FIX_ENABLE; mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix enable i = 0; retry++; } if ((i > 12) || (retry > 2)) // read twelve times to ensure good break; } while (1); val = mii_read(dev, phyaddr, MII_BRCM_TEST); val &= ~MII_BRCM_TEST_SHADOW_ENABLE; mii_write(dev, phyaddr, MII_BRCM_TEST, val); // disabled shadow mode }
/* BCM5325E register access through MDC/MDIO */ static void ethsw_mdio_rreg(struct net_device *dev, int page, int reg, uint8 *data, int len) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); volatile EmacRegisters *emac; int cmd, res, ret; int max_retry = 0; emac = pDevCtrl->emac; cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd); cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_READ; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd); do { res = mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17); udelay(10); } while ((max_retry++ < 5) && ((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE)); ret = 0; ret |= mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24) << 0; ret |= mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25) << 16; switch (len) { case 1: *data = (uint8)ret; break; case 2: *(uint16 *)data = (uint16)ret; break; case 4: *(uint32 *)data = ret; break; } }
static void config_phy(int phy_id) { u32 mii_anlpar; full_duplex = 0; mii_anlpar = mii_read(phy_id, MII_ANLPA); if (mii_anlpar != 0xffff) { mii_anlpar = mii_read(phy_id, MII_ANLPA); // read twice to make data stable if ((mii_anlpar & 0x0100) || (mii_anlpar & 0x01C0) == 0x0040) full_duplex = 1; phy_mode = mii_anlpar >> 5; #ifdef USE_RMII if (phy_mode & MII_ANLPA_100M) REG32(ETH_MAC_PSR) |= PSR_OS; else REG32(ETH_MAC_PSR) &= ~PSR_OS; #endif printf("ETH: setting %s %s-duplex based on MII tranceiver #%d\n", (phy_mode & MII_ANLPA_100M) ? "100Mbps" : "10Mbps", full_duplex ? "full" : "half", phy_id); }
void mac_phy_reset(void){ palSetPad(GPIOD, GPIOD_EPHY_NRST); halPolledDelay(BOARD_PHY_HARD_RESET_DELAY); /* PHY soft reset procedure.*/ mii_write(ÐD1, MII_BMCR, BMCR_RESET); while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET) ; mii_write(ÐD1, PHYCTRL2, mii_read(ÐD1, PHYCTRL2) | RMII_RCLKSEL); }
static int mii_get_media_pcs (struct net_device *dev) { __u16 negotiate; __u16 bmsr; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); phy_addr = np->phy_addr; bmsr = mii_read (dev, phy_addr, PCS_BMSR); if (np->an_enable) { if (!(bmsr & MII_BMSR_AN_COMPLETE)) { /* Auto-Negotiation not completed */ return -1; } negotiate = mii_read (dev, phy_addr, PCS_ANAR) & mii_read (dev, phy_addr, PCS_ANLPAR); np->speed = 1000; if (negotiate & PCS_ANAR_FULL_DUPLEX) { printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n"); np->full_duplex = 1; } else { printk (KERN_INFO "Auto 1000 Mbps, half duplex\n"); np->full_duplex = 0; } if (negotiate & PCS_ANAR_PAUSE) { np->tx_flow &= 1; np->rx_flow &= 1; } else if (negotiate & PCS_ANAR_ASYMMETRIC) { np->tx_flow = 0; np->rx_flow &= 1; } /* else tx_flow, rx_flow = user select */ } else { __u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR); printk (KERN_INFO "Operating at 1000 Mbps, "); if (bmcr & MII_BMCR_DUPLEX_MODE) { printk (KERN_CONT "Full duplex\n"); } else { printk (KERN_CONT "Half duplex\n"); } } if (np->tx_flow) printk(KERN_INFO "Enable Tx Flow Control\n"); else printk(KERN_INFO "Disable Tx Flow Control\n"); if (np->rx_flow) printk(KERN_INFO "Enable Rx Flow Control\n"); else printk(KERN_INFO "Disable Rx Flow Control\n"); return 0; }
static int mii_set_media_pcs (struct net_device *dev) { __u16 bmcr; __u16 esr; __u16 anar; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); phy_addr = np->phy_addr; /* Auto-Negotiation? */ if (np->an_enable) { /* Advertise capabilities */ esr = mii_read (dev, phy_addr, PCS_ESR); anar = mii_read (dev, phy_addr, MII_ANAR) & ~PCS_ANAR_HALF_DUPLEX & ~PCS_ANAR_FULL_DUPLEX; if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD)) anar |= PCS_ANAR_HALF_DUPLEX; if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD)) anar |= PCS_ANAR_FULL_DUPLEX; anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC; mii_write (dev, phy_addr, MII_ANAR, anar); /* Soft reset PHY */ mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET); bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | MII_BMCR_RESET; mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(1); } else { /* Force speed setting */ /* PHY Reset */ bmcr = MII_BMCR_RESET; mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); if (np->full_duplex) { bmcr = MII_BMCR_DUPLEX_MODE; printk (KERN_INFO "Manual full duplex\n"); } else { bmcr = 0; printk (KERN_INFO "Manual half duplex\n"); } mii_write (dev, phy_addr, MII_BMCR, bmcr); mdelay(10); /* Advertise nothing */ mii_write (dev, phy_addr, MII_ANAR, 0); } return 0; }
int mii_linkstatus(struct net_device *dev, int phy_id) { int val; val = mii_read(dev, phy_id, MII_BMSR); /* reread: the link status bit is sticky */ val = mii_read(dev, phy_id, MII_BMSR); if (val & BMSR_LSTATUS) return 1; else return 0; }
/** * Check link status * * @v smsc95xx SMSC95xx device * @ret rc Return status code */ static int smsc95xx_check_link ( struct smsc95xx_device *smsc95xx ) { struct net_device *netdev = smsc95xx->netdev; int intr; int rc; /* Read PHY interrupt source */ intr = mii_read ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE ); if ( intr < 0 ) { rc = intr; DBGC ( smsc95xx, "SMSC95XX %p could not get PHY interrupt " "source: %s\n", smsc95xx, strerror ( rc ) ); return rc; } /* Acknowledge PHY interrupt */ if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_SOURCE, intr ) ) != 0 ) { DBGC ( smsc95xx, "SMSC95XX %p could not acknowledge PHY " "interrupt: %s\n", smsc95xx, strerror ( rc ) ); return rc; } /* Check link status */ if ( ( rc = mii_check_link ( &smsc95xx->mii, netdev ) ) != 0 ) { DBGC ( smsc95xx, "SMSC95XX %p could not check link: %s\n", smsc95xx, strerror ( rc ) ); return rc; } DBGC ( smsc95xx, "SMSC95XX %p link %s (intr %#04x)\n", smsc95xx, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr ); return 0; }
int mii_init(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); volatile EmacRegisters *emac; int data32; char *phytype = ""; char *setup = ""; switch(pDevCtrl->EnetInfo.ucPhyType) { case BP_ENET_INTERNAL_PHY: phytype = "Internal PHY"; break; case BP_ENET_EXTERNAL_PHY: phytype = "External PHY"; break; default: printk(KERN_INFO ": Unknown PHY type\n"); return -1; } switch (pDevCtrl->EnetInfo.usConfigType) { case BP_ENET_CONFIG_MDIO: setup = "MDIO"; break; default: setup = "Undefined Interface"; break; } printk(KERN_INFO "Config %s Through %s", phytype, setup); emac = pDevCtrl->emac; switch(pDevCtrl->EnetInfo.ucPhyType) { case BP_ENET_INTERNAL_PHY: /* init mii clock, do soft reset of phy, default is 10Base-T */ emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC; /* reset phy */ mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress); mii_setup(dev); break; case BP_ENET_EXTERNAL_PHY: emac->config |= EMAC_EXT_PHY; emac->mdioFreq = EMAC_MII_PRE_EN | EMAC_MDC; /* reset phy */ mii_soft_reset(dev, pDevCtrl->EnetInfo.ucPhyAddress); data32 = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE); data32 |= ADVERTISE_FDFC; /* advertise flow control capbility */ mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_ADVERTISE, data32); mii_setup(dev); break; default: break; } return 0; }
static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { int phy_addr; struct netdev_private *np = netdev_priv(dev); struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; phy_addr = np->phy_addr; switch (cmd) { case SIOCDEVPRIVATE: break; case SIOCGMIIPHY: miidata->phy_id = phy_addr; break; case SIOCGMIIREG: miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num); break; case SIOCSMIIREG: if (!capable(CAP_NET_ADMIN)) return -EPERM; mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in); break; default: return -EOPNOTSUPP; } return 0; }
/* probe for an external PHY via MDIO; return PHY address */ int mii_probe(struct net_device *dev, void *p) { struct BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); int i; struct bcmemac_platform_data *cfg = p; if (cfg->phy_type != BRCM_PHY_TYPE_EXT_MII) { /* * Enable RGMII to interface external PHY, disable * internal 10/100 MII. */ GENET_RGMII_OOB_CTRL(pDevCtrl) |= RGMII_MODE_EN; /* Power down EPHY */ pDevCtrl->ext->ext_pwr_mgmt |= (EXT_PWR_DOWN_PHY | EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); } for (i = 0; i < 32; i++) { if (mii_read(dev, i, MII_BMSR) != 0) { pDevCtrl->phyAddr = i; if (i == 1) continue; return 0; } TRACE(("I=%d\n", i)); } return -ENODEV; }
void ethmac_start(const uint8_t* address) { // Copy MAC address int i; for (i = 0; i < 6; i++) { mac.mac_address[i] = address[i]; } /* MAC clocks activation and commanded reset procedure.*/ *ethmac_get_DMABMR() |= ETHMAC_DMABMR__SR; while (*ethmac_get_DMABMR() & ETHMAC_DMABMR__SR) ; // Reset the descriptors ethmac_descriptors_reset(); /* ISR vector enabled.*/ nvic_enable_interrupt_line(NVIC_IRQ_LINE_ETH); /* PHY in power up mode.*/ mii_write(MII_BMCR, mii_read(MII_BMCR) & ~MII_BMCR__PDOWN); /* MAC configuration.*/ *ethmac_get_MACFFR() = 0; *ethmac_get_MACFCR() = 0; *ethmac_get_MACVLANTR() = 0; /* MAC address setup.*/ set_mac_address(mac.mac_address); /* Transmitter and receiver enabled. Note that the complete setup of the MAC is performed when the link status is detected.*/ // No checksum offload *ethmac_get_MACCR() = ETHMAC_MACCR__RE | ETHMAC_MACCR__TE; /* DMA configuration: Descriptor chains pointers.*/ *ethmac_get_DMARDLAR() = (uint32_t) ethmac_rx_des; *ethmac_get_DMATDLAR() = (uint32_t) ethmac_tx_des; /* Enabling required interrupt sources.*/ *ethmac_get_DMASR() = (uint32_t) (*ethmac_get_DMASR()); *ethmac_get_DMAIER() = ETHMAC_DMAIER__NISE | ETHMAC_DMAIER__AISE | ETHMAC_DMAIER__RIE | ETHMAC_DMAIER__TIE; /* DMA general settings.*/ *ethmac_get_DMABMR() = ETHMAC_DMABMR__AAB | ETHMAC_DMABMR__RDP_1Beat | ETHMAC_DMABMR__PBL_1Beat; /* Transmit FIFO flush.*/ *ethmac_get_DMAOMR() = ETHMAC_DMAOMR__FTF; while (*ethmac_get_DMAOMR() & ETHMAC_DMAOMR__FTF) ; /* DMA final configuration and start.*/ *ethmac_get_DMAOMR() = ETHMAC_DMAOMR__DTCEFD | ETHMAC_DMAOMR__RSF | ETHMAC_DMAOMR__TSF | ETHMAC_DMAOMR__ST | ETHMAC_DMAOMR__SR; }
/* reset the MII */ static void mii_soft_reset(struct net_device *dev, int PhyAddr) { int val; mii_write(dev, PhyAddr, MII_BMCR, BMCR_RESET); udelay(10); /* wait ~10usec */ do { val = mii_read(dev, PhyAddr, MII_BMCR); } while (val & BMCR_RESET); }
void mii_dump(void) { const struct gcu_adapter *adapter; int phy, r, rc; uint16_t v; adapter = gcu_get_adapter(); if (!adapter) { printk("No adapter??\n"); return; } for (phy = 0; (phy < 32); phy++) { printk("---------------------------------------------------\n"); printk("PHY=%d:\n", phy); for (r = 0; (r < 32); r++) { if ((r % 8) == 0) printk("%04x: ", r); rc = mii_read(adapter, phy, r, &v); if (rc) printk("FFFF "); else printk("%04x ", v); if (((r + 1) % 8) == 0) printk("\n"); } } printk("---------------------------------------------------\n"); dump_mvl(adapter, 2); dump_mvl(adapter, 4); for (phy = 0; (phy < 32); phy++) { printk("---------------------------------------------------\n"); printk("SUB(2) PHY=%d:\n", phy); for (r = 0; (r < 32); r++) { if ((r % 8) == 0) printk("%04x: ", r); rc = mvl_mii_phy_read(adapter, 2, phy, r, &v); if (rc) printk("FFFF "); else printk("%04x ", v); if (((r + 1) % 8) == 0) printk("\n"); } } printk("---------------------------------------------------\n"); gcu_release_adapter(&adapter); }
void mii_dealan(struct local *l, unsigned timo) { unsigned anar, bound; anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA; mii_write(l, l->phy, MII_ANAR, anar); mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); l->anlpar = 0; bound = getsecs() + timo; do { l->bmsr = mii_read(l, l->phy, MII_BMSR) | mii_read(l, l->phy, MII_BMSR); /* read twice */ if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) { l->anlpar = mii_read(l, l->phy, MII_ANLPAR); break; } DELAY(10 * 1000); } while (getsecs() < bound); return; }
static int search_phy(int phy_id) { u32 r; r = mii_read(phy_id, MII_SR); //printf("mii read data MII_SR: 0x%04x\n", r); if (r != 0 && r != 0xffff) { // printf("search_phy: Found phy 0x%x\n", r); return 1; } return 0; }
static void mii_init(au1x00_emac_softc_t *sc) { uint16_t data; mii_write(sc, 0, 0x8000); /* reset */ do { mii_read(sc, 0, &data); } while (data & 0x8000); mii_write(sc, 0, 0x3200); /* reset autonegotiation */ mii_write(sc, 17, 0xffc0); /* setup LEDs */ }
static void pga_fix_enable(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); int val; int phyaddr; phyaddr = pDevCtrl->EnetInfo.ucPhyAddress; val = (MII_BRCM_TEST_HARDRESET | MII_BRCM_TEST_10BT_SERIAL_NODRIB | MII_BRCM_TEST_100TX_POWERDOWN | MII_BRCM_TEST_10BT_POWERDOWN ); mii_write(dev, phyaddr, MII_BRCM_TEST, val); // reset phy val = mii_read(dev, phyaddr, MII_BRCM_TEST); val |= MII_BRCM_TEST_SHADOW_ENABLE; mii_write(dev, phyaddr, MII_BRCM_TEST, val); // shadow mode val = mii_read(dev, phyaddr, MII_TX_CONTROL); val |= MII_TX_CONTROL_PGA_FIX_ENABLE; mii_write(dev, phyaddr, MII_TX_CONTROL, val); // pga fix enable val = mii_read(dev, phyaddr, MII_BRCM_TEST); val &= ~MII_BRCM_TEST_SHADOW_ENABLE; mii_write(dev, phyaddr, MII_BRCM_TEST, val); // shadow mode }
/* set the MII loopback mode */ static void mii_loopback(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); uint32 val; TRACE(("mii_loopback\n")); val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR); /* Disable autonegotiation */ val &= ~BMCR_ANENABLE; /* Enable Loopback */ val |= BMCR_LOOPBACK; mii_write(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_BMCR, val); }
void ethmac_enable() { // Enable the clocks rcc_ahb_enable(RCC_AHB_BIT_ETHMAC); rcc_ahb_enable(RCC_AHB_BIT_ETHMACTX); rcc_ahb_enable(RCC_AHB_BIT_ETHMACRX); // Configure MII uint32_t tmp = *ethmac_get_MACMIIAR(); tmp &= ~ETHMAC_MACMIIAR__CR_MASK; tmp |= mac.mii_cr; *ethmac_get_MACMIIAR() = tmp; // Find the PHY address mii_find_phy_addr(); // Reset the PHY log_debug("Resetting PHY... (was %04x)", mii_read(MII_BMCR)); mii_write(MII_BMCR, MII_BMCR__RESET); while (mii_read(MII_BMCR) & MII_BMCR__RESET) ; log_debug("\tOK (now %04x)", mii_read(MII_BMCR)); }
/** * Reset MII interface * * @v mii MII interface * @ret rc Return status code */ int mii_reset ( struct mii_interface *mii ) { unsigned int i; int bmcr; int rc; /* Power-up, enable autonegotiation and initiate reset */ if ( ( rc = mii_write ( mii, MII_BMCR, ( BMCR_RESET | BMCR_ANENABLE ) ) ) != 0 ) { DBGC ( mii, "MII %p could not write BMCR: %s\n", mii, strerror ( rc ) ); return rc; } /* Wait for reset to complete */ for ( i = 0 ; i < MII_RESET_MAX_WAIT_MS ; i++ ) { /* Check if reset has completed */ bmcr = mii_read ( mii, MII_BMCR ); if ( bmcr < 0 ) { rc = bmcr; DBGC ( mii, "MII %p could not read BMCR: %s\n", mii, strerror ( rc ) ); return rc; } /* If reset is not complete, delay 1ms and retry */ if ( bmcr & BMCR_RESET ) { mdelay ( 1 ); continue; } /* Force autonegotation on again, in case it was * cleared by the reset. */ if ( ( rc = mii_write ( mii, MII_BMCR, BMCR_ANENABLE ) ) != 0 ){ DBGC ( mii, "MII %p could not write BMCR: %s\n", mii, strerror ( rc ) ); return rc; } DBGC ( mii, "MII %p reset after %dms\n", mii, i ); return 0; } DBGC ( mii, "MII %p timed out waiting for reset\n", mii ); return -ETIMEDOUT; }
static int autonet_complete(int phy_id) { int i; for (i = 0; i < MAX_WAIT && !(mii_read(phy_id, MII_SR) & 0x0020); i++, udelay(10)) { ; } if (i == MAX_WAIT) { printf("autonet_comlete: autonet time out!\n"); return -1; } return 0; }
static int mii_wait_link (struct net_device *dev, int wait) { __u16 bmsr; int phy_addr; struct netdev_private *np; np = netdev_priv(dev); phy_addr = np->phy_addr; do { bmsr = mii_read (dev, phy_addr, MII_BMSR); if (bmsr & MII_BMSR_LINK_STATUS) return 0; mdelay (1); } while (--wait > 0); return -1; }
/* return the current MII configuration */ static MII_CONFIG mii_getconfig(struct net_device *dev) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); uint32 val; MII_CONFIG eConfig = 0; TRACE(("mii_getconfig\n")); /* Read the Link Partner Ability */ val = mii_read(dev, pDevCtrl->EnetInfo.ucPhyAddress, MII_LPA); if (val & LPA_100FULL) { /* 100 MB Full-Duplex */ eConfig = (MII_100MBIT | MII_FULLDUPLEX); } else if (val & LPA_100HALF) { /* 100 MB Half-Duplex */ eConfig = MII_100MBIT; } else if (val & LPA_10FULL) { /* 10 MB Full-Duplex */ eConfig = MII_FULLDUPLEX; } return eConfig; }
static void ethsw_mdio_wreg(struct net_device *dev, int page, int reg, uint8 *data, int len) { BcmEnet_devctrl *pDevCtrl = netdev_priv(dev); volatile EmacRegisters *emac; uint32 cmd, res; int val = 0; int max_retry = 0; emac = pDevCtrl->emac; switch (len) { case 1: val = *data; break; case 2: val = *(uint16 *)data; break; case 4: val = *(uint32 *)data; break; } cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd); cmd = val>>0 & 0xffff; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24, cmd); cmd = val>>16 & 0xffff; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25, cmd); cmd = 0; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG26, cmd); cmd = 0; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG27, cmd); cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_WRITE; mii_write(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd); do { res = mii_read(dev, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17); udelay(10); } while ((max_retry++ < 5) && ((res & (REG_PPM_REG17_OP_WRITE|REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE)); }
void mii_switch_unmanage_mode(struct net_device *dev) { uint8 value; BcmEnet_devctrl* pDevCtrl = NULL; /*add of support ADM6996M LSW by l39225 20061218*/ if(dev == NULL) { printk(" dev is NULL\n"); return; } pDevCtrl= netdev_priv(dev); if(pDevCtrl == NULL) { printk(" pDevCtrl is NULL\n"); return; } if ( ESW_TYPE_ADM6996M == pDevCtrl->ethSwitch.type) { int val; val = mii_read(dev,0,SWI_SYSTEM_CTRLREG3); val &= ~0x1800; mii_write(dev, 0, SWI_SYSTEM_CTRLREG3, val); } /*end of support ADM6996M LSW by l39225 20061218*/ else { ethsw_rreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value)); value &= ~REG_SWITCH_MODE_FRAME_MANAGE_MODE; ethsw_wreg(dev, PAGE_CONTROL, REG_SWITCH_MODE, &value, sizeof(value)); value = 0; ethsw_wreg(dev, PAGE_MANAGEMENT, REG_GLOBAL_CONFIG, &value, sizeof(value)); } }
static int find_miiphy (struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); int i, phy_found = 0; np = netdev_priv(dev); np->phy_addr = 1; for (i = 31; i >= 0; i--) { int mii_status = mii_read (dev, i, 1); if (mii_status != 0xffff && mii_status != 0x0000) { np->phy_addr = i; phy_found++; } } if (!phy_found) { printk (KERN_ERR "%s: No MII PHY found!\n", dev->name); return -ENODEV; } return 0; }
void cmd_phy(BaseSequentialStream *chp, int argc, char *argv[]) { uint32_t phy_val = 0; uint32_t reg_to_ping = 0; //uint32_t bmcr_val = 0; if (argc != 1) { chprintf(chp, "Usage: phy reg(decimal)\r\n"); return; } // bmcr_val = mii_read(ÐD1, MII_BMCR); // // mii_write(ÐD1, MII_BMCR, (bmcr_val & ~(1<<12)) ); // // bmcr_val = mii_read(ÐD1, MII_BMCR); // // mii_write(ÐD1, 0x1f,( bmcr_val | 1<<13)); reg_to_ping = atoi(argv[0]); phy_val = mii_read(ÐD1, reg_to_ping); chprintf(chp, "phy reg 0x%x value:\t0x%x\n\r", reg_to_ping, phy_val); }