Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
	}
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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 */
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
Arquivo: macb.c Projeto: DFE/u-boot
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;
}