This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DP83869HM: Near end loopback

Part Number: DP83869HM
Other Parts Discussed in Thread: DP83869

I want to test the MAC<->PHY communication by setting the PHY in near-end loopback mode.

The interface speed is 1000M (RGMII), OP MODE copper.

I tried to follow the description in the datasheet, but this is unclear.

https://www.ti.com/lit/ds/symlink/dp83869hm.pdf

Following section 9.3.4.1, I should write 0xE720 in register 0x00FE (LOOPCR), the problem is that there is not such a register, what am I missing?

The Methods I tried: (without success)

Method 1

1) Write 0x4140 into 0x0 (Set loopback, disable A/N, set 1000M speed)

2) Write 0x1 Into 0x16 (PCS Loopback select, loop before scrambler)

3) Write 0X4000 into 0x1F (SW reset).

Method 2

1) Just writing 0x1 to register 0x16 (PCS Loopback select, loop before scrambler)

Method 3

1) Write 0x8000 into 0x1f (Reset, clear registers)

2) Write 0x40 Into 0x00 (set 1000M mode)

3) Write 0x1 Into 0X16 (PCS Loopback select, loop before scrambler)

4) Write 0X4000 into 0x1F (SW reset, keep register values).

Can you please provide clear steps on how to configure the PHY as near-end loopback (PCS Loopback), 1000M?

Thanks

I have another question, how can I test the communication (MAC<->PHY, when PHY is in loopback) with Linux? seems that both MACs I'm using (CPSW, ICSSG) don't support test mode

# ethtool -i eth0
driver: am65-cpsw-nuss
version: 5.10.41-00009-g2b4dcfa8d633-dir
firmware-version:
expansion-rom-version:
bus-info: 8000000.ethernet
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: yes


--------------------------------------------------------------------------------

# ethtool -i eth1
driver: icssg-prueth
version: 5.10.41-00009-g2b4dcfa8d633-dir
firmware-version:
expansion-rom-version:
bus-info: icssg1-eth
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

How can I test the communication?

I was thinking maybe to add a function in the kernel driver to write to PHY registers, so PHY will enter Loopback mode, then just using the interface normal, and the data will be looped back to RX. Can this work?

Thanks again

  • Hello,

    Can you please try following configuration for PCS loopback :

    Register 0x0000 = 0x0140

    Register 0x0010 = 0x5008

    Register 0x0016 = 0x0001

    Register 0x001F = x4000

    Or you may also try digital loopback with : 

    Register 0x0000 = 0x0140

    Register 0x0010 = 0x5008

    Register 0x0016 = 0x0004

    Register 0x001F = x4000

    After successful loopback, link status of PHY should go high in register 0x0001.

    Yes with above loopback data from MAC side will get looped back to the MAC. But you will need some utility in MAC to match the outgoing data with incoming data to verify that communication is all ok.

    --

    Regards,

    Vikram

  • Thanks for the reply.

    I tried your suggestion, but this is not working (PCS loopback and digital loopback).

    After writing these values, I get 0x7949 value in BMSR register.

    This is the code I use in the PHY driver:

    static int dp83869_set_loopback(struct phy_device *phydev)
    {
    	int ret = 0;
    	
    	ret = phy_write(phydev, 0x00, 0x140);
    	if(ret) 
    		return ret;
    	
    
    	ret = phy_write(phydev, 0x10, 0x5008);
    	if(ret) 
    		return ret;
    	
    
    	ret = phy_write(phydev, 0x16, 0x1);
    	if(ret) 
    		return ret;
    	
    
    	ret = phy_write(phydev, 0x1f, 0x4000);
    	if(ret) 
    		return ret;
    	
    
    	phydev_info(phydev, "BMSR Value IS: 0x%4X\n", phy_read(phydev, 0x0001) );
    
    	return ret;
    }

    This function is been called from dp83869_config_init function.

    Here is the relevant message from boot log:

    TI DP83869 300b2400.mdio:03: BMSR Value IS: 0x7949

    TI DP83869 300b2400.mdio:0f: BMSR Value IS: 0x7949

    TI DP83869 8000f00.mdio:00: BMSR Value IS: 0x7949

    Same for all 3 PHYs.

    Do you know what I'm doing wrong?

    I get no errors from any phy_write call.

  • After writting the registers, were you able to read back those registers to confirm that writes are going through?

  • I was able to read all written values but the value written to the GEN_CTRL register (which I'm not sure if reset value can be read, or it always will read 0)

    static int dp83869_set_loopback(struct phy_device *phydev)
    {
    	int ret = 0;
    
    
    	ret = phy_write(phydev, 0x00, 0x140);
    	if(ret) 
    		return ret;
    
    
    	phydev_info(phydev, "PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x%4x\n", phy_read(phydev, 0x00));
    
    	ret = phy_write(phydev, 0x10, 0x5008);
    	if(ret) 
    		return ret;
    	
    
    	phydev_info(phydev, "PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x%4x\n", phy_read(phydev, 0x10));
    
    
    	ret = phy_write(phydev, 0x16, 0x1);
    	if(ret)
    		return ret;
    	
    
    	phydev_info(phydev, "PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x%4x\n", phy_read(phydev, 0x16));
    
    
    	ret = phy_write(phydev, 0x1f, 0x4000);
    	if(ret) 
    		return ret;
    
    	phydev_info(phydev, "PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x%4x\n", phy_read(phydev, 0x1f));
    
    
    
    	phydev_info(phydev, "SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x%4x\n", phy_read(phydev, 0x00));
    	phydev_info(phydev, "SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x%4x\n", phy_read(phydev, 0x10));
    	phydev_info(phydev, "SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x%4x\n", phy_read(phydev, 0x16));
    
    
    	phydev_info(phydev, "PHYDEBUG: BMSR Value Is: 0x%4X\n", phy_read(phydev, 0x0001) );
    
    	return ret;
    }

    This is "dmesg | grep PHYDEBUG" output (I have 3 PHYs)

    [    2.936147] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    2.946886] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    2.957724] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    2.968285] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    2.978906] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    2.989965] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.001205] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.012173] TI DP83869 300b2400.mdio:0f: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.037834] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.048489] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.059329] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.069898] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.080513] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.091582] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.102823] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.113796] TI DP83869 300b2400.mdio:03: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.266729] TI DP83869 8000f00.mdio:00: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.277092] TI DP83869 8000f00.mdio:00: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.287600] TI DP83869 8000f00.mdio:00: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.297840] TI DP83869 8000f00.mdio:00: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.308135] TI DP83869 8000f00.mdio:00: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.318862] TI DP83869 8000f00.mdio:00: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.329759] TI DP83869 8000f00.mdio:00: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.340395] TI DP83869 8000f00.mdio:00: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.448680] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.459093] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.469685] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.480011] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.490386] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.501199] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.512182] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.522904] TI DP83869 300b2400.mdio:0f: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.545839] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.556251] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.566839] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.577164] TI DP83869 300b2400.mdio:0f: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.587540] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.598354] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.609337] TI DP83869 300b2400.mdio:0f: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.620059] TI DP83869 300b2400.mdio:0f: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.650993] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.661410] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.671999] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.682324] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.692707] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.703516] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.714499] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.725221] TI DP83869 300b2400.mdio:03: PHYDEBUG: BMSR Value Is: 0x7949
    [    3.748154] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.758570] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.769155] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.779480] TI DP83869 300b2400.mdio:03: PHYDEBUG: Value 0x4000 was written to register 0x1F, read value: 0x   0
    [    3.789856] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x140 was written to register 0x0, read value: 0x 140
    [    3.800665] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x5008 was written to register 0x10, read value: 0x5008
    [    3.811647] TI DP83869 300b2400.mdio:03: SECOND PHYDEBUG: Value 0x1 was written to register 0x16, read value: 0x   1
    [    3.822371] TI DP83869 300b2400.mdio:03: PHYDEBUG: BMSR Value Is: 0x7949
    

    What do you suggest?

  • Yes value of register 0x001F will go back to default after write. I will try to recreate your setup in lab. I should be able to get back to you by 16th November.

    --

    Regards,

    Vikram

  • Hi,

    Following worked for me in the lab : 

    01DF 0040 //to enable rgmii to copper mode
    00FE E720
    0000 0140
    0010 5008
    0016 0008
    001F 4000

    I had to write 01DF extra as by default it was showing 0041. Do you also see 0041 in register 01DF?

    Datasheet mentions writting 00FE so I kept it in  my settings but without that also I see loopback generating link status as high : reg<x0001> = x794D

    --

    Regards,

    Vikram

  • Thanks for the reply.

    I can't write to register 0x1df, I get errors.

    Here is an example from U-boot:

    # reading register 0x0 - works
    => mii read 0 0x0
    1100
    
    
    # reading register 0x1f - works
    => mii read 0 0x1f
    0000
    
    
    # reading register 0x1df - fails
    => mii read 0 0x1df
    Error reading from the PHY addr=00 reg=df
    
    #using mdio commands:
    
    # reading register 0x0 - works
    => mdio read 0x0
    Reading from bus ethernet@8000000
    PHY at address 0:
    0 - 0x1100
    
    
    
    # reading register 0x1f - works
    => mdio read 0x1f
    Reading from bus ethernet@8000000
    PHY at address 0:
    31 - 0x0
    
    
    
    # reading register 0x1df - fails
    => mdio read 0x1df
    Reading from bus ethernet@8000000
    PHY at address 0:
    Error
    
    
    
    
    

    Same for Linux kernel, This line returns an error:

    phy_write(phydev, 0x01df, 0x40);

    I used phy_write_mmd function as well, it didn't return any error, but, afterwards, I read the value 0

    ret = phy_write_mmd(phydev,0, 0x01df, 0x40);
    
    if(ret) 
    	return ret;
    
    phydev_info(phydev, "PHYDEBUG: Value 0x40 Was written into register 0x1df, read value: 0x%4x\n", phy_read_mmd(phydev,0, 0x1df));
    
    
    

    Output:

    [    3.292681] TI DP83869 8000f00.mdio:00: PHYDEBUG: Value 0x40 Was written into register 0x1df, read value: 0x   0

    I'm not sure why I should write 0x40 into OP_MODE_DECODE register

    0x40 -> SGMII to Copper

    I need RGMII to Copper, so the value should be 0 (or I'm wrong?), which is the default value (according to phy_read_mmd).

    I can't write/read to/from 0xfe as well (and could not find it in register map in datasheet)

    https://www.ti.com/lit/ds/symlink/dp83869hm.pdf

    => mdio read 0xfe
    Reading from bus ethernet@8000000
    PHY at address 0:
    Error
    

    In general, seems that I can read and write register up to address 0x1f, address 0x20 and higher leads to errors in U-boot.

    Any ideas?

  • 1. Register 0x01DF = x40 will be "Rgmii to Copper"

    2. Use following for register address greater than x1F : 

    write procedure for MMD "1F" regiters:

    write reg<000D> = 0x001F
    write reg<000E> = <address>
    write reg<000D> = 0x401F
    write reg<000E> = <value>

    read procedure for MMD "1F" regiters:

    write reg<000D> = 0x001F
    write reg<000E> = <address>
    write reg<000D> = 0x401F
    read reg<000E>

    Note : To read/write MMD "1" registers, replace 1F with 01.
    Note : Above write and read procedure is normally used for registers with address greater than 0x001F. But it can also be used for any address in general.

    --

    Regards,

    Vikram

  • OK, I found the problem, seems that I needed some delay before reading the BMSR register.

    Adding a little delay was all I needed.

    Just a little question:

    if LINK_STS1 bit is ON in BMSR register, that means that the MAC<->PHY connection is OK?

    I just need to know if the connection is OK, no need to send data and check If I receive the same data I sent.

    Thanks for the support and for the patience.

  • Link_sts1 is not the indication of MAC-PHY connection. It indicates the connection status on the cable side or during the successfull loopback. To check MAC-PHY connection you will have to send and receive the data from the MAC side.

    --

    Regards,

    Vikram

  • I'm able to read Link_sts1='1' in 2 PHYs, the third one is '0'.

    What can cause this? How can I debug this?

    PHY at address 0x0 -> CPSW ->  Link_sts1='1'. (Single PHY in this MII bus)

    PHY at address 0xf -> ICSSG1 ->  Link_sts1='1'

    PHY at address 0x3 -> ICSSG1 ->  Link_sts1='0' (Same MII bus as the PHY in address 0xf)

     

    Can you please recommend  me a Linux tool to test MAC<->PHY connection once  the PHY is in loopback?

    I'm not able to Link up with the loopback..

  • When you say PHY with address 0x3 has link_sts1 = 0, is that during the loopback case? Have you already checked register write's correctness for this PHY by reading them back? What else is different for this PHY (straps/configurtion?)

    MAC <-> PHY connection is very commonly checked by MAC based utilities (Data sent by MAC is matched with incoming data with PHY in loopback). I am not aware of any specific tool.

    --

    Regards,

    Vikram

  • Hi,

    Yes, I set the PHY in loopback mode and read the link_sts1 bit.

    For 2 PHYs the value is 1, and for one PHY the value is 0.

    I do verify all written data by reading it back, and all written data is read back, even in the 0x3 PHY.

    The only difference is in the Address straps, which are ok, since I do detect the PHY in address 0x3.

  • If PHY's are configured same and you are able to confirm that registers are getting written properly then I can't think of a logical reason for one of the PHY behaving differently in the loopback case. There must be something different. You may check register x6E to see if the PHY is strapped in different mode.

    --

    Regards,

    Vikram