本文主要是介绍T2080 AR8031 RGMII to 1000Base-X(fiber),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前段时间在调试FT-M6678和C6678的板卡,结果中途来了一个T2080网络配置的更改需求,就临时处理了一下,花了一点功夫,记录下来,为大家做个参考。
这个问题完成后,就得继续开发FT-M6678了~
- uboot下面phy配置更改(board/freescale/tx208xrdb/eth_t208xrdb.c)
a. 配置芯片模式配置为BX1000_RGMII_50
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1F, 0x106); //mode_cfg: 0010 = BX1000_RGMII_50
printf("phy write 0x1F by 0x106!\r\n");
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x0, 0x2100);
printf("phy write 0x0 by 0x2100!\r\n");
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x0, 0x140);
printf("phy write 0x0 by 0x140!\r\n");
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1F, 0x102); //mode_cfg: 0010 = BX1000_RGMII_50
printf("phy write 0x1F by 0x102!\r\n");
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0xD, 0x3);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0xE, 0x805D);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0xD, 0x4003);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0xE, 0x100);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1D, 0x0);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1E, 0x8000);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1D, 0x5);
miiphy_write(DEFAULT_FM_MDIO_NAME, 0x6, 0x1E, 0x100);
//dummy read status
miiphy_read(DEFAULT_FM_MDIO_NAME, 0x6, 0x1, &value);
2. 更改phy.c(drivers/net/phy)
/*** genphy_update_link - update link status in @phydev* @phydev: target phy_device struct** Description: Update the value in phydev->link to reflect the* current link value. In order to do this, we need to read* the status register twice, keeping the second value.*/
int genphy_update_link(struct phy_device *phydev)
{unsigned int mii_reg;/** Wait if the link is up, and autonegotiation is in progress* (ie - we're capable and it's not done)*/mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);/** If we already saw the link up, and it hasn't gone down, then* we don't need to wait for autoneg again*///modifyif (phydev->addr != 6){if (phydev->link && mii_reg & BMSR_LSTATUS)return 0;}else{if (mii_reg & BMSR_LSTATUS) {phydev->link = 1;printf("%s Force Mode", phydev->dev->name);phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, 0x140);return 0;}}if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {int i = 0;printf("%s Waiting for PHY auto negotiation to complete",phydev->dev->name);while (!(mii_reg & BMSR_ANEGCOMPLETE)) {/** Timeout reached ?*/if (i > PHY_ANEG_TIMEOUT) {printf(" TIMEOUT !\n");phydev->link = 0;return 0;}if (ctrlc()) {puts("user interrupt!\n");phydev->link = 0;return -EINTR;}if ((i++ % 500) == 0)printf(".");udelay(1000); /* 1 ms */mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);}printf(" done\n");phydev->link = 1;} else {/* Read the link a second time to clear the latched state */mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);if (mii_reg & BMSR_LSTATUS)phydev->link = 1;elsephydev->link = 0;}return 0;
}
/** Generic function which updates the speed and duplex. If* autonegotiation is enabled, it uses the AND of the link* partner's advertised capabilities and our advertised* capabilities. If autonegotiation is disabled, we use the* appropriate bits in the control register.** Stolen from Linux's mii.c and phy_device.c*/
int genphy_parse_link(struct phy_device *phydev)
{int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);if (phydev->addr != 6){/* We're using autonegotiation */if (phydev->supported & SUPPORTED_Autoneg) {u32 lpa = 0;int gblpa = 0;u32 estatus = 0;/* Check for gigabit capability */if (phydev->supported & (SUPPORTED_1000baseT_Full |SUPPORTED_1000baseT_Half)) {/* We want a list of states supported by* both PHYs in the link*/gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);if (gblpa < 0) {debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");gblpa = 0;}gblpa &= phy_read(phydev,MDIO_DEVAD_NONE, MII_CTRL1000) << 2;}/* Set the baseline so we only have to set them* if they're different*/phydev->speed = SPEED_10;phydev->duplex = DUPLEX_HALF;/* Check the gigabit fields */if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {phydev->speed = SPEED_1000;if (gblpa & PHY_1000BTSR_1000FD)phydev->duplex = DUPLEX_FULL;/* We're done! */return 0;}lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);if (lpa & (LPA_100FULL | LPA_100HALF)) {phydev->speed = SPEED_100;if (lpa & LPA_100FULL)phydev->duplex = DUPLEX_FULL;} else if (lpa & LPA_10FULL)phydev->duplex = DUPLEX_FULL;/** Extended status may indicate that the PHY supports* 1000BASE-T/X even though the 1000BASE-T registers* are missing. In this case we can't tell whether the* peer also supports it, so we only check extended* status if the 1000BASE-T registers are actually* missing.*/if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))estatus = phy_read(phydev, MDIO_DEVAD_NONE,MII_ESTATUS);if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {phydev->speed = SPEED_1000;if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_TFULL))phydev->duplex = DUPLEX_FULL;}} else {u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);phydev->speed = SPEED_10;phydev->duplex = DUPLEX_HALF;if (bmcr & BMCR_FULLDPLX)phydev->duplex = DUPLEX_FULL;if (bmcr & BMCR_SPEED1000)phydev->speed = SPEED_1000;else if (bmcr & BMCR_SPEED100)phydev->speed = SPEED_100;}}else{u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);phydev->speed = SPEED_10;phydev->duplex = DUPLEX_HALF;if (bmcr & BMCR_FULLDPLX)phydev->duplex = DUPLEX_FULL;if (bmcr & BMCR_SPEED1000)phydev->speed = SPEED_1000;else if (bmcr & BMCR_SPEED100)phydev->speed = SPEED_100;}return 0;
}
2. 在内核系统启动后,依次输入如下指令:
ifconfig fm1-mac1 192.168.1.130 up
ifconfig fm1-mac3 192.168.2.130 up
ethtool -s fm1-mac3 speed 1000 duplex full autoneg off
使用ethtool配置强制千兆全双工,自协商关闭,即可
这篇关于T2080 AR8031 RGMII to 1000Base-X(fiber)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!