嵌入式爱好者

查看: 3395|回复: 4

[Ubuntu] ls1046A下获取网口PHY的寄存器值

[复制链接]

4

主题

9

帖子

32

积分

LS1043A\46A通行证

扫一扫,手机访问本帖
发表于 2022-10-10 14:18:16 | 显示全部楼层 |阅读模式
你好:
     请问在ls1046A下,怎样获取网口PHY各个寄存器的值?
     谢谢!
回复

使用道具 举报

4

主题

9

帖子

32

积分

LS1043A\46A通行证

 楼主| 发表于 2022-10-12 18:50:01 | 显示全部楼层
hai 发表于 2022-10-12 10:20
您好,我们这边是直接使用的ethtool fm1-amc3这个命令,这个能看到网口的协商结果还有是否处于link状态等 ...

嗯,是的,我实现了,分享如下:
修改文件:drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
修改接口:dpa_ioctl
修改的地方:在接口dpa_ioctl的最后一个return之前加入如下的代码:
       if( cmd >= SIOCGMIIPHY && cmd <= SIOCSMIIREG)
        {
                struct dpa_priv_s *priv = netdev_priv(dev);
                if( priv && priv->mac_dev && priv->mac_dev->phy_dev )
                {               
                        return phy_mii_ioctl(priv->mac_dev->phy_dev, rq, cmd);
                }
                else
                {
                        netdev_warn(dev, "No phy device\n");
                        ret = -ENODEV;
                }
        }

上层使用如下工具就可以读取到网络接口的PHY寄存器了:

#include <stdio.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>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <unistd.h>


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

#define help() \
    printf("mdio:\n");                  \
    printf("read all regs: mdio if\n");          \
    printf("write regAddr to value : mdio if regAddr value\n");    \
    printf("For example:\n");            \
    printf("mdio fm1-mac5 \n");             \
    printf("mdio fm1-mac5 0 0x1234\n\n");      \
    exit(0);

int sockfd;

int main(int argc, char *argv[])
{
        uint16_t data[32] = {0};
    struct mii_ioctl_data *mii = NULL;
    struct ifreq ifr;
    int ret;
        uint16_t i;
       
    if(argc == 1 || !strcmp(argv[1], "-h"))
        {
        help();
    }
   
        if((argc != 2) && (argc != 4))
        {
        help();
    }       

    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 == 2)
        {                       
                for( i =0 ;i < 32;i++)
                {
                        mii->reg_num  = i;
                        //printf("mii->reg_num = %d\n",mii->reg_num);
                       
                        ret = ioctl(sockfd, SIOCGMIIREG, &ifr);
                        reteck(ret);               
                        data = mii->val_out;
                }
                       
                printf("%s\'s phyAddr = %d\n",ifr.ifr_name,mii->phy_id);
                printf("All Phy Reg as follows:\n");
                printf("--------------------------------------\n");
                for(i = 0 ;i < 32; i++)
                {                       
                        printf("regAddr = %2d,Val = 0x%04X   ",i,data);
                        if( ((i+1) %2) == 0)
                        {
                                printf("\n");
                        }
                }
               
                printf("\n");        
        }
        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;
}

点评回复 支持 1 反对 0

使用道具 举报

0

主题

79

帖子

324

积分

发表于 2022-10-10 14:48:38 | 显示全部楼层
可以在uboot阶段使用如下命令读取,详细的参数还是用看芯片手册。
例:
列举PHY:mdio list
读取寄存器0: mdio read 1 0x00
读取寄存器1:mdio read 1 0x01

点评

在uboot阶段验证OK,感谢! 另外,请教一下,在Linux下有什么工具可用吗? 使用ethtool提示如下,不知什么原因? root@localhost:~# root@localhost:~# ethtool -i fm1-mac5 driver: fsl_dpa version: 5.10  详情 回复 发表于 2022-10-10 16:18
点评回复 支持 反对

使用道具 举报

4

主题

9

帖子

32

积分

LS1043A\46A通行证

 楼主| 发表于 2022-10-10 16:18:55 | 显示全部楼层
hai 发表于 2022-10-10 14:48
可以在uboot阶段使用如下命令读取,详细的参数还是用看芯片手册。
例:
列举PHY:mdio list

在uboot阶段验证OK,感谢!

另外,请教一下,在Linux下有什么工具可用吗?
使用ethtool提示如下,不知什么原因?
root@localhost:~#
root@localhost:~# ethtool -i fm1-mac5
driver: fsl_dpa
version: 5.10.35-rt39-svn80
firmware-version: 0
expansion-rom-version:
bus-info: soc:fsl,dpaa
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no     【提示no】
supports-priv-flags: no
root@localhost:~#
root@localhost:~#
root@localhost:~# ethtool -d fm1-mac5
Cannot get register dump: Operation not supported
root@localhost:~#

点评

hai
您好,我们这边是直接使用的ethtool fm1-amc3这个命令,这个能看到网口的协商结果还有是否处于link状态等等信息。但是ls系列的是不支持在ubuntu系统中读取phy寄存器状态的。如果想读取需要您自己改驱动。 root@loca  详情 回复 发表于 2022-10-12 10:20
点评回复 支持 反对

使用道具 举报

0

主题

79

帖子

324

积分

发表于 2022-10-12 10:20:04 | 显示全部楼层
elephant4216 发表于 2022-10-10 16:18
在uboot阶段验证OK,感谢!

另外,请教一下,在Linux下有什么工具可用吗?

您好,我们这边是直接使用的ethtool fm1-amc3这个命令,这个能看到网口的协商结果还有是否处于link状态等等信息。但是ls系列的是不支持在ubuntu系统中读取phy寄存器状态的。如果想读取需要您自己改驱动。
root@localhost:~# ethtool fm1-mac3
Settings for fm1-mac3:
        Supported ports: [ MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Supported pause frame use: Symmetric Receive-only
        Supports auto-negotiation: Yes
        Supported FEC modes: Not reported
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Advertised FEC modes: Not reported
        Speed: 10Mb/s
        Duplex: Half
        Port: MII
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: d
        Wake-on: d
        Current message level: 0xffffffff (-1)
                               drv probe link timer ifdown ifup rx_err tx_err tx_queued intr tx_done rx_status pktdata hw wol 0xffff8000
        Link detected: no

点评

嗯,是的,我实现了,分享如下: 修改文件:drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c 修改接口:dpa_ioctl 修改的地方:在接口dpa_ioctl的最后一个return之前加入如下的代码: if( cm  详情 回复 发表于 2022-10-12 18:50
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-11-24 06:21

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表