IMX6DL+AR8031以太网一致性测试方法

参考链接:

http://www.eeworld.com.cn/Test_and_measurement/2014/0722/article_9221.html

https://blog.csdn.net/liushi558/article/details/45267665

 

软件信息:

uboot: 2016.03

linux: 4.1.15

rootfs: Qt5.6.2

 

通过AR8031 PHY Datasheet可知:

MII registers

1000BASE-T control register Offset: 0x09

000 = Normal Mode

001 = Test mode 1 – Transmit waveform test

010 = Test mode 2 – Transmit jitter test (master mode)

011 = Test mode 3 – Transmit jitter test (slave mode)

100 = Test mode 4 – Transmit distortion test

101, 110, 111 = Reserved

 

Debug registers

100BASE-TX test mode select register Offset: 0x10

100BASE-TX jitter test

100BASE-TX over shoot test

100BASE-TX DCD test

 

10BASE-Tetest mode select register Offset: 0x12

Bit[2] of TEST_MODE, used together with TEST_MODE[1:0] Bit[0] and bit[1] of TEST_MODE, used together with TEST_MODE[2].

001= Packet with all 1, 10 MHz sine wave, for harmonic test.

010 = Pseudo random, for TP_IDLE/Jitter/Differential voltage test

011 = Normal link pulse only

100 = 5 MHz sine wave

Others: Normal mode

 

读写寄存器方法:

5 Registers

Three types of registers are present on AR8031:

5.1 IEEE defined 32 MII registers, referred to as “MII Registers” in this document

¨ MII registers are accessed directly through the management frame.

5.2 Debug registers defined by Qualcomm Atheros, referred to as “Debug Registers” in this

document

¨ Write the offset address of debug register to 0x1D.

¨ Read/write the data from/to 0x1E.

5.3 IEEE defined MDIO Manageable Device (MMD) register, referred to as “MDIO Interface

(MMD3/MMD7) Registers” in this document

¨ MMD registers are accessed by reading/writing MMD access control register (MII register

0xD) and MMD access data register (MII register 0xE).

5.4 Example: Writing 0x8000 to register 0x0 of MMD3

1. Write 0x3 to MII register 0xD to set the device address of the MMD register.

2. Write 0x0 to MII register 0xE to set the offset address of the MMD register.

3. Write 0x4003 to MII register 0xD to keep the device address.

4. Read MII register 0xE to check the data from register 0x0 of MMD3.

5. Write 0x8000 to MII register 0xE, that is register 0x0 of MMD3.

NOTE Read operation follows the process 1 to 4.

 

MMD3 — PCS control register

Device Address = 3; Offset = 0x0

MMD7 -- ...

Device Address = 7

 

kernel源码跟踪:

/arch/arm/mach-imx/mach-imx6q.c

static int ar8031_phy_fixup(struct phy_device *dev)
{
        u16 val;

        // === MII Registers ========
        // MII registers are accessed directly through the management frame.
        // === Debug Registers ========
        // Write the offset address of debug register to 0x1D.
        // Read/write the data from/to 0x1E.
        // === MDIO Registers -- Interface(MMD3/MMD7) ========
        // MMD registers are accessed by reading/writing MMD access control register (MII register 0xD)
        // and MMD access data register (MII register 0xE).

// === Debug Registers ========
        /* Set RGMII IO voltage to 1.8V */
        phy_write(dev, 0x1d, 0x1f); // PHY control debug register 0
        phy_write(dev, 0x1e, 0x8); // 1 = 1.8 V; 0 = 1.5 V (default)

// === MDIO Registers --MMD3 ========
        /* disable phy AR8031 SmartEEE function. */
        phy_write(dev, 0xd, 0x3); // set the device address of the MMD register.
        phy_write(dev, 0xe, 0x805d); // set the offset address of the MMD register.
        phy_write(dev, 0xd, 0x4003); // keep the device address.
        val = phy_read(dev, 0xe);
        val &= ~(0x1 << 8); // Enables or disables SmartEEE,0 = Disable
        phy_write(dev, 0xe, val);

// === MDIO Registers --MMD7 ========
        /* To enable AR8031 output a 125MHz clk from CLK_25M */
        phy_write(dev, 0xd, 0x7);
        phy_write(dev, 0xe, 0x8016); // MMD7 — CLK_25M clock select register
        phy_write(dev, 0xd, 0x4007);
        //
        val = phy_read(dev, 0xe);
        val &= 0xffe3;
        val |= 0x18; // 110 = 125 MHz from local PLL source
        phy_write(dev, 0xe, val);

// === Debug Registers ========
        /* introduce tx clock delay */
        phy_write(dev, 0x1d, 0x5); // SerDes test and system mode control register
        val = phy_read(dev, 0x1e);
     val |= 0x0100; // Bit8: 1 = RGMII Tx clock delay enable
        phy_write(dev, 0x1e, val);

        return 0;
}

 

kernel\drivers\net\phy\phy.h

static inline int phy_read(struct phy_device *phydev, u32 regnum)
    return mdiobus_read(phydev->bus, phydev->addr, regnum);
static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
    return mdiobus_write(phydev->bus, phydev->addr, regnum, val);

 

kernel\drivers\net\phy\mdio_bus.c

int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
{
    int retval;

    BUG_ON(in_interrupt());

    mutex_lock(&bus->mdio_lock);
    retval = bus->read(bus, addr, regnum);
    mutex_unlock(&bus->mdio_lock);

    return retval;
}
EXPORT_SYMBOL(mdiobus_read);
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) { int err; BUG_ON(in_interrupt()); mutex_lock(&bus->mdio_lock); err = bus->write(bus, addr, regnum, val); mutex_unlock(&bus->mdio_lock); return err; } EXPORT_SYMBOL(mdiobus_write);

 

在内核代码中加入打印信息,查看phy-addr和phy-name:

aplex@aplex:~/sbc7819/kernel$ vi ./arch/arm/mach-imx/mach-imx6q.c

printk("<0>" "phy addr=%d +++++++\n", dev->addr); /* Bus address of the PHY (0-31) */

printk("<0>" "phy bus name=%s +++++++\n", dev->bus->name);

启动时在内核中打印出

<0>phy addr=1 +++++++

<0>phy bus name=fec_enet_mii_bus +++++++

 

用户层phytool工具的使用:

源码链接:https://github.com/wkz/phytool

 使用cross compile toolchain编译后即可使用。

 

phytool用法:

root@imx6dlsabresd:~# ./phytool

Usage: phytool read IFACE/ADDR/REG

phytool write IFACE/ADDR/REG <0-0xffff>

phytool print IFACE/ADDR[/REG]

where

 

ADDR := C22 | C45

C22 := <0-0x1f>

C45 := <0-0x1f>:<0-0x1f>

REG := <0-0x1f>

 

Examples:

phytool read eth0/0:3/1

phytool write eth0/0xa/0 0x1140

phytool print eth0/0x1c

 

Note: Not all MDIO drivers support the `port:device` Clause 45 address

format.

 

The `read` and `write` commands are simple register level

accessors. The `print` command will pretty-print a register. When

using the `print` command, the register is optional. If left out, the

most common registers will be shown.

Bug report address: https://github.com/wkz/phytool/issues

root@imx6dlsabresd:~#

 

 

确认寄存器的值是否正确:

1.确认电压配置

内核实际配置为:

// === Debug Registers ========

/* Set RGMII IO voltage to 1.8V */

phy_write(dev, 0x1d, 0x1f); // PHY control debug register 0

phy_write(dev, 0x1e, 0x8); // 1 = 1.8 V; 0 = 1.5 V (default)

通过工具读取为:

root@imx6dlsabresd:~# ./phytool write eth0/1/0x1d 0x1f

root@imx6dlsabresd:~# ./phytool read eth0/1/0x1d

0x001f

root@imx6dlsabresd:~# ./phytool read eth0/1/0x1e

0x0008

 

 

配置寄存器进入测试模式:

1000BASE-T control register   Offset: 0x09   MII registers

000 = Normal Mode

001 = Test mode 1 – Transmit waveform test

010 = Test mode 2 – Transmit jitter test (master mode)

011 = Test mode 3 – Transmit jitter test (slave mode)

100 = Test mode 4 – Transmit distortion test

101, 110, 111 = Reserved

//  上电后第一次读取

root@imx6dlsabresd:~# ./phytool read eth0/1/0x09

    0x0200

// 操作MII Resgister进入测试模式

//Normal Mode

  ./phytool write eth0/1/0x09 0x0200

  ./phytool read eth0/1/0x09

//Test mode 1 – Transmit waveform test

  ./phytool write eth0/1/0x09 0x2200

  ./phytool read eth0/1/0x09

//Test mode 2 – Transmit jitter test (master mode)

  ./phytool write eth0/1/0x09 0x4200

  ./phytool read eth0/1/0x09

//Test mode 3 – Transmit jitter test (slave mode)

  ./phytool write eth0/1/0x09 0x6200

  ./phytool read eth0/1/0x09

//Test mode 4 – Transmit distortion test

  ./phytool write eth0/1/0x09 0x8200

  ./phytool read eth0/1/0x09

 

 

100BASE-TX test mode select register   Offset: 0x10   Debug registers

 

root@imx6dlsabresd:~# ./phytool read eth0/1/0x1d

  0x001f // 内核初始化时设置为了0x1f

//

//100BASE-TX jitter test

  ./phytool write eth0/1/0x1d 0x10

  ./phytool read eth0/1/0x1d

  ./phytool read eth0/1/0x1e

    0000

  ./phytool write eth0/1/0x1e 0x80

  ./phytool read eth0/1/0x1e

    0x0080

//100BASE-TX over shoot test

  //./phytool write eth0/1/0x1d 0x10

  //./phytool read eth0/1/0x1d

  ./phytool read eth0/1/0x1e

    0x0080

  ./phytool write eth0/1/0x1e 0x40

  ./phytool read eth0/1/0x1e

    0x0040

//100BASE-TX DCD test

  //./phytool write eth0/1/0x1d 0x10

  //./phytool read eth0/1/0x1d

  ./phytool read eth0/1/0x1e

    0x0080

  ./phytool write eth0/1/0x1e 0x20

  ./phytool read eth0/1/0x1e

    0x0020

 

 

10BASE-Tetest mode select register  Offset: 0x12  Debug registers

//001= Packet with all 1, 10 MHz sine wave, for harmonic test.

  ./phytool write eth0/1/0x1d 0x12

  ./phytool read eth0/1/0x1d

  ./phytool read eth0/1/0x1e

    0x4c04

  ./phytool write eth0/1/0x1e 0x4C05

  ./phytool read eth0/1/0x1e

    0x4C05

//010 = Pseudo random, for TP_IDLE/Jitter/Differential voltage test

  //./phytool write eth0/1/0x1d 0x12

  //./phytool read eth0/1/0x1d

  //./phytool read eth0/1/0x1e

  ./phytool write eth0/1/0x1e 0x4C06

  ./phytool read eth0/1/0x1e

    0x4C06

//011 = Normal link pulse only

  //./phytool write eth0/1/0x1d 0x12

  //./phytool read eth0/1/0x1d

  //./phytool read eth0/1/0x1e

  ./phytool write eth0/1/0x1e 0x4C07

  ./phytool read eth0/1/0x1e

    0x4C07

//100 = 5 MHz sine wave

  //./phytool write eth0/1/0x1d 0x12

  //./phytool read eth0/1/0x1d

  //./phytool read eth0/1/0x1e

  ./phytool write eth0/1/0x1e 0x4C24

  ./phytool read eth0/1/0x1e

    0x4C14

//Others: Normal mode

  //./phytool write eth0/1/0x1d 0x12

  //./phytool read eth0/1/0x1d

  //./phytool read eth0/1/0x1e

  ./phytool write eth0/1/0x1e 0x4C04

  ./phytool read eth0/1/0x1e

    0x4C04

 

 

------------------- The end. Thanks! ------------------------

 

posted on 2018-07-20 09:03  HertzZhang  阅读(3243)  评论(0)    收藏  举报

导航