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

相关推荐
嵌入(师)6 小时前
嵌入式驱动开发详解21(网络驱动开发)
网络·驱动开发
hhhhhhh_hhhhhh_2 天前
rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)
驱动开发
icy、泡芙2 天前
T527-----音频调试
linux·驱动开发·音视频
7yewh3 天前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
疯狂飙车的蜗牛3 天前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
嵌入式进阶行者4 天前
【驱动开发初级】内核模块静态和动态添加功能的步骤
驱动开发
逝灮4 天前
【蓝桥杯——物联网设计与开发】拓展模块3 - 温度传感器模块
驱动开发·stm32·单片机·嵌入式硬件·物联网·蓝桥杯·温度传感器
__NULL__USER5 天前
petalinux-adi ---添加AD9361驱动(二)
linux·驱动开发
7yewh5 天前
嵌入式驱动RK3566 HDMI eDP MIPI 背光 屏幕选型与调试提升篇-eDP屏
linux·arm开发·驱动开发·嵌入式硬件·嵌入式linux·rk·edp
少年、潜行6 天前
树莓派3B+驱动开发(8)- i2c控制PCF8591
驱动开发·树莓派·3b+