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

相关推荐
颖火虫盟主16 小时前
规范驱动开发(Spec-Driven Development)
驱动开发
charlie1145141911 天前
嵌入式Linux驱动开发——新 API 字符设备驱动完整教程 - 从设备结构体到应用测试
linux·运维·驱动开发
长安第一美人2 天前
RT-Thread 工业屏驱动开发实战:UART 串口屏协议解析 + 数据实时刷新 + 设备驱动框架完整实现
驱动开发·嵌入式硬件·rt-thread·工业控制·uart通信·串口屏驱动
不怕犯错,就怕不做2 天前
RK3562的CPU如何降频及关闭硬件编解码
linux·驱动开发·嵌入式硬件
可可西里_X_back2 天前
Linux学习(二)- 驱动开发步骤
linux·驱动开发·学习
云天AI实战派3 天前
AI 智能体/API 调用故障排查指南:实时语音、Codex 权限与 Spec 驱动开发全流程修复手册
人工智能·驱动开发·chatgpt·api·codex
小猪写代码3 天前
Linux 驱动开发
驱动开发
小猪写代码3 天前
字符设备驱动开发基础实验
驱动开发
l1t3 天前
DeepSeek总结的使用 eBPF 和硬件断点跟踪 PostgreSQL
数据库·驱动开发·postgresql
高翔·权衡之境3 天前
缓存一致性——多核系统的默契之约
驱动开发·嵌入式硬件·安全·缓存·系统安全·信息与通信