T2080 AR8031 RGMII to 1000Base-X(fiber)

前段时间在调试FT-M6678和C6678的板卡,结果中途来了一个T2080网络配置的更改需求,就临时处理了一下,花了一点功夫,记录下来,为大家做个参考。

这个问题完成后,就得继续开发FT-M6678了~

  1. 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);
  1. 更改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
      */
     //modify
     if (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;
         else
             phydev->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配置强制千兆全双工,自协商关闭,即可

相关推荐
cxr82811 小时前
SPARC方法论在Claude Code基于规则驱动开发中的应用
人工智能·驱动开发·claude·智能体
sukalot18 小时前
window显示驱动开发—显示适配器的子设备
驱动开发
Evan_ZGYF丶1 天前
【RK3576】【Android14】如何在Android14下单独编译kernel-6.1?
linux·驱动开发·android14·rk3576
sukalot2 天前
window显示驱动开发—视频呈现网络简介
驱动开发
sukalot2 天前
window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(二)
驱动开发
zwhSunday2 天前
Linux驱动开发(1)概念、环境与代码框架
linux·运维·驱动开发
sukalot3 天前
window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(三)
驱动开发
sukalot3 天前
window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(一)
驱动开发
cxr8284 天前
基于Claude Code的 规范驱动开发(SDD)指南
人工智能·hive·驱动开发·敏捷流程·智能体
zwhSunday5 天前
Linux驱动开发(2)进一步理解驱动
linux·驱动开发