phy回环模式测试

Posted by 婷 on November 8, 2023 本文总阅读量

前言

最近工作碰到RGMII需要调整TXC delay的情况,而Soc端的MAC控制器不支持调整,所以只能在phy端调整。而要确认这个delay,也需要方法。这个过程就是phytranning的过程。

参考RK3568的做法,其代码 drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c的做法,主要是把phy设置成loopback模式,然后它的做法挺巧妙的,就是直接在驱动中用dma去发出一个报文,然后dma接收直接去拿ddr中的skb,对比是否都是一样的。

参考这个思路,我们可以先把phy设置为回环模式,然后代码写个for循环,设置phy不同的delay值,然后发出报文,对收到的报文进行对比比较。

所以写代码前就要针对这个phy的回环模式是否设置成功了,需要先验证一下。验证思路就是配置了回环模式后,发出ping包,tcpdump抓到的包是不是一模一样的ping包就可以。这里有两点需要注意。第一,设置网卡为混杂模式,这样网卡就不会过滤掉不属于它的mac地址的帧了,当然tcpdump已经做好这一步了。第二,就是因为是ping包会发起广播的arp包,为了抓包好看,直接配了一条静态arp。虽然说如果回环模式设置的对,应该也会收到原封不动的arp报文,但是它不像ping那样可以看seq对比。

image-20231105214559039

过程

查看当前信息,因为我现在是接着网线的,link up的状态。

image-20231105163415633

然后我们设置phyinternal loopback,根据手册用phyreg工具来设置reg0 bit141。工具源码是从网上copy的,我放到最后了。

# ./phyreg eth0 0
# ./phyreg eth0 0 0x5040
# ./phyreg eth0 0

image-20231105165707980

image-20231105213956626

加一条静态arp

arp -s 192.168.1.102 70:a6:cc:80:18:4e

image-20231105170105253

配置混杂模式(虽然tcpdump也会帮我们做啦)

ifconfig eth0 promisc

image-20231105215346651

配置phy进入回环模式,然后ping 192.168.1.102tcpdump抓包

# ./phyreg eth0 0 0x5040

image-20231105215401489

可以看到抓到了两个一模一样的icmp request包,证明配置回环模式没有问题。

image-20231105172042294

参考链接

代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/mii.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/types.h>
#include <netinet/in.h>


#define reteck(ret)     \
        if(ret < 0){    \
            printf("%m! \"%s\" : line: %d\n", __func__, __LINE__);   \
            goto lab;   \
        }

#define help() \
    printf("mdio:\n");                  \
    printf("read operation: mdio reg_addr\n");          \
    printf("write operation: mdio reg_addr value\n");    \
    printf("For example:\n");            \
    printf("mdio eth0 1\n");             \
    printf("mdio eth0 0 0x12\n\n");      \
    exit(0);

int sockfd;

int main(int argc, char *argv[]){

    if(argc == 1 || !strcmp(argv[1], "-h")){
        help();
    }

    struct mii_ioctl_data *mii = NULL;
    struct ifreq ifr;
    int ret;

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);

    sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
    reteck(sockfd);

    //get phy address in smi bus
    ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);
    reteck(ret);

    mii = (struct mii_ioctl_data*)&ifr.ifr_data;

    if(argc == 3){

        mii->reg_num    = (uint16_t)strtoul(argv[2], NULL, 0);

        ret = ioctl(sockfd, SIOCGMIIREG, &ifr);
        reteck(ret);

        printf("read phy addr: 0x%x  reg: 0x%x   value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_out);
        }else if(argc == 4){

        mii->reg_num    = (uint16_t)strtoul(argv[2], NULL, 0);
        mii->val_in     = (uint16_t)strtoul(argv[3], NULL, 0);

        ret = ioctl(sockfd, SIOCSMIIREG, &ifr);
        reteck(ret);

        printf("write phy addr: 0x%x  reg: 0x%x  value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_in);
    }

lab:
    close(sockfd);
    return 0;
}
                                      

相关概念

回环模式

回环模式分好几种,有mac可以自己回环,有phy可以自己回环。然后phy自己回环,又分三种模式,参考此链接的说法。且对于phy来说,回环模式不一定三种都支持。

三种回环模式分别为:

  • Internal loopback mode,内回环模式

    image-20231108063801759

  • External loopback mode,外回环模式

    image-20231108063911051

    前两种模式都是用于检查 MACPHY 之间的发送与接收数据链路,支持三种速率(10/100/1000Mbps)与全双工模式。以太网帧由 MAC 端发出,PHY 芯片将接收到的帧发回 MAC 端。一般内部回环就跟我们前面配置的一样,配置reg0 bit14,外部回环则不需要配置。

  • Lineside (Remote) loopback mode,线回环模式

    也叫远端模拟回环模式,主要用于检查差分线、RJ45 连接器或者以太网线缆的工作情况,只支持 1000M 全双工模式。

delay

根据 RGMII 标准,时钟的上升和下降沿采样,且时钟信号需要比数据信号 delay 1~2ns 来保证setup/hold时间,这个 delay 可以发送端加,也可以接收端加,甚至在早期的 RGMII 标准中通过时钟信号的板上走线延迟来达到此目的。可参考此链接

mac跟phy的连接

参考此链接,复习一下,下面以MII接口为例

image-20231108065107620

TXD(Transmit Data)[3:0]: 数据发送信号,共4根信号线;

RXD(Receive Data)[3:0]:数据接收信号,共4根信号线;

TX_ER(Transmit Error): 发送数据错误提示信号,同步于TX_CLK,高电平有效,表示TX_ER有效期内传输的数据无效。对于10Mbps速率下,TX_ER不起作用;

RX_ER(Receive Error): 接收数据错误提示信号,同步于RX_CLK,高电平有效,表示RX_ER有效期内传输的数据无效。对于10Mbps速率下,RX_ER不起作用;

TX_EN(Transmit Enable): 发送使能信号,只有在TX_EN有效期内传的数据才有效;

RX_DV(Reveive Data Valid): 接收数据有效信号,作用类似于发送通道的TX_EN;

TX_CLK:发送参考时钟,100Mbps速率下,时钟频率为25MHz,10Mbps速率下,时钟频率为2.5MHz。注意,TX_CLK时钟的方向是从PHY侧指向MAC侧的,因此此时钟是由PHY提供的。

RX_CLK:接收数据参考时钟,100Mbps速率下,时钟频率为25MHz,10Mbps速率下,时钟频率为2.5MHz。RX_CLK也是由PHY侧提供的。

CRS:Carrier Sense,载波侦测信号,不需要同步于参考时钟,只要有数据传输,CRS就有效,另外,CRS只有PHY在半双工模式下有效;

COL:Collision Detectd,冲突检测信号,不需要同步于参考时钟,只有PHY在半双工模式下有效。