int _kc_mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) { struct net_device *dev = mii->dev; u32 advert, bmcr, lpa, nego; ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); /* only supports twisted-pair */ ecmd->port = PORT_MII; /* only supports internal transceiver */ ecmd->transceiver = XCVR_INTERNAL; /* this isn't fully supported at higher layers */ ecmd->phy_address = mii->phy_id; ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); if (advert & ADVERTISE_10HALF) ecmd->advertising |= ADVERTISED_10baseT_Half; if (advert & ADVERTISE_10FULL) ecmd->advertising |= ADVERTISED_10baseT_Full; if (advert & ADVERTISE_100HALF) ecmd->advertising |= ADVERTISED_100baseT_Half; if (advert & ADVERTISE_100FULL) ecmd->advertising |= ADVERTISED_100baseT_Full; bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA); if (bmcr & BMCR_ANENABLE) { ecmd->advertising |= ADVERTISED_Autoneg; ecmd->autoneg = AUTONEG_ENABLE; nego = mii_nway_result(advert & lpa); if (nego == LPA_100FULL || nego == LPA_100HALF) ecmd->speed = SPEED_100; else ecmd->speed = SPEED_10; if (nego == LPA_100FULL || nego == LPA_10FULL) { ecmd->duplex = DUPLEX_FULL; mii->full_duplex = 1; } else { ecmd->duplex = DUPLEX_HALF; mii->full_duplex = 0; } } else { ecmd->autoneg = AUTONEG_DISABLE; ecmd->speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; } /* ignore maxtxpkt, maxrxpkt for now */ return 0; }
static int macb_phy_init(struct macb_device *macb) { struct eth_device *netdev = &macb->netdev; u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", netdev->name); return 0; } status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ macb_phy_reset(macb); for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { status = macb_mdio_read(macb, MII_BMSR); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", netdev->name, status); return 0; } else { adv = macb_mdio_read(macb, MII_ADVERTISE); lpa = macb_mdio_read(macb, MII_LPA); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", netdev->name, speed ? "100" : "10", duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); if (speed) ncfgr |= MACB_BIT(SPD); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; } }
static int at91emac_phy_init(struct eth_device *netdev) { u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; at91_emac_t *emac; emac = (at91_emac_t *) netdev->iobase; /* Check if the PHY is up to snuff... */ at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_PHYSID1, &phy_id); if (phy_id == 0xffff) { printf("%s: No PHY present\n", netdev->name); return 1; } at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &status); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ if (at91emac_phy_reset(netdev)) return 2; for (i = 0; i < 100000 / 100; i++) { at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &status); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { VERBOSEP("%s: link down\n", netdev->name); return 3; } else { at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_ADVERTISE, &adv); at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_LPA, &lpa); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; VERBOSEP("%s: link up, %sMbps %s-duplex\n", netdev->name, speed ? "100" : "10", duplex ? "full" : "half"); } return 0; }
/** * mii_check_media - check the MII interface for a duplex change * @mii: the MII interface * @ok_to_print: OK to print link up/down messages * @init_media: OK to save duplex mode in @mii * * Returns 1 if the duplex mode changed, 0 if not. * If the media type is forced, always returns 0. */ unsigned int mii_check_media (struct mii_if_info *mii, unsigned int ok_to_print, unsigned int init_media) { unsigned int old_carrier, new_carrier; int advertise, lpa, media, duplex; int lpa2 = 0; /* if forced media, go no further */ if (mii->force_media) return 0; /* duplex did not change */ /* check current and old link status */ old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0; new_carrier = (unsigned int) mii_link_ok(mii); /* if carrier state did not change, this is a "bounce", * just exit as everything is already set correctly */ if ((!init_media) && (old_carrier == new_carrier)) return 0; /* duplex did not change */ /* no carrier, nothing much to do */ if (!new_carrier) { netif_carrier_off(mii->dev); if (ok_to_print) netdev_info(mii->dev, "link down\n"); return 0; /* duplex did not change */ } /* * we have carrier, see who's on the other end */ netif_carrier_on(mii->dev); /* get MII advertise and LPA values */ if ((!init_media) && (mii->advertising)) advertise = mii->advertising; else { advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE); mii->advertising = advertise; } lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA); if (mii->supports_gmii) lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000); /* figure out media and duplex from advertise and LPA values */ media = mii_nway_result(lpa & advertise); duplex = (media & ADVERTISE_FULL) ? 1 : 0; if (lpa2 & LPA_1000FULL) duplex = 1; if (ok_to_print) netdev_info(mii->dev, "link up, %uMbps, %s-duplex, lpa 0x%04X\n", lpa2 & (LPA_1000FULL | LPA_1000HALF) ? 1000 : media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 100 : 10, duplex ? "full" : "half", lpa); if ((init_media) || (mii->full_duplex != duplex)) { mii->full_duplex = duplex; return 1; /* duplex changed */ } return 0; /* duplex did not change */ }
static int macb_phy_init(struct macb_device *macb, const char *name) #endif { #ifdef CONFIG_DM_ETH struct macb_device *macb = dev_get_priv(dev); #endif u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; arch_get_mdio_control(name); /* Auto-detect phy_addr */ if (!macb_phy_find(macb, name)) return 0; /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", name); return 0; } #ifdef CONFIG_PHYLIB #ifdef CONFIG_DM_ETH macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev, macb->phy_interface); #else /* need to consider other phy interface mode */ macb->phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev, PHY_INTERFACE_MODE_RGMII); #endif if (!macb->phydev) { printf("phy_connect failed\n"); return -ENODEV; } phy_config(macb->phydev); #endif status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ macb_phy_reset(macb, name); for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) { status = macb_mdio_read(macb, MII_BMSR); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", name, status); return 0; } /* First check for GMAC and that it is GiB capable */ if (gem_is_gigabit_capable(macb)) { lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (LPA_1000FULL | LPA_1000HALF)) { duplex = ((lpa & LPA_1000FULL) ? 1 : 0); printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n", name, duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); ncfgr |= GEM_BIT(GBE); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; } } /* fall back for EMAC checking */ adv = macb_mdio_read(macb, MII_ADVERTISE); lpa = macb_mdio_read(macb, MII_LPA); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", name, speed ? "100" : "10", duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE)); if (speed) ncfgr |= MACB_BIT(SPD); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; }
static int ftgmac100_phy_init(struct eth_device *dev) { struct ftgmac100_data *priv = dev->priv; int phy_addr; u16 phy_id, status, adv, lpa, stat_ge; int media, speed, duplex; int i; /* Check if the PHY is up to snuff... */ for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) { ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id); /* * When it is unable to found PHY, * the interface usually return 0xffff or 0x0000 */ if (phy_id != 0xffff && phy_id != 0x0) { printf("%s: found PHY at 0x%02x\n", dev->name, phy_addr); priv->phy_addr = phy_addr; break; } } if (phy_id == 0xffff || phy_id == 0x0) { printf("%s: no PHY present\n", dev->name); return 0; } ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ ftgmac100_phy_reset(dev); for (i = 0; i < 100000 / 100; i++) { ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down\n", dev->name); return 0; } #ifdef CONFIG_FTGMAC100_EGIGA /* 1000 Base-T Status Register */ ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge); speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF) ? 1 : 0); duplex = ((stat_ge & LPA_1000FULL) ? 1 : 0); if (speed) { /* Speed is 1000 */ printf("%s: link up, 1000bps %s-duplex\n", dev->name, duplex ? "full" : "half"); return 0; } #endif ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv); ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex\n", dev->name, speed ? "100" : "10", duplex ? "full" : "half"); return 1; }
static int macb_phy_init(struct macb_device *macb) { struct eth_device *netdev = &macb->netdev; #ifdef CONFIG_PHYLIB struct phy_device *phydev; #endif u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; arch_get_mdio_control(netdev->name); #ifdef CONFIG_MACB_SEARCH_PHY /* Auto-detect phy_addr */ if (!macb_phy_find(macb)) { return 0; } #endif /* CONFIG_MACB_SEARCH_PHY */ /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", netdev->name); return 0; } #ifdef CONFIG_PHYLIB phydev->bus = macb->bus; phydev->dev = netdev; phydev->addr = macb->phy_addr; phy_config(phydev); #endif status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ macb_phy_reset(macb); for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { status = macb_mdio_read(macb, MII_BMSR); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", netdev->name, status); return 0; } /* First check for GMAC */ if (macb_is_gem(macb)) { lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (1 << 11)) { speed = 1000; duplex = 1; } else { if (lpa & (1 << 10)) { speed = 1000; duplex = 1; } else { speed = 0; } } if (speed == 1000) { printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n", netdev->name, speed, duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD)); if (speed) ncfgr |= GEM_BIT(GBE); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; } } /* fall back for EMAC checking */ adv = macb_mdio_read(macb, MII_ADVERTISE); lpa = macb_mdio_read(macb, MII_LPA); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", netdev->name, speed ? "100" : "10", duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); if (speed) ncfgr |= MACB_BIT(SPD); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; }
static int _nic_wired_max_bit_rate(char *dev) { int rate=0; int skfd=0; unsigned int lpa, bmcr, advert; struct ifreq ifr; struct mii_ioctl_data * mii_data; if(!securesoho_nic_check_ifc_link(dev, strlen(dev))){ /* not link up */ fprintf(stdout, "F:%s:%d, %s Net Link Down\n", __FUNCTION__, __LINE__, dev); goto out; } if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) { printf("socket error\n"); goto out; } sprintf(ifr.ifr_name, "%s", dev); if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) { printf("%s:%d [%s] errno=%d (%s)\n", __FUNCTION__, __LINE__, dev, errno, strerror(errno)); close(skfd); return 0; } mii_data = (struct mii_ioctl_data *) &(ifr.ifr_data); mii_data->reg_num = MII_BMCR; mii_data->val_out = 0; if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { printf("%s:%d [%s] errno=%d (%s)\n", __FUNCTION__, __LINE__, dev, errno, strerror(errno)); goto out; } bmcr = (unsigned int)(mii_data->val_out); mii_data = (struct mii_ioctl_data *) &(ifr.ifr_data); mii_data->val_out = 0; mii_data->reg_num = MII_ADVERTISE; if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { printf("%s:%d [%s] errno=%d (%s)\n", __FUNCTION__, __LINE__, dev, errno, strerror(errno)); goto out; } advert = (unsigned int)(mii_data->val_out); mii_data = (struct mii_ioctl_data *) &(ifr.ifr_data); mii_data->val_out = 0; mii_data->reg_num = MII_LPA; if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { printf("%s:%d [%s] errno=%d (%s)\n", __FUNCTION__, __LINE__, dev, errno, strerror(errno)); goto out; } lpa = (unsigned int)(mii_data->val_out); if (bmcr & BMCR_ANENABLE){ unsigned int nego; nego = mii_nway_result(advert & lpa); switch(nego){ case LPA_10FULL: case LPA_10HALF: rate = NIC_RATE_10MBPS; //fprintf(stdout, "F:%s:%d, 10Mbps Net Link\n", __FUNCTION__, __LINE__); break; case LPA_100FULL: case LPA_100BASE4: case LPA_100HALF: rate = NIC_RATE_100MBPS; //fprintf(stdout, "F:%s:%d, 100Mbps Net Link\n", __FUNCTION__, __LINE__); break; default: /* default set link speed to 100Mbps */ rate = NIC_RATE_10MBPS; //fprintf(stdout, "F:%s:%d, default set 10Mbps Net Link,%d\n", __FUNCTION__, __LINE__, lpa); break; } }else{ rate = (bmcr & BMCR_SPEED100)?(NIC_RATE_100MBPS):(NIC_RATE_10MBPS); //fprintf(stdout, "F:%s:%d, default set Net Link,%d\n", __FUNCTION__, __LINE__, rate); } out: if(skfd > 0) close(skfd); return rate; }