[QNX]QNX BSP下AR8035 PHY驱动调试

锋影

email:[email protected]

如果你认为本系列文章对你有所帮助,请大家有钱的捧个钱场,点击此处赞助,赞助额0.1元起步,多少随意


背景: 当前开发板用的是QNX 7的sabreARD的BSP,主芯片是imx6q,PHY芯片是atheros的AR8035,当把MAC与PHY之间的管脚配置好之后。启动io-pkt-v6-hc -d mx6x服务之后,PHY无论如何无也无法正常工作,具体信息如下:

-->ifconfig
        fec0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        address: 00:00:12:34:56:78
        media: Ethernet 10baseT full-duplex (none)
        status: no carrier
        inet 192.168.1.11 netmask 0xffffff00 broadcast 192.168.1.255
        inet6 fe80::200:12ff:fe34:5678%fec0 prefixlen 64 scopeid 0x11

--> nicinfo
            fec0: 
          i.MX6 Ethernet Controller
        
          Link is DOWN
        
          Physical Node ID ........................... 000012 345678
          Current Physical Node ID ................... 000012 345678
          Current Operation Rate ..................... Unknown
          Active Interface Type ...................... MII
            Active PHY address ....................... 0
          Maximum Transmittable data Unit ............ 1500
          Maximum Receivable data Unit ............... 1500
          Hardware Interrupt ......................... 0x96
          Hardware Interrupt ......................... 0x97
          Memory Aperture ............................ 0x2188000 - 0x2188fff
          Memory Aperture ............................ 0x2098000 - 0x2098fff
          Promiscuous Mode ........................... Off
          Multicast Support .......................... Enabled

与QNX的网络工程师交流得知:status: no carrier是由于当前phy的link状态是down的,所以status 是no carrier的

所以当前问题归根结底是:当PHY初始化完成之后,PHY与电脑对接后一直处于DOWN状态。层层定位后发现是由于ar8035配置了自协商之后,端口变down了,但是PHY芯片肯定是要配置自协商的

顺便补充一下:QNX的sambreARD默认适配的是AR8031,而我编译好的ifs文件在8031的板子上网口是可以正常工作的。所以当时的思路只有一个:就是查看ar8031和ar8035数据手册的差异。

1、PHY Address

获取PHY的物理地址,QNX是通过MDI_FindPhy 接口配置的。遍历32位来查询当前的PHY的地址,添加日志

之后发现当前PHY的地址为0。


在电路图中NC表示不接的意思。所以LED_ACT/RXD1/RXD0都是直接接地。所以PHY的物理地址为0.与

软件识别到的地址是一致的。

2、Mode Select

当前硬件电路上的PHY MODE是1100 (NC表示断接),根据AR8035的手册,可以看到当前的MODE配置为:

RGMII,PLLOFF,INT
RGMII表示数据通信的接口,MDIO表示MAC对PHY的控制接口;
PLLOFF:表示芯片可以关闭内部PLL,以达到节能的目的。具体做法是:当进入节能模式之后,

25M时钟的输出将会周期性的消失。但在PLLON模式,25M时钟的输出将是连续的,

AR8031和AR8035芯片的主要区别是:AR8031支持光口和电口;而AR8035仅支持电口。

光口和电口的配置就是通过mode select的硬件电路来配置的。具体差异如下:

AR8031Mode Definition:

AR8035 Mode Definition:

3、查看PHY配置

通过DUMP PHY的寄存器,发现8031和8035的寄存器的配置都是相同的。由于当初购买的开发板带的是

linux系统,所以就查看linux中ar8031和ar8035的差异(kernel_imx\drivers\net\phy\at803x.c)。发现8031和8035

注册的接口都是一样的,仅PHYID不同;在linux内核工程里面搜索该PHYID,发现没有做特殊处理的地方。因而

对于linux 网络驱动框架而言,并不关注当前的PHY是什么芯片,框架都是做同样的处理。所以当初的思路就变

为排查MAC的配置,当从网络驱动的入口函数 fec_main.c中的fec_probe函数开始排查,发现在代码中会调用

fec_reset_phy函数来对PHY做硬件上的复位,即通过reset管脚来复位到此,在QNX BSP中在调用mx6q_init_phy

之前添加对PHY硬复位的代码。由于当前代码编译到so的,也就是用户态的程序,所以不能直接操作imx6q的

硬件寄存器,所以只能通过mmp来做映射:具体代码如下:

// reset phy by hardware
gpio_base_addr = mmap_device_memory (NULL, /*MX6X_GPIO_SIZE,*/MX6Q_MAP_SIZE,
                             PROT_READ | PROT_WRITE |
                             PROT_NOCACHE,
                             MAP_SHARED,
                             /*MX6X_GPIO1_BASE*/0x0209C000); //GPIO1
*(gpio_base_addr + 0) &= (~(1<<25));
nic_delay(1);
*(gpio_base_addr + 0) |= 1<<25;
/* unmap the address have been mapped*/
munmap_device_memory(gpio_base_addr, MX6Q_MAP_SIZE);       
            
    // Do one time PHY initialization
    if (mx6q_init_phy(mx6q)) {
        log(LOG_INFO, "PHY init failed");
mx6q_destroy(mx6q, -1);
return ENODEV;
    }

