Linux-PHY 88E1512 驱动调试记录

1. 简介

1)开发板平台:创龙 AM5728 (tl5728-easy-evm)
2)PHY芯片:Marvell 88E1512

88E1512和88E1510都是一个系列的phy,采用marvell的通用phy驱动,驱动源码路径如下:drivers/net/phy/marvell.c

2. 应用场景

1)系统框图
在这里插入图片描述
AM5728连接两个PHY,PHY0的工作模式是 RGMII to Copper (RGMII到电口),PHY1的工作模式是 RGMII to SGMII。
两个PHY与处理器的连接方式都是RGMII,只是PHY出口的电气接口不一样,一个到电口,一个到SGMII与交换芯片相连。

2)硬件原理图:
LAN0
在这里插入图片描述
LAN1

在这里插入图片描述

3. 芯片手册

PHY的工作模式:(P5)
在这里插入图片描述
几种电气接口的解释:(P33)
MDI:传输媒介接口
RGMII:系统接口
SGMII:系统接口/传输媒介接口
在这里插入图片描述
在这里插入图片描述
PHY的工作模式选择:Page 18 – Register 20
在这里插入图片描述
在这里插入图片描述
寄存器读写的API:
在这里插入图片描述
读写88E1512的寄存器前,先往Register 22写入要操作的 Page number。我们这里要操作的是 Page 18,Register 20,用于配置PHY的工作模式MODE[2:0]

在这里插入图片描述
在这里插入图片描述

4. 修改的地方

1)设备树 (创龙)

AM57xx\Linux-RT\kernel\Linux-RT-4.9.65\arch\arm\boot\dts\am57xx-beagle-x15-common.dtsi

在这里插入图片描述
在这里插入图片描述

phy-mode属性是“rgmii-id”, “rgmii-id”和“rgmii”是有区别的,主要体现在RX和TX的延时是由MAC补偿还是由PHY补偿。如下:
(参考:http://www.360doc.com/content/19/0804/20/36367108_852988840.shtml

在这里插入图片描述
内核文档
AM57xx\Linux-RT\kernel\Linux-RT-4.9.65\Documentation\devicetree\bindings\net\ethernet.txt

对 phy-mode 属性进行了详细介绍,可以阅读查看。

上面的3个节点未做修改,创龙底板使用的PHY是KSZ9031(RGMII to Copper),沿用了这3个节点的属性。

2)驱动源码修改
AM57xx\Linux-RT\kernel\Linux-RT-4.9.65\drivers\net\phy\marvell.c

主要是修改了初始化函数:m88e1510_config_init(),根据设备树中的 operating-mode 属性来判断PHY的工作模式,以此来写寄存器的值。
在这里插入图片描述

/* add by heat */
static int m88e1510_config_init(struct phy_device *phydev)
{
    int err;
    int temp;
    u32 mode_num;

    int ret;
    struct device_node *np = phydev->mdio.dev.of_node;

    ret = of_property_read_u32(np, "operating-mode", &mode_num);

    if (ret) {
        printk("invalid 'operating-mode' property: %d\n", ret);
        return ret;     
    } else {
        if (0 == mode_num ) {
            /* RGMII-to-Copper mode initialization */
            printk("=== Enter RGMII-to Copper mode initialization. === \n");
            if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
                /* Select page 18 */
                err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18);
                if (err < 0)
                    return err;

                /* In reg 20, write MODE[2:0] = 0x0 (RGMII to Copper) */
                temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1);
                temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK;
                temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_TO_COPPER; 
                err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp);
                if (err < 0)
                    return err;

                /* PHY reset is necessary after changing MODE[2:0] */
                temp |= MII_88E1510_GEN_CTRL_REG_1_RESET;
                err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp);
                if (err < 0)
                    return err;

                /* heat test */
                /* Select page 18 */
                err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18);
                if (err < 0)
                    return err;
                /* read reg 22 */
                temp = phy_read(phydev, MII_MARVELL_PHY_PAGE);
                printk("=== ETH0: Reg22 : 0x%x . === \n", temp);

                /* In reg 20, write MODE[2:0] = 0x0 (RGMII to Copper) */
                temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1);
                printk("=== ETH0: Reg20_Page18 : 0x%x . === \n", temp);
    
                /* Reset page selection */
                err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
                if (err < 0)
                    return err;

            }
        } else if (2 == mode_num) {
            /* RGMII-to-1000BASE-X mode initialization */
            printk("=== Enter RGMII-to-1000BASE-X mode initialization. === \n");
            if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
                /* Select page 18 */
                err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18);
                if (err < 0)
                    return err;

                /* In reg 20, write MODE[2:0] = 0x4 (RGMII to SGMII) */
                temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1);
                temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK;
                temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_TO_1000BASE_X;    /* RGMII-to-1000BASE-X */
                err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp);
                if (err < 0)
                    return err;

                /* PHY reset is necessary after changing MODE[2:0] */
                temp |= MII_88E1510_GEN_CTRL_REG_1_RESET;
                err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp);
                if (err < 0)
                    return err;

                /* heat test */
                /* Select page 18 */
                err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18);
                if (err < 0)
                    return err;
                /* read reg 22 */
                temp = phy_read(phydev, MII_MARVELL_PHY_PAGE);
                printk("=== ETH1: Reg22 : 0x%x . === \n", temp);

                temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1);
                printk("=== ETH1: Reg20_Page18 : 0x%x . === \n", temp); 

            }
        }
    }

    return m88e1121_config_init(phydev);
}
/* End add by heat */

其他地方暂未修改。

3)文件系统修改

    上面的驱动在内核加载后,网卡eth0是电口,插上网线后直接phy0显示link up; 网卡eth1与交换芯片P9口连接,eth1可以看做是Fiber口,但是PHY并没有切至Fiber Page,MAC一直获取的是PHY的CopperPage的link状态,所以网卡eth1一直显示无法link。我们使用mdio 工具进行了切页,将PHY切至Fiber Page后,网卡link up;

文件路径: \etc\init.d\init-fatri
添加的命令如下
在这里插入图片描述
mdio eth1 22 1 用于切至Fiber Page,以便MAC正确判断PHY1的link状态;

mdio eth1 22 3;mdio eth1 16 0xa0 用于配置LED[1]的工作模式。

硬件设计时,PHY1的LED[1]引脚还用于接收PPS信号输入。在测试时发现该引脚会影响PPS信号质量,会拉低PPS信号电平。需操作PHY寄存器 LED[1]的工作模式为Hi-Z高阻状态。

在这里插入图片描述

寄存器配置:

在这里插入图片描述
此外,还有一项重要更改:
在这里插入图片描述
关闭AM5728 RGMII-1 内部时延补偿。因为我们使用的是 rgmii-id 模式,由 88E1512 PHY侧补偿 rgmii 的TX和RX时延,就不用MAC再进行补偿,所以应该关闭AM5728 MAC侧的时延补偿。

AM5728的手册:Page-4305 ,如下图所示。
Table 18-279. CTRL_CORE_SMA_SW_1
在这里插入图片描述

5. PHY调试心得

1) PHY 一般都有 Packet Generation 功能,可以通过此功能判断 PHY到Copper端的链路是否正常。

在这里插入图片描述
在这里插入图片描述
开发板与PC机直连,PC机打开Wireshark抓包,看是否可以抓到固定大小的包(5AA55AA5…)。
开发板可以打开 tcpdump 工具,由PC机ping 开发板,这样链路就是copper->PHY->MAC,通过 tcpdump抓包;
tcpdump命令:“tcpdump –i eth0 arp –XX -v”,抓ARP解析包,看能否收到。

2) PHY和MAC一般都具备CRC 统计功能,可以统计收发的数据包个数以及错包个数,以此来判断哪个方向的传输不正常。

在这里插入图片描述
在这里插入图片描述
其他参考文件:

头文件:
AM57xx\Linux-RT\kernel\Linux-RT-4.9.65\include\linux\marvell_phy.h
AM57xx\Linux-RT\kernel\Linux-RT-4.9.65\include\linux\phy.h

### 回答1: phy88e1512是一种高速串行收发器,它可以实现高速数据传输和通信。手册提供了丰富的信息和指导,帮助用户了解和使用该收发器。 手册的前面部分介绍了收发器的概念、特点、应用、技术指标等基础知识,有助于用户理解和掌握产品的基本情况。 手册的中间部分包括了主要参数、功能描述、引脚功能、应用电路图等详细的技术信息,方便用户进行产品的选择、设计和调试。同时,手册还提供了丰富的示例应用电路,为用户提供了实际应用时的参考。 手册的后面部分包括了产品维护、故障排除、注意事项等信息,帮助用户在使用和维护产品时避免出现问题。 总之,phy88e1512手册提供了全面、详细的产品信息和技术指导,有助于用户了解和掌握该款收发器的使用方法和技术特点,是用户购买和使用收发器的必备参考资料。 ### 回答2: phy88e1512是一款高速以太网物理层收发器,能够支持多种不同的以太网标准,包括10BASE-T、100BASE-TX和1000BASE-T等标准。它具有一系列出色的功能和性能,可以帮助用户提高网络传输速度和稳定性。 该产品的使用手册提供了详细的使用说明和技术规范。用户可以在手册中找到有关该产品的硬件和软件特性的完整描述,包括端口功能、电气规范、时序图以及各种性能参数。此外,手册还提供了针对不同应用场景所需的配置指导,以及故障排除和维护建议,帮助用户更好地理解和操作该产品。 总的来说,phy88e1512可以帮助用户轻松搭建高效、稳定的以太网网络,适合于应用于各种企业级、工业控制和数据中心等领域。使用手册提供的全面的技术支持和指导,可以帮助用户充分了解该产品的各种特点和优势,为其使用和维护提供有力的保障。 ### 回答3: phy88e1512是一款高速以太网物理层收发器,其手册提供了详细的技术规格和使用说明。手册中介绍了该收发器的特点,包括支持多种速率和多种连接方式,并能实现自动协商功能,从而提高了传输效率和网络稳定性。手册还提供了针对不同应用场景的参考设计和电路图,方便用户根据需求进行定制化设计。此外,手册中还详细介绍了该收发器的电气特性、时序和信号传输等技术参数,对于用户进行网络优化和故障排除具有很好的指导意义。总之,phy88e1512手册是对于该产品进行正确使用和维护的必要参考,用户应该认真阅读并按照手册进行操作,以确保网络通讯的正常运行。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heat.huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值