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配置强制千兆全双工,自协商关闭,即可

相关推荐
待什么青丝3 小时前
【TMS570LC4357】之相关驱动开发学习记录2
c语言·arm开发·驱动开发·单片机·学习
__Benco10 小时前
OpenHarmony平台驱动使用(十五),SPI
人工智能·驱动开发·harmonyos
贝塔实验室2 天前
FPGA 动态重构配置流程
驱动开发·fpga开发·硬件架构·硬件工程·射频工程·fpga·基带工程
thinkMoreAndDoMore3 天前
linux驱动开发(1)-内核模块
linux·运维·驱动开发
待什么青丝4 天前
【TMS570LC4357】之相关驱动开发学习记录1
c语言·arm开发·驱动开发·学习
Narnat5 天前
Rk3568驱动开发_GPIO点亮LED_12
驱动开发
__Benco6 天前
OpenHarmony平台驱动使用(四),GPIO
人工智能·驱动开发·harmonyos
打倒焦虑6 天前
驱动开发学习20250529
驱动开发
Despacito0o7 天前
APM32主控键盘全功能开发实战教程:软件部分
驱动开发·计算机外设
yan123687 天前
Linux 驱动之设备树
android·linux·驱动开发·linux驱动