设备上地址映射只能通过mmap_device_memory,内存上的地址映射可以用mmap,注意两者的区别。
重新编译后,网口可以正常工作。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sgbsgb/article/details/78110027

-->ifconfig
        fec0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        address: 00:00:12:34:56:78
        media: Ethernet 10baseT full-duplex (none)
        status: no carrier
        inet 192.168.1.11 netmask 0xffffff00 broadcast 192.168.1.255
        inet6 fe80::200:12ff:fe34:5678%fec0 prefixlen 64 scopeid 0x11

--> nicinfo
            fec0: 
          i.MX6 Ethernet Controller
        
          Link is DOWN
        
          Physical Node ID ........................... 000012 345678
          Current Physical Node ID ................... 000012 345678
          Current Operation Rate ..................... Unknown
          Active Interface Type ...................... MII
            Active PHY address ....................... 0
          Maximum Transmittable data Unit ............ 1500
          Maximum Receivable data Unit ............... 1500
          Hardware Interrupt ......................... 0x96
          Hardware Interrupt ......................... 0x97
          Memory Aperture ............................ 0x2188000 - 0x2188fff
          Memory Aperture ............................ 0x2098000 - 0x2098fff
          Promiscuous Mode ........................... Off
          Multicast Support .......................... Enabled

与QNX的网络工程师交流得知:status: no carrier是由于当前phy的link状态是down的,所以status 是no carrier的

所以当前问题归根结底是:当PHY初始化完成之后,PHY与电脑对接后一直处于DOWN状态。层层定位后发现是由于ar8035配置了自协商之后,端口变down了,但是PHY芯片肯定是要配置自协商的

顺便补充一下:QNX的sambreARD默认适配的是AR8031,而我编译好的ifs文件在8031的板子上网口是可以正常工作的。所以当时的思路只有一个:就是查看ar8031和ar8035数据手册的差异。

1、PHY Address

获取PHY的物理地址,QNX是通过MDI_FindPhy 接口配置的。遍历32位来查询当前的PHY的地址,添加日志

之后发现当前PHY的地址为0。


在电路图中NC表示不接的意思。所以LED_ACT/RXD1/RXD0都是直接接地。所以PHY的物理地址为0.与

软件识别到的地址是一致的。

2、Mode Select

当前硬件电路上的PHY MODE是1100 (NC表示断接),根据AR8035的手册,可以看到当前的MODE配置为:

RGMII,PLLOFF,INT
RGMII表示数据通信的接口,MDIO表示MAC对PHY的控制接口;
PLLOFF:表示芯片可以关闭内部PLL,以达到节能的目的。具体做法是:当进入节能模式之后,

25M时钟的输出将会周期性的消失。但在PLLON模式,25M时钟的输出将是连续的,

AR8031和AR8035芯片的主要区别是:AR8031支持光口和电口;而AR8035仅支持电口。

光口和电口的配置就是通过mode select的硬件电路来配置的。具体差异如下:

AR8031Mode Definition:

AR8035 Mode Definition:

3、查看PHY配置

通过DUMP PHY的寄存器,发现8031和8035的寄存器的配置都是相同的。由于当初购买的开发板带的是

linux系统,所以就查看linux中ar8031和ar8035的差异(kernel_imx\drivers\net\phy\at803x.c)。发现8031和8035

注册的接口都是一样的,仅PHYID不同;在linux内核工程里面搜索该PHYID,发现没有做特殊处理的地方。因而

对于linux 网络驱动框架而言,并不关注当前的PHY是什么芯片,框架都是做同样的处理。所以当初的思路就变

为排查MAC的配置,当从网络驱动的入口函数 fec_main.c中的fec_probe函数开始排查,发现在代码中会调用

fec_reset_phy函数来对PHY做硬件上的复位,即通过reset管脚来复位到此,在QNX BSP中在调用mx6q_init_phy

之前添加对PHY硬复位的代码。由于当前代码编译到so的,也就是用户态的程序,所以不能直接操作imx6q的

硬件寄存器,所以只能通过mmp来做映射:具体代码如下:

// reset phy by hardware
gpio_base_addr = mmap_device_memory (NULL, /*MX6X_GPIO_SIZE,*/MX6Q_MAP_SIZE,
                             PROT_READ | PROT_WRITE |
                             PROT_NOCACHE,
                             MAP_SHARED,
                             /*MX6X_GPIO1_BASE*/0x0209C000); //GPIO1
*(gpio_base_addr + 0) &= (~(1<<25));
nic_delay(1);
*(gpio_base_addr + 0) |= 1<<25;
/* unmap the address have been mapped*/
munmap_device_memory(gpio_base_addr, MX6Q_MAP_SIZE);       
            
    // Do one time PHY initialization
    if (mx6q_init_phy(mx6q)) {
        log(LOG_INFO, "PHY init failed");
mx6q_destroy(mx6q, -1);
return ENODEV;
    }

设备上地址映射只能通过mmap_device_memory,内存上的地址映射可以用mmap,注意两者的区别。
重新编译后,网口可以正常工作。

猜你喜欢

转载自blog.csdn.net/xjhhjx/article/details/81053985