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.

AM2434: EtherCAT not running with DP83867IR PHY

Part Number: AM2434
Other Parts Discussed in Thread: SYSCONFIG, DP83867IR, , DP83869

Tool/software:

Dear TI support,

I´m currently working with a custom board with AM2434 chip and DP83867IR phys. I took the ethercat_slave_beckhoff_ssc_demo for the evm board and I made little changes in sysconfig, such as declaring the DP83867 as custom phy and other board specific changes. Moreover, I created a driver for the 83867 based on 83869.

I expect to run the same demo but on our custom board but sadly it is not the case. I have an AM243x-EVM board, and with that I have no issues to run the demo. I compared the phy register values and these are the values.

DP83867 phy output:

INFO: ETHPHY_DP83867_printRegs:971: PHY 0: BMCR        = 0x1140
INFO: ETHPHY_DP83867_printRegs:973: PHY 0: BMSR        = 0x796d
INFO: ETHPHY_DP83867_printRegs:975: PHY 0: PHYIDR1     = 0x2000
INFO: ETHPHY_DP83867_printRegs:977: PHY 0: PHYIDR2     = 0xa231
INFO: ETHPHY_DP83867_printRegs:979: PHY 0: ANAR        = 0x01e1
INFO: ETHPHY_DP83867_printRegs:981: PHY 0: ANLPAR      = 0xcde1
INFO: ETHPHY_DP83867_printRegs:983: PHY 0: ANER        = 0x006f
INFO: ETHPHY_DP83867_printRegs:985: PHY 0: ANNPTR      = 0x2001
INFO: ETHPHY_DP83867_printRegs:987: PHY 0: ANNPRR      = 0x0000
INFO: ETHPHY_DP83867_printRegs:989: PHY 0: CFG1        = 0x0000
INFO: ETHPHY_DP83867_printRegs:991: PHY 0: STS1        = 0x0000
INFO: ETHPHY_DP83867_printRegs:993: PHY 0: REGCR       = 0x401f
INFO: ETHPHY_DP83867_printRegs:995: PHY 0: 1KSCR       = 0x3000
INFO: ETHPHY_DP83867_printRegs:997: PHY 0: PHYCR       = 0x5048
INFO: ETHPHY_DP83867_printRegs:999: PHY 0: PHYSTS      = 0x7f02
INFO: ETHPHY_DP83867_printRegs:1001: PHY 0: MICR        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1003: PHY 0: ISR         = 0x5c40
INFO: ETHPHY_DP83867_printRegs:1005: PHY 0: CFG2        = 0x29c7
INFO: ETHPHY_DP83867_printRegs:1007: PHY 0: RECR        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1009: PHY 0: BISCR       = 0x0000
INFO: ETHPHY_DP83867_printRegs:1011: PHY 0: STS2        = 0x0040
INFO: ETHPHY_DP83867_printRegs:1013: PHY 0: LEDCR1      = 0x8be0
INFO: ETHPHY_DP83867_printRegs:1015: PHY 0: LEDCR2      = 0x4444
INFO: ETHPHY_DP83867_printRegs:1017: PHY 0: LEDCR3      = 0x0002
INFO: ETHPHY_DP83867_printRegs:1019: PHY 0: CFG3        = 0x0802
INFO: ETHPHY_DP83867_printRegs:1021: PHY 0: CTRL        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1023: PHY 0: FLDCFG      = 0x401f
INFO: ETHPHY_DP83867_printRegs:1025: PHY 0: RGMIICTL    = 0x0000
INFO: ETHPHY_DP83867_printRegs:1027: PHY 0: RGMIICTL2   = 0x0000
INFO: ETHPHY_DP83867_printRegs:1029: PHY 0: 100CR       = 0xa231

INFO: ETHPHY_DP83867_printRegs:971: PHY 3: BMCR        = 0x1140
INFO: ETHPHY_DP83867_printRegs:973: PHY 3: BMSR        = 0x7949
INFO: ETHPHY_DP83867_printRegs:975: PHY 3: PHYIDR1     = 0x2000
INFO: ETHPHY_DP83867_printRegs:977: PHY 3: PHYIDR2     = 0xa231
INFO: ETHPHY_DP83867_printRegs:979: PHY 3: ANAR        = 0x01e1
INFO: ETHPHY_DP83867_printRegs:981: PHY 3: ANLPAR      = 0x0000
INFO: ETHPHY_DP83867_printRegs:983: PHY 3: ANER        = 0x0064
INFO: ETHPHY_DP83867_printRegs:985: PHY 3: ANNPTR      = 0x2001
INFO: ETHPHY_DP83867_printRegs:987: PHY 3: ANNPRR      = 0x0000
INFO: ETHPHY_DP83867_printRegs:989: PHY 3: CFG1        = 0x0000
INFO: ETHPHY_DP83867_printRegs:991: PHY 3: STS1        = 0x0000
INFO: ETHPHY_DP83867_printRegs:993: PHY 3: REGCR       = 0x401f
INFO: ETHPHY_DP83867_printRegs:995: PHY 3: 1KSCR       = 0x3000
INFO: ETHPHY_DP83867_printRegs:997: PHY 3: PHYCR       = 0x5048
INFO: ETHPHY_DP83867_printRegs:999: PHY 3: PHYSTS      = 0x0302
INFO: ETHPHY_DP83867_printRegs:1001: PHY 3: MICR        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1003: PHY 3: ISR         = 0x0040
INFO: ETHPHY_DP83867_printRegs:1005: PHY 3: CFG2        = 0x29c7
INFO: ETHPHY_DP83867_printRegs:1007: PHY 3: RECR        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1009: PHY 3: BISCR       = 0x0000
INFO: ETHPHY_DP83867_printRegs:1011: PHY 3: STS2        = 0x0040
INFO: ETHPHY_DP83867_printRegs:1013: PHY 3: LEDCR1      = 0x8be0
INFO: ETHPHY_DP83867_printRegs:1015: PHY 3: LEDCR2      = 0x4444
INFO: ETHPHY_DP83867_printRegs:1017: PHY 3: LEDCR3      = 0x0002
INFO: ETHPHY_DP83867_printRegs:1019: PHY 3: CFG3        = 0x0802
INFO: ETHPHY_DP83867_printRegs:1021: PHY 3: CTRL        = 0x0000
INFO: ETHPHY_DP83867_printRegs:1023: PHY 3: FLDCFG      = 0x401f
INFO: ETHPHY_DP83867_printRegs:1025: PHY 3: RGMIICTL    = 0x0000
INFO: ETHPHY_DP83867_printRegs:1027: PHY 3: RGMIICTL2   = 0x0040
INFO: ETHPHY_DP83867_printRegs:1029: PHY 3: 100CR       = 0xa231

DP83869 phy output:

INFO: ETHPHY_DP83869_printRegisters:932: PHY 15: BMCR            = 0x1140
INFO: ETHPHY_DP83869_printRegisters:934: PHY 15: BMSR            = 0x796d
INFO: ETHPHY_DP83869_printRegisters:936: PHY 15: PHYIDR1         = 0x2000
INFO: ETHPHY_DP83869_printRegisters:938: PHY 15: PHYIDR2         = 0xa0f1
INFO: ETHPHY_DP83869_printRegisters:940: PHY 15: ANAR            = 0x01e1
INFO: ETHPHY_DP83869_printRegisters:942: PHY 15: ANLPAR          = 0xcde1
INFO: ETHPHY_DP83869_printRegisters:944: PHY 15: ANER            = 0x006f
INFO: ETHPHY_DP83869_printRegisters:946: PHY 15: ANNPTR          = 0x2001
INFO: ETHPHY_DP83869_printRegisters:948: PHY 15: ANNPRR          = 0x4312
INFO: ETHPHY_DP83869_printRegisters:950: PHY 15: CFG1            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:952: PHY 15: STS1            = 0x0c00
INFO: ETHPHY_DP83869_printRegisters:954: PHY 15: REGCR           = 0x401f
INFO: ETHPHY_DP83869_printRegisters:956: PHY 15: 1KSCR           = 0xf000
INFO: ETHPHY_DP83869_printRegisters:958: PHY 15: PHYCR           = 0x5048
INFO: ETHPHY_DP83869_printRegisters:960: PHY 15: PHYSTS          = 0x7f02
INFO: ETHPHY_DP83869_printRegisters:962: PHY 15: MICR            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:964: PHY 15: ISR             = 0x1c40
INFO: ETHPHY_DP83869_printRegisters:966: PHY 15: CFG2            = 0x29c7
INFO: ETHPHY_DP83869_printRegisters:968: PHY 15: RECR            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:970: PHY 15: BISCR           = 0x0000
INFO: ETHPHY_DP83869_printRegisters:972: PHY 15: STS2            = 0x0040
INFO: ETHPHY_DP83869_printRegisters:974: PHY 15: LEDCR1          = 0x8be0
INFO: ETHPHY_DP83869_printRegisters:976: PHY 15: LEDCR2          = 0x4444
INFO: ETHPHY_DP83869_printRegisters:978: PHY 15: LEDCR3          = 0x0002
INFO: ETHPHY_DP83869_printRegisters:980: PHY 15: CFG3            = 0x0812
INFO: ETHPHY_DP83869_printRegisters:982: PHY 15: CTRL            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:984: PHY 15: FLDCFG          = 0x401f
INFO: ETHPHY_DP83869_printRegisters:986: PHY 15: RGMIICTL        = 0x0000
INFO: ETHPHY_DP83869_printRegisters:988: PHY 15: RGMIICTL2       = 0x0000
INFO: ETHPHY_DP83869_printRegisters:990: PHY 15: 100CR           = 0xa0f1

INFO: ETHPHY_DP83869_printRegisters:932: PHY 3: BMCR            = 0x1140
INFO: ETHPHY_DP83869_printRegisters:934: PHY 3: BMSR            = 0x7949
INFO: ETHPHY_DP83869_printRegisters:936: PHY 3: PHYIDR1         = 0x2000
INFO: ETHPHY_DP83869_printRegisters:938: PHY 3: PHYIDR2         = 0xa0f1
INFO: ETHPHY_DP83869_printRegisters:940: PHY 3: ANAR            = 0x01e1
INFO: ETHPHY_DP83869_printRegisters:942: PHY 3: ANLPAR          = 0x0000
INFO: ETHPHY_DP83869_printRegisters:944: PHY 3: ANER            = 0x0064
INFO: ETHPHY_DP83869_printRegisters:946: PHY 3: ANNPTR          = 0x2001
INFO: ETHPHY_DP83869_printRegisters:948: PHY 3: ANNPRR          = 0x0000
INFO: ETHPHY_DP83869_printRegisters:950: PHY 3: CFG1            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:952: PHY 3: STS1            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:954: PHY 3: REGCR           = 0x401f
INFO: ETHPHY_DP83869_printRegisters:956: PHY 3: 1KSCR           = 0xf000
INFO: ETHPHY_DP83869_printRegisters:958: PHY 3: PHYCR           = 0x5048
INFO: ETHPHY_DP83869_printRegisters:960: PHY 3: PHYSTS          = 0x0002
INFO: ETHPHY_DP83869_printRegisters:962: PHY 3: MICR            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:964: PHY 3: ISR             = 0x0040
INFO: ETHPHY_DP83869_printRegisters:966: PHY 3: CFG2            = 0x29c7
INFO: ETHPHY_DP83869_printRegisters:968: PHY 3: RECR            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:970: PHY 3: BISCR           = 0x0000
INFO: ETHPHY_DP83869_printRegisters:972: PHY 3: STS2            = 0x0040
INFO: ETHPHY_DP83869_printRegisters:974: PHY 3: LEDCR1          = 0x8be0
INFO: ETHPHY_DP83869_printRegisters:976: PHY 3: LEDCR2          = 0x4444
INFO: ETHPHY_DP83869_printRegisters:978: PHY 3: LEDCR3          = 0x0002
INFO: ETHPHY_DP83869_printRegisters:980: PHY 3: CFG3            = 0x0812
INFO: ETHPHY_DP83869_printRegisters:982: PHY 3: CTRL            = 0x0000
INFO: ETHPHY_DP83869_printRegisters:984: PHY 3: FLDCFG          = 0x401f
INFO: ETHPHY_DP83869_printRegisters:986: PHY 3: RGMIICTL        = 0x0000
INFO: ETHPHY_DP83869_printRegisters:988: PHY 3: RGMIICTL2       = 0x0040
INFO: ETHPHY_DP83869_printRegisters:990: PHY 3: 100CR           = 0xa0f1

The phy is set in MII mode and I tried disabling the enhanced link detection as well as switching the polarity too but it had no effect. As you can see in the phy register output, it tells that there is a link and the auto-negotiation is completed. I can see that the link led is switched on too.

However, when I scan for devices in TwinCAT, it does not find any EtherCAT device. If I read the ESC register 0x110 from the micocontroller, the value is 0x5501, which means that there is no link on the ports 0-3 (bits 4-7).

My colleagues are able to run Profinet and EIP, therefore the HW seems to be fine.

I'd appreaciate any hint on this topic.

Many thanks in advance,

Álvaro

  • Hi,

    I wanted to confirm on few points:

    1. Have you made sure that the driver for DP83867IR is correctly configured, that is, there is no mention of DP83869 phy within the register read/write?
    2. Do you see set bits in the MDIO PHY Alive Reg (0x300B2408). If yes, have you configured the PHY address in sysconfig based on the corresponding bit set in MDIO PHY Alive Reg?
    3. In the case of Enhanced Link enabled (enhancedlink_enable = TIESC_MDIO_RX_LINK_ENABLE), have you configured the link polarity correctly? If there is a bit set in MDIO_LINK_REG (0x300B240C) when the wire is connected, TIESC_LINK0_POL0/1 should be made TIESC_LINK_POL_ACTIVE_HIGH. Otherwise, TIESC_LINK0_POL0/1 should be made TIESC_LINK_POL_ACTIVE_LOW.
    4. Is tiesc_ethphyInit() in tiescsoc.c file updated with DP83867IR based parameters ?

    Regards,
    Aaron 

  • Hi Aaron,

    1. Yes, I double checked the phy register map. I think I had to modify some entry but other than that the registers are almost identical.
    2. I'll double check the mdio phy alive register and come back to you. However, I can interact with the phys. The phy adresses are correct in sysconfig.
    3. I tested with normal and inverted polarity. The normal polarity is the correct one.
    4. Yes, I updated the tiesc_ethphyInit function and I'm configuring the DP83867IR parameters from there. You can find below the code I wrote and diff with the originial tiesc_ethphyInit function and 83869 phy driver.

    void tiesc_ethphyInit(PRUICSS_Handle pruIcssHandle, uint8_t phy0addr,
                         uint8_t phy1addr, uint8_t enhancedlink_enable)
    {
        uint32_t mdioBaseAddress = ((const ETHPHY_Attrs *)ETHPHY_getAttrs(CONFIG_ETHPHY0))->mdioBaseAddress;
    
    #ifdef ICSSG0_INSTANCE
        ETHPHY_DP83826E_LedSourceConfig ledConfig;
        ETHPHY_DP83826E_LedBlinkRateConfig ledBlinkConfig;
        ETHPHY_DP83826E_FastLinkDownDetectionConfig fastLinkDownDetConfig;
    #else
        ETHPHY_DP83867_LedSourceConfig ledConfig;
        ETHPHY_DP83867_LedBlinkRateConfig ledBlinkConfig;
        ETHPHY_DP83867_FastLinkDownDetectionConfig fastLinkDownDetConfig;
    #endif
    
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_AUTO_MDIX, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_AUTO_MDIX, NULL, 0);
    
        if(TIESC_MDIO_RX_LINK_ENABLE == enhancedlink_enable)
        {
            /*TODO: Review these 2 calls*/
        #ifdef ICSSG0_INSTANCE
            ledConfig.ledNum = ETHPHY_DP83826E_LED0;
            ledConfig.mode = ETHPHY_DP83826E_LED_MODE_LINK_OK;
        #else
            ledConfig.ledNum = ETHPHY_DP83867_LED0;
            ledConfig.mode = ETHPHY_DP83867_LED_MODE_LINK_OK;
        #endif
    
            ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
            ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
        }
    
        /* Enable Extended Full-Duplex */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_EXTENDED_FD_ABILITY, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_EXTENDED_FD_ABILITY, NULL, 0);
    
        /* Enable Odd Nibble Detection */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_ODD_NIBBLE_DETECTION, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_ODD_NIBBLE_DETECTION, NULL, 0);
    
        /* Enable detection of RXERR during IDLE */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_ENHANCED_IPG_DETECTION, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_ENHANCED_IPG_DETECTION, NULL, 0);
    
        /* PHY pin LED_0 as link for fast link detection */
    #ifdef ICSSG0_INSTANCE
        ledConfig.ledNum = ETHPHY_DP83826E_LED0;
        ledConfig.mode = ETHPHY_DP83826E_LED_MODE_MII_LINK_100BT_FD;
    #else
        ledConfig.ledNum = ETHPHY_DP83867_LED0;
        ledConfig.mode = ETHPHY_DP83867_LED_MODE_LINK_OK;
    #endif
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
    
        /* PHY pin LED_1 as RX_ER. Needed for detecting RX_ER during frame. */
    #ifdef ICSSG0_INSTANCE
        ledConfig.ledNum = ETHPHY_DP83826E_LED1;
        /*For DP83286E, RX_ER is a separate pin (not an LED pin like DP83867E). Configuring LED_1 for 10M speed indication. */
        ledConfig.mode = ETHPHY_DP83826E_LED_MODE_SPEED_10BT;
     #else
        ledConfig.ledNum = ETHPHY_DP83867_LED1;
        ledConfig.mode = ETHPHY_DP83867_LED_MODE_RX_ERROR;
    #endif
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
    
        /* PHY pin LED_2 as Rx/Tx Activity */
    #ifdef ICSSG0_INSTANCE
        ledConfig.ledNum = ETHPHY_DP83826E_LED2;
        ledConfig.mode = ETHPHY_DP83826E_LED_MODE_LINK_OK_AND_BLINK_ON_RX_TX;
     #else
        ledConfig.ledNum = ETHPHY_DP83867_LED2;
        ledConfig.mode = ETHPHY_DP83867_LED_MODE_LINK_OK_AND_BLINK_ON_RX_TX;
    #endif
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
    
        /* PHY pin LED_3 as 100M link established */
    #ifdef ICSSG0_INSTANCE
        ledConfig.ledNum = ETHPHY_DP83826E_LED2;
        ledConfig.mode = ETHPHY_DP83826E_LED_MODE_MII_LINK_100BT_FD;
    #else
        ledConfig.ledNum = ETHPHY_DP83867_LED_GPIO;
        ledConfig.mode = ETHPHY_DP83867_LED_MODE_10_OR_100BT_LINK_UP;
    
    #endif
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_SOURCE, (void *)&ledConfig, sizeof(ledConfig));
    
    #ifdef ICSSG0_INSTANCE
        ledBlinkConfig.rate = ETHPHY_DP83826E_LED_BLINK_RATE_200_MS;
    #else
        ledBlinkConfig.rate = ETHPHY_DP83867_LED_BLINK_RATE_200_MS;
    #endif
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_CONFIGURE_LED_BLINK_RATE, (void *)&ledBlinkConfig, sizeof(ledBlinkConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_CONFIGURE_LED_BLINK_RATE, (void *)&ledBlinkConfig, sizeof(ledBlinkConfig));
    
        /* Enable fast link drop detection for EtherCAT
         * Bit3: Drop the link based on RX Error count of the MII interface, when a predefined number
         * of 32 RX Error occurrences in a 10us interval is reached, the link will be dropped
         * Bit0(not enabled by following lines): Drop the link based on Signal/Energy loss indication,
         * when the Energy detector indicates Energy Loss, the link will be dropped. Typical reaction
         * time is 10us. If it needs to be enabled, set fastLinkDownDetConfig.mode as
         * (ETHPHY_DP83867_FAST_LINKDOWN_MODE_ENERGY_LOST | ETHPHY_DP83867_FAST_LINKDOWN_MODE_RX_ERR)
         */
    #ifdef ICSSG0_INSTANCE
        fastLinkDownDetConfig.mode = ETHPHY_DP83826E_FAST_LINKDOWN_MODE_RX_ERR;
    #else
        fastLinkDownDetConfig.mode = ETHPHY_DP83867_FAST_LINKDOWN_MODE_RX_ERR;
    #endif
    
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_FAST_LINK_DOWN_DETECTION, (void *)&fastLinkDownDetConfig, sizeof(fastLinkDownDetConfig));
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_FAST_LINK_DOWN_DETECTION, (void *)&fastLinkDownDetConfig, sizeof(fastLinkDownDetConfig));
    
        if(enhancedlink_enable == 0)
        {
            MDIO_enableLinkInterrupt(mdioBaseAddress, 0, phy0addr, MDIO_LINKSEL_MDIO_MODE);
            MDIO_enableLinkInterrupt(mdioBaseAddress, 1, phy1addr, MDIO_LINKSEL_MDIO_MODE);
        }
        else
        {
            MDIO_enableLinkInterrupt(mdioBaseAddress, 0, phy0addr, MDIO_LINKSEL_MLINK_MODE);
            MDIO_enableLinkInterrupt(mdioBaseAddress, 1, phy1addr, MDIO_LINKSEL_MLINK_MODE);
        }
    
        /* Select MII mode */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_MII, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_MII, NULL, 0);
    
        /* Disable 1G advertisement */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_DISABLE_1000M_ADVERTISEMENT, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_DISABLE_1000M_ADVERTISEMENT, NULL, 0);
    
        /* Disable 1G advertisement */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_DISABLE_1000M_ADVERTISEMENT, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_DISABLE_1000M_ADVERTISEMENT, NULL, 0);
    #if 0
        /* Reconfigure ANAR */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_DP83867_CMD_ANAR_100MB, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_DP83867_CMD_ANAR_100MB, NULL, 0);
    
        /* Disable Robust AutoMDIX */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_DP83867_CMD_DISABLE_ROBUST_AUTOMIDX, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_DP83867_CMD_DISABLE_ROBUST_AUTOMIDX, NULL, 0);
    #endif
    }
    
    #ifdef ICSSG0_INSTANCE
    void tiesc_addOnBoardResetSequence()
    {
        GPIO_setDirMode(CONFIG_GPIO_31_BASE_ADDR, CONFIG_GPIO_31_PIN, GPIO_DIRECTION_OUTPUT);
        GPIO_pinWriteHigh(CONFIG_GPIO_31_BASE_ADDR, CONFIG_GPIO_31_PIN);
        GPIO_setDirMode(CONFIG_GPIO_32_BASE_ADDR, CONFIG_GPIO_32_PIN, GPIO_DIRECTION_OUTPUT);
        GPIO_pinWriteHigh(CONFIG_GPIO_32_BASE_ADDR, CONFIG_GPIO_32_PIN);
        ClockP_usleep(1000);
        GPIO_pinWriteLow(CONFIG_GPIO_31_BASE_ADDR, CONFIG_GPIO_31_PIN);
        GPIO_pinWriteLow(CONFIG_GPIO_32_BASE_ADDR, CONFIG_GPIO_32_PIN);
        ClockP_usleep(1000);
        GPIO_pinWriteHigh(CONFIG_GPIO_31_BASE_ADDR, CONFIG_GPIO_31_PIN);
        GPIO_pinWriteHigh(CONFIG_GPIO_32_BASE_ADDR, CONFIG_GPIO_32_PIN);
        ClockP_usleep(1000);
    }
    #endif
    
    void tiesc_ethphyEnablePowerDown()
    {
    #if CONFIG_PRU_ICSS1_CORE_CLK_FREQ_HZ == (333333333U)
        /*Update clock divider for MDIO according to 333 MHz PRU Core Clock*/
        /*FIXME: Fix cleanly by updating the MDIO_initClock API*/
        uint32_t mdioBaseAddress = ((const ETHPHY_Attrs *)ETHPHY_getAttrs(CONFIG_ETHPHY0))->mdioBaseAddress;
        HW_WR_REG32((mdioBaseAddress + CSL_MDIO_CONTROL_REG), (CSL_FMKT(MDIO_CONTROL_REG_ENABLE, YES) | CSL_FMK(MDIO_CONTROL_REG_CLKDIV, MDIO_CLK_DIV_CFG)));
    #endif
        /* Ensure that PHY register access is working by checking the Identifier register */
        while(SystemP_SUCCESS != ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_VERIFY_IDENTIFIER_REGISTER, NULL, 0));
        while(SystemP_SUCCESS != ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_VERIFY_IDENTIFIER_REGISTER, NULL, 0));
    
    #ifdef ICSSG0_INSTANCE
        /* Set Bit6 and Bit8 of DP83826E Auto-Negotiation Advertisemenmt register for PORT0 manually*/
        uint32_t mdioBaseAddress = ((const ETHPHY_Attrs *)ETHPHY_getAttrs(CONFIG_ETHPHY0))->mdioBaseAddress;
        int32_t status;
        uint16_t phyRegVal = 0;
        status = MDIO_phyRegRead(
                            mdioBaseAddress, 
                            NULL, 
                            ((const ETHPHY_Attrs *)ETHPHY_getAttrs(CONFIG_ETHPHY0))->phyAddress,  
                            DP83826E_AUTO_NEGOTIATION_ADVERTISEMENT_REG_ADDRESS, 
                            &phyRegVal);
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegWrite(
                                mdioBaseAddress, 
                                NULL, 
                                ((const ETHPHY_Attrs *)ETHPHY_getAttrs(CONFIG_ETHPHY0))->phyAddress, 
                                DP83826E_AUTO_NEGOTIATION_ADVERTISEMENT_REG_ADDRESS, 
                                phyRegVal | 1<<6 | 1<<8);
        }
    #endif
        /* Enable IEEE Power Down mode so that PHY does not establish any link */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_ENABLE_IEEE_POWER_DOWN, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_ENABLE_IEEE_POWER_DOWN, NULL, 0);
    }
    
    void tiesc_ethphyDisablePowerDown()
    {
        /* Disable IEEE Power Down mode so that PHY does not establish any link */
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY0], ETHPHY_CMD_DISABLE_IEEE_POWER_DOWN, NULL, 0);
        ETHPHY_command(gEthPhyHandle[CONFIG_ETHPHY1], ETHPHY_CMD_DISABLE_IEEE_POWER_DOWN, NULL, 0);
    }
    

    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <ethphy_dp83867.h>
    #include <drivers/mdio.h>
    
    #include <kernel/dpl/DebugP.h>
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    #define ETHPHY_DP83867_BMCR_REG                                     (0x0000)
    #define ETHPHY_DP83867_BMSR_REG                                     (0x0001)
    #define ETHPHY_DP83867_PHYIDR1_REG                                  (0x0002)
    #define ETHPHY_DP83867_PHYIDR2_REG                                  (0x0003)
    #define ETHPHY_DP83867_ANAR_REG                                     (0x0004)
    #define ETHPHY_DP83867_ANLPAR_REG                                   (0x0005)
    #define ETHPHY_DP83867_ANER_REG                                     (0x0006)
    #define ETHPHY_DP83867_ANNPTR_REG                                   (0x0007)
    #define ETHPHY_DP83867_ANNPRR_REG                                   (0x0008)
    #define ETHPHY_DP83867_GEN_CFG1_REG                                 (0x0009)
    #define ETHPHY_DP83867_GEN_STS1_REG                                 (0x000A)
    #define ETHPHY_DP83867_GEN_REGCR_REG                                (0x000D)
    #define ETHPHY_DP83867_GEN_ADDAR_REG                                (0x000E)
    #define ETHPHY_DP83867_GEN_1KSCR_REG                                (0x000F)
    #define ETHPHY_DP83867_PHY_CONTROL_REG                              (0x0010)
    #define ETHPHY_DP83867_PHY_STATUS_REG                               (0x0011)
    #define ETHPHY_DP83867_MICR_REG                                     (0x0012)
    #define ETHPHY_DP83867_ISR_REG                                      (0x0013)
    #define ETHPHY_DP83867_CFG2_REG                                     (0x0014)
    #define ETHPHY_DP83867_RECR_REG                                     (0x0015)
    #define ETHPHY_DP83867_BISCR_REG                                    (0x0016)
    #define ETHPHY_DP83867_STS2_REG                                     (0x0017)
    #define ETHPHY_DP83867_LEDS_CFG1_REG                                (0x0018)
    #define ETHPHY_DP83867_LEDS_CFG2_REG                                (0x0019)
    #define ETHPHY_DP83867_LEDS_CFG3_REG                                (0x001A)
    #define ETHPHY_DP83867_GEN_CFG3_REG                                 (0x001E)
    #define ETHPHY_DP83867_GEN_CTRL_REG                                 (0x001F)
    #define ETHPHY_DP83867_GEN_CFG_FLD_REG                              (0x002D)
    #define ETHPHY_DP83867_RGMII_CTRL_REG                               (0x0032)
    #define ETHPHY_DP83867_RGMII_CTRL2_REG                              (0x0033)
    #define ETHPHY_DP83867_G_100BT_REG0_REG                             (0x0043)
    
    #define ETHPHY_DP83867_BMCR_IEEE_POWER_DOWN_ENABLE_MASK             (0x0800)
    #define ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK              (0x1000)
    #define ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK                      (0x2000)
    #define ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK                      (0x0040)
    #define ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK                          (0x0100)
    #define ETHPHY_DP83867_BMSR_AUTONEG_COMP_MASK                       (0x0020)
    #define ETHPHY_DP83867_ANER_LP_AUTONEG_ABLE_MASK                    (0x0001)
    #define ETHPHY_DP83867_GEN_CFG1_G_1000BT_FD_ADV_MASK                (0x0200)
    #define ETHPHY_DP83867_GEN_CFG1_G_1000BT_HD_ADV_MASK                (0x0100)
    #define ETHPHY_DP83867_PHY_CONTROL_AUTOMDIX_ENABLE_MASK             (0x0040)
    #define ETHPHY_DP83867_PHY_STATUS_SPEED_MASK                        (0xC000)
    #define ETHPHY_DP83867_PHY_STATUS_DUPLEX_MASK                       (0x2000)
    #define ETHPHY_DP83867_LEDS_CFG1_LED_SEL_MASK                       (0x000F)
    #define ETHPHY_DP83867_LEDS_CFG3_LEDS_BLINK_RATE_MASK               (0x0003)
    #define ETHPHY_DP83867_GEN_CFG3_ROBUST_AUTO_MDIX                    (0x0200)
    #define ETHPHY_DP83867_GEN_CFG3_EXT_FD_ENABLE_MASK                  (0x0800)
    #define ETHPHY_DP83867_GEN_CTRL_SW_RESTART_MASK                     (0x4000)
    #define ETHPHY_DP83867_GEN_CFG_FLD_FAST_LINK_DOWN_MODES_MASK        (0x001F)
    #define ETHPHY_DP83867_RGMII_CTRL_RX_HALF_FULL_THR_LSB_MASK         (0x0060)
    #define ETHPHY_DP83867_RGMII_CTRL_TX_HALF_FULL_THR_LSB_MASK         (0x0018)
    #define ETHPHY_DP83867_RGMII_CTRL2_RX_HALF_FULL_THR_MSB_MASK        (0x0002)
    #define ETHPHY_DP83867_RGMII_CTRL2_TX_HALF_FULL_THR_MSB_MASK        (0x0001)
    #define ETHPHY_DP83867_RGMII_CTRL2_LOW_LATENCY_10_100_EN_MASK       (0x0004)
    #define ETHPHY_DP83867_G_100BT_REG0_ENHANCED_IPG_DET_ENABLE_MASK    (0x0010)
    #define ETHPHY_DP83867_G_100BT_REG0_ODDNIBBLE_DET_ENABLE_MASK       (0x0002)
    #define ETHPHY_DP83867_RGMIICTL_RGMII_ENABLE_MASK                   (0x0080)
    
    #define ETHPHY_DP83867_RGMII_CTRL_RX_HALF_FULL_THR_LSB_SHIFT        (0x0005)
    #define ETHPHY_DP83867_RGMII_CTRL_TX_HALF_FULL_THR_LSB_SHIFT        (0x0003)
    #define ETHPHY_DP83867_RGMII_CTRL2_RX_HALF_FULL_THR_MSB_SHIFT       (0x0001)
    #define ETHPHY_DP83867_RGMII_CTRL2_TX_HALF_FULL_THR_MSB_SHIFT       (0x0000)
    
    #define ETHPHY_DP83867_PHYIDR1_REG_VALUE                            (0x2000)
    
    #define ETHPHY_DP83867_PHY_STATUS_SPEED_10M                         (0x0000)
    #define ETHPHY_DP83867_PHY_STATUS_SPEED_100M                        (0x4000)
    #define ETHPHY_DP83867_PHY_STATUS_SPEED_1000M                       (0xC000)
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    
    int32_t ETHPHY_DP83867_open(ETHPHY_Config *config, const ETHPHY_Params *params);
    
    int32_t ETHPHY_DP83867_command(ETHPHY_Config *config,
                                   uint32_t command,
                                   void *data,
                                   uint32_t dataSize);
    
    static int32_t ETHPHY_DP83867_enableMii(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_softRestart(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_enableAutoMdix(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_verifyIdentifierRegister(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_disable1000mAdvertisement(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_enableFastLinkDownDetection(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_configureLedSource(ETHPHY_Attrs *attrs,
                                                     void         *data,
                                                     uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_configureLedBlinkRate(ETHPHY_Attrs *attrs,
                                                        void         *data,
                                                        uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_enableExtendedFdAbility(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_disableRobustAutoMDIX(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_enableOddNibbleDetection(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_enableEnhancedIpgDetection(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_getSpeedDuplex(ETHPHY_Attrs *attrs,
                                                    void         *data,
                                                    uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_setSpeedDuplex(ETHPHY_Attrs *attrs,
                                                    void         *data,
                                                    uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_enableLowLatencyRgmii(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_setRxHalfFullThresholdRgmii(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_setTxHalfFullThresholdRgmii(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_getAutonegCompleteStatus(ETHPHY_Attrs *attrs,
                                                           void         *data,
                                                           uint32_t     dataSize);
    
    
    static int32_t ETHPHY_DP83867_getLinkPartnerAutonegAbility(ETHPHY_Attrs *attrs,
                                                               void         *data,
                                                               uint32_t     dataSize);
    
    static int32_t ETHPHY_DP83867_enableIeeePowerDownMode(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_disableIeeePowerDownMode(ETHPHY_Attrs *attrs);
    
    static int32_t ETHPHY_DP83867_printRegs(ETHPHY_Attrs *attrs);
    
    static int32_t Board_setAdv100M_FD(ETHPHY_Attrs *attrs);
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    ETHPHY_Fxns gEthPhyFxns_DP83867 =
    {
        .openFxn    = ETHPHY_DP83867_open,
        .closeFxn   = NULL,
        .commandFxn = ETHPHY_DP83867_command,
    };
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    
    int32_t ETHPHY_DP83867_open(ETHPHY_Config *config, const ETHPHY_Params *params)
    {
        int32_t         status = SystemP_SUCCESS;
        ETHPHY_Attrs    *attrs;
    
        if((NULL == config) || (NULL == params) || (NULL == config->attrs))
        {
            status = SystemP_FAILURE;
        }
        else
        {
            attrs = config->attrs;
            status = MDIO_initClock(attrs->mdioBaseAddress);
        }
    
        return status;
    }
    
    int32_t ETHPHY_DP83867_command(ETHPHY_Config *config,
                                   uint32_t command,
                                   void *data,
                                   uint32_t dataSize)
    {
        int32_t         status = SystemP_SUCCESS;
        ETHPHY_Attrs    *attrs;
    
        if(NULL == config)
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            attrs = config->attrs;
            switch (command)
            {
            case ETHPHY_CMD_ENABLE_MII :
                status = ETHPHY_DP83867_enableMii(attrs);
                break;
    
            case ETHPHY_CMD_SOFT_RESTART :
                status = ETHPHY_DP83867_softRestart(attrs);
                break;
    
            case ETHPHY_CMD_ENABLE_AUTO_MDIX :
                status = ETHPHY_DP83867_enableAutoMdix(attrs);
                break;
    
            case ETHPHY_CMD_VERIFY_IDENTIFIER_REGISTER :
                status = ETHPHY_DP83867_verifyIdentifierRegister(attrs);
                break;
    
            case ETHPHY_CMD_DISABLE_1000M_ADVERTISEMENT :
                status = ETHPHY_DP83867_disable1000mAdvertisement(attrs);
                break;
    
            case ETHPHY_CMD_ENABLE_FAST_LINK_DOWN_DETECTION :
                status = ETHPHY_DP83867_enableFastLinkDownDetection(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_CONFIGURE_LED_SOURCE :
                status = ETHPHY_DP83867_configureLedSource(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_CONFIGURE_LED_BLINK_RATE :
                status = ETHPHY_DP83867_configureLedBlinkRate(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_ENABLE_EXTENDED_FD_ABILITY :
                status = ETHPHY_DP83867_enableExtendedFdAbility(attrs);
                break;
    
            case ETHPHY_CMD_ENABLE_ODD_NIBBLE_DETECTION :
                status = ETHPHY_DP83867_enableOddNibbleDetection(attrs);
                break;
    
            case ETHPHY_CMD_ENABLE_ENHANCED_IPG_DETECTION :
                status = ETHPHY_DP83867_enableEnhancedIpgDetection(attrs);
                break;
    
            case ETHPHY_CMD_GET_LINK_STATUS :
                status = MDIO_phyLinkStatus(attrs->mdioBaseAddress, attrs->phyAddress);
                break;
    
            case ETHPHY_CMD_GET_SPEED_AND_DUPLEX_CONFIG :
                status = ETHPHY_DP83867_getSpeedDuplex(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_SET_SPEED_AND_DUPLEX_CONFIG :
                status = ETHPHY_DP83867_setSpeedDuplex(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_ENABLE_LOW_LATENCY_10M_100M_RGMII:
                status = ETHPHY_DP83867_enableLowLatencyRgmii(attrs);
                break;
    
            case ETHPHY_CMD_SET_RX_HALF_FULL_THRESHOLD_RGMII:
                status = ETHPHY_DP83867_setRxHalfFullThresholdRgmii(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_SET_TX_HALF_FULL_THRESHOLD_RGMII:
                status = ETHPHY_DP83867_setTxHalfFullThresholdRgmii(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_GET_AUTONEG_COMPLETE_STATUS:
                status = ETHPHY_DP83867_getAutonegCompleteStatus(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_GET_LINK_PARTNER_AUTONEG_ABILITY:
                status = ETHPHY_DP83867_getLinkPartnerAutonegAbility(attrs, data, dataSize);
                break;
    
            case ETHPHY_CMD_ENABLE_IEEE_POWER_DOWN:
                status = ETHPHY_DP83867_enableIeeePowerDownMode(attrs);
                break;
    
            case ETHPHY_CMD_DISABLE_IEEE_POWER_DOWN:
                status = ETHPHY_DP83867_disableIeeePowerDownMode(attrs);
                break;
            case ETHPHY_DP83867_CMD_PRINT_REGISTERS:
                status = ETHPHY_DP83867_printRegs(attrs);
                break;
            case ETHPHY_DP83867_CMD_ANAR_100MB:
                status = Board_setAdv100M_FD(attrs);
                break;
            case ETHPHY_DP83867_CMD_DISABLE_ROBUST_AUTOMIDX:
                status = ETHPHY_DP83867_disableRobustAutoMDIX(attrs);
                break;
    
            default:
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableMii(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal &= ~ETHPHY_DP83867_RGMIICTL_RGMII_ENABLE_MASK;
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_softRestart(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CTRL_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= ETHPHY_DP83867_GEN_CTRL_SW_RESTART_MASK;
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CTRL_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableAutoMdix(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHY_CONTROL_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= ETHPHY_DP83867_PHY_CONTROL_AUTOMDIX_ENABLE_MASK;
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHY_CONTROL_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_verifyIdentifierRegister(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHYIDR1_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            if(phyRegVal == ETHPHY_DP83867_PHYIDR1_REG_VALUE)
            {
                status = SystemP_SUCCESS;
            }
            else
            {
                status = SystemP_FAILURE;
            }
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_disable1000mAdvertisement(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG1_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal &= ~ETHPHY_DP83867_GEN_CFG1_G_1000BT_FD_ADV_MASK;
            phyRegVal &= ~ETHPHY_DP83867_GEN_CFG1_G_1000BT_HD_ADV_MASK;
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG1_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableFastLinkDownDetection(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint32_t mode;
    
        if((data == NULL) || (dataSize != sizeof(ETHPHY_DP83867_FastLinkDownDetectionConfig)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG_FLD_REG, &phyRegVal);
        }
        if(status == SystemP_SUCCESS)
        {
            mode = ((ETHPHY_DP83867_FastLinkDownDetectionConfig *)data)->mode;
    
            phyRegVal &= ~(ETHPHY_DP83867_GEN_CFG_FLD_FAST_LINK_DOWN_MODES_MASK);
            phyRegVal |= (mode & ETHPHY_DP83867_GEN_CFG_FLD_FAST_LINK_DOWN_MODES_MASK);
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG_FLD_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_configureLedSource(ETHPHY_Attrs *attrs,
                                                     void         *data,
                                                     uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint32_t ledNum;
        uint32_t mode;
    
        if((data == NULL) || (dataSize != sizeof(ETHPHY_DP83867_LedSourceConfig)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG1_REG, &phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            ledNum = ((ETHPHY_DP83867_LedSourceConfig *)data)->ledNum;
            mode = ((ETHPHY_DP83867_LedSourceConfig *)data)->mode;
    
            switch(ledNum)
            {
                case ETHPHY_DP83867_LED0:
                    phyRegVal &= ~(ETHPHY_DP83867_LEDS_CFG1_LED_SEL_MASK << 0);
                    phyRegVal |= (mode << 0);
                    break;
    
                case ETHPHY_DP83867_LED1:
                    phyRegVal &= ~(ETHPHY_DP83867_LEDS_CFG1_LED_SEL_MASK << 4);
                    phyRegVal |= (mode << 4);
                    break;
    
                case ETHPHY_DP83867_LED2:
                    phyRegVal &= ~(ETHPHY_DP83867_LEDS_CFG1_LED_SEL_MASK << 8);
                    phyRegVal |= (mode << 8);
                    break;
    
                case ETHPHY_DP83867_LED_GPIO:
                    phyRegVal &= ~(ETHPHY_DP83867_LEDS_CFG1_LED_SEL_MASK << 12);
                    phyRegVal |= (mode << 12);
                    break;
            }
    
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG1_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_configureLedBlinkRate(ETHPHY_Attrs *attrs,
                                                        void         *data,
                                                        uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint32_t blinkRate;
    
        if((data == NULL) || (dataSize != sizeof(ETHPHY_DP83867_LedBlinkRateConfig)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG3_REG, &phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            blinkRate = ((ETHPHY_DP83867_LedBlinkRateConfig *)data)->rate;
    
            phyRegVal &= ~(ETHPHY_DP83867_LEDS_CFG3_LEDS_BLINK_RATE_MASK);
            phyRegVal |= blinkRate;
    
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG3_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableExtendedFdAbility(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG3_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= ETHPHY_DP83867_GEN_CFG3_EXT_FD_ENABLE_MASK;
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG3_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_disableRobustAutoMDIX(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG3_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal &= ~ETHPHY_DP83867_GEN_CFG3_ROBUST_AUTO_MDIX;
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG3_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableOddNibbleDetection(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_G_100BT_REG0_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= (ETHPHY_DP83867_G_100BT_REG0_ODDNIBBLE_DET_ENABLE_MASK);
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_G_100BT_REG0_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableEnhancedIpgDetection(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_G_100BT_REG0_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= (ETHPHY_DP83867_G_100BT_REG0_ENHANCED_IPG_DET_ENABLE_MASK);
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_G_100BT_REG0_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_getSpeedDuplex(ETHPHY_Attrs *attrs,
                                                    void         *data,
                                                    uint32_t     dataSize)
    {
        uint16_t phyRegVal = 0;
        int32_t status = SystemP_SUCCESS;
        ETHPHY_SpeedDuplexConfig *pSpeedDuplex = NULL;
    
        if((data == NULL) || (dataSize != sizeof(ETHPHY_DP83867_LedBlinkRateConfig)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHY_STATUS_REG, &phyRegVal);
            pSpeedDuplex = (ETHPHY_SpeedDuplexConfig *)data;
        }
    
        if(status == SystemP_SUCCESS)
        {
            if((phyRegVal & ETHPHY_DP83867_PHY_STATUS_SPEED_MASK) == ETHPHY_DP83867_PHY_STATUS_SPEED_10M)  /*Speed is 10*/
            {
                if(phyRegVal & ETHPHY_DP83867_PHY_STATUS_DUPLEX_MASK)
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_10FD;
                }
    
                else
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_10HD;
                }
            }
            else if((phyRegVal & ETHPHY_DP83867_PHY_STATUS_SPEED_MASK) == ETHPHY_DP83867_PHY_STATUS_SPEED_100M)/*Speed is 100*/
            {
                if(phyRegVal & ETHPHY_DP83867_PHY_STATUS_DUPLEX_MASK)
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_100FD;
                }
    
                else
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_100HD;
                }
            }
            else if((phyRegVal & ETHPHY_DP83867_PHY_STATUS_SPEED_MASK) == ETHPHY_DP83867_PHY_STATUS_SPEED_1000M)/*Speed is 1000*/
            {
                if(phyRegVal & ETHPHY_DP83867_PHY_STATUS_DUPLEX_MASK)
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_1000FD;
                }
    
                else
                {
                    pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_1000HD;
                }
            }
            else
            {
                pSpeedDuplex->config = ETHPHY_SPEED_DUPLEX_CONFIG_INVALID;
            }
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_setSpeedDuplex(ETHPHY_Attrs *attrs,
                                                    void         *data,
                                                    uint32_t     dataSize)
    {
        uint16_t phyRegVal = 0;
        int32_t status = SystemP_SUCCESS;
        uint32_t config;
    
        if((data == NULL) || (dataSize != sizeof(ETHPHY_DP83867_LedBlinkRateConfig)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, &phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            config = ((ETHPHY_SpeedDuplexConfig *)data)->config;
    
            switch(config)
            {
                case ETHPHY_SPEED_DUPLEX_CONFIG_AUTONEG:
                    phyRegVal |= ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK;
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_10FD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK);
                    phyRegVal |= ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK;
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_100FD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK);
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK;
                    phyRegVal |= ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK;
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_1000FD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK;
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK;
                    phyRegVal |= ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK;
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_10HD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK);
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_100HD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK);
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK;
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK);
                    break;
    
                case ETHPHY_SPEED_DUPLEX_CONFIG_1000HD:
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_AUTO_NEGOTIATE_ENABLE_MASK);
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_MSB_MASK;
                    phyRegVal |= ETHPHY_DP83867_BMCR_SPEED_SEL_LSB_MASK;
                    phyRegVal &= ~(ETHPHY_DP83867_BMCR_DUPLEX_EN_MASK);
                    break;
    
                default:
                    status = SystemP_FAILURE;
                    break;
            }
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, phyRegVal);
        }
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableLowLatencyRgmii(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= (ETHPHY_DP83867_RGMII_CTRL2_LOW_LATENCY_10_100_EN_MASK);
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_setRxHalfFullThresholdRgmii(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint16_t phyRegVal2 = 0;
        uint8_t value;
        uint8_t valueLsbs;
        uint8_t valueMsb;
    
        if((data == NULL) || (dataSize != sizeof(uint8_t)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, &phyRegVal);
            status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, &phyRegVal2);
        }
    
        if(status == SystemP_SUCCESS)
        {
            value = (uint8_t)(*(uint8_t *)data);
    
            /*Store 2 LSBs from value(Bits[1:0]) into Bits[1:0] of valueLsbs*/
            valueLsbs = (value & 0x03);
    
            /*Store MSB from value(Bit[2]) into Bit[0] of valueMsb*/
            valueMsb = (value & 0x04);
            valueMsb >>= 2;
    
            /* Set lower 2 bits in Bits[6:5] of RGMII_CTRL and MSB in Bit[1] of RGMII_CTRL2*/
            phyRegVal &= ~(ETHPHY_DP83867_RGMII_CTRL_RX_HALF_FULL_THR_LSB_MASK);
            phyRegVal |= (valueLsbs << ETHPHY_DP83867_RGMII_CTRL_RX_HALF_FULL_THR_LSB_SHIFT);
            phyRegVal2 &= ~(ETHPHY_DP83867_RGMII_CTRL2_RX_HALF_FULL_THR_MSB_MASK);
            phyRegVal2 |= (valueMsb << ETHPHY_DP83867_RGMII_CTRL2_RX_HALF_FULL_THR_MSB_SHIFT);
    
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, phyRegVal2);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_setTxHalfFullThresholdRgmii(ETHPHY_Attrs *attrs,
                                                              void         *data,
                                                              uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint16_t phyRegVal2 = 0;
        uint8_t value;
        uint8_t valueLsbs;
        uint8_t valueMsb;
    
        if((data == NULL) || (dataSize != sizeof(uint8_t)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, &phyRegVal);
            status = MDIO_phyExtRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, &phyRegVal2);
        }
    
        if(status == SystemP_SUCCESS)
        {
            value = (uint8_t)(*(uint8_t *)data);
    
            /*Store 2 LSBs from value(Bits[1:0]) into Bits[1:0] of valueLsbs*/
            valueLsbs = (value & 0x03);
    
            /*Store MSB from value(Bit[2]) into Bit[0] of valueMsb*/
            valueMsb = (value & 0x04);
            valueMsb >>= 2;
    
            /* Set lower 2 bits in Bits[4:3] of RGMII_CTRL and MSB in Bit[0] of RGMII_CTRL2*/
            phyRegVal &= ~(ETHPHY_DP83867_RGMII_CTRL_TX_HALF_FULL_THR_LSB_MASK);
            phyRegVal |= (valueLsbs << ETHPHY_DP83867_RGMII_CTRL_TX_HALF_FULL_THR_LSB_SHIFT);
            phyRegVal2 &= ~(ETHPHY_DP83867_RGMII_CTRL2_TX_HALF_FULL_THR_MSB_MASK);
            phyRegVal2 |= (valueMsb << ETHPHY_DP83867_RGMII_CTRL2_TX_HALF_FULL_THR_MSB_SHIFT);
    
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyExtRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, phyRegVal2);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_getAutonegCompleteStatus(ETHPHY_Attrs *attrs,
                                                           void         *data,
                                                           uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint8_t *value = (uint8_t *)data;
    
        if((data == NULL) || (dataSize != sizeof(uint8_t)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMSR_REG, &phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            if(phyRegVal & ETHPHY_DP83867_BMSR_AUTONEG_COMP_MASK)
            {
                *value = 1;
            }
            else
            {
                *value = 0;
            }
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_getLinkPartnerAutonegAbility(ETHPHY_Attrs *attrs,
                                                               void         *data,
                                                               uint32_t     dataSize)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
        uint8_t *value = (uint8_t *)data;
    
        if((data == NULL) || (dataSize != sizeof(uint8_t)))
        {
            status = SystemP_FAILURE;
        }
    
        if(status == SystemP_SUCCESS)
        {
            status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANER_REG, &phyRegVal);
        }
    
        if(status == SystemP_SUCCESS)
        {
            if(phyRegVal & ETHPHY_DP83867_ANER_LP_AUTONEG_ABLE_MASK)
            {
                *value = 1;
            }
            else
            {
                *value = 0;
            }
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_enableIeeePowerDownMode(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal |= (ETHPHY_DP83867_BMCR_IEEE_POWER_DOWN_ENABLE_MASK);
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_disableIeeePowerDownMode(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_FAILURE;
        uint16_t phyRegVal = 0;
    
        status = MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, &phyRegVal);
    
        if(status == SystemP_SUCCESS)
        {
            phyRegVal &= ~(ETHPHY_DP83867_BMCR_IEEE_POWER_DOWN_ENABLE_MASK);
            status = MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, phyRegVal);
        }
    
        return status;
    }
    
    static int32_t ETHPHY_DP83867_printRegs(ETHPHY_Attrs *attrs)
    {
        int32_t status = SystemP_SUCCESS;
        uint16_t phyRegVal = 0;
    
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: BMCR        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMSR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: BMSR        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHYIDR1_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: PHYIDR1     = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHYIDR2_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: PHYIDR2     = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANAR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ANAR        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANLPAR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ANLPAR      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANER_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ANER        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANNPTR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ANNPTR      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANNPRR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ANNPRR      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG1_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: CFG1        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_STS1_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: STS1        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_REGCR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: REGCR       = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_1KSCR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: 1KSCR       = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHY_CONTROL_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: PHYCR       = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_PHY_STATUS_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: PHYSTS      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_MICR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: MICR        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ISR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: ISR         = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_CFG2_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: CFG2        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RECR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: RECR        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BISCR_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: BISCR       = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_STS2_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: STS2        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG1_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: LEDCR1      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG2_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: LEDCR2      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_LEDS_CFG3_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: LEDCR3      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG3_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: CFG3        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CTRL_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: CTRL        = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_GEN_CFG_FLD_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: FLDCFG      = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: RGMIICTL    = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_RGMII_CTRL2_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: RGMIICTL2   = 0x%04x\n", attrs->phyAddress, phyRegVal);
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_G_100BT_REG0_REG, &phyRegVal);
        DebugP_logInfo("PHY %u: 100CR       = 0x%04x\n", attrs->phyAddress, phyRegVal);
    
        return status;
    }
    
    int32_t Board_setAdv100M_FD(ETHPHY_Attrs *attrs)
    {
        uint16_t regData = 0;
    
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANAR_REG, &regData);
    
        /* Only enable 100M FD advertisement */
        // (1 << 5) | (1 << 6) | (1 << 7)
        //regData &= ~((1 << 5) | (1 << 6) | (1 << 7));
        regData |= ((1 << 8) | (1 << 6) | (1 << 7));
    
        MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_ANAR_REG, regData);
    
    
        MDIO_phyRegRead(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, &regData);
    
        /* Enable and restart Auto negotiation */
        regData |= 0x1200;
    
        MDIO_phyRegWrite(attrs->mdioBaseAddress, NULL, attrs->phyAddress, ETHPHY_DP83867_BMCR_REG, regData);
    
        return SystemP_SUCCESS;
    }

    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #ifndef ETHPHY_DP83867_H_
    #define ETHPHY_DP83867_H_
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <board/ethphy.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    /**
     *  \anchor ETHPHY_DP83867_LEDS
     *  \name ETHPHY DP83867 LEDS
     *
     *  Different LEDs present in ETHPHY DP83867
     *
     *  @{
     */
    #define ETHPHY_DP83867_LED0                                     (0x0)
    #define ETHPHY_DP83867_LED1                                     (0x1)
    #define ETHPHY_DP83867_LED2                                     (0x2)
    #define ETHPHY_DP83867_LED_GPIO                                 (0x3)
    /** @} */
    
    /**
     *  \anchor ETHPHY_DP83867_LED_MODES
     *  \name ETHPHY DP83867 LED MODES
     *
     *  Different modes for LED present in ETHPHY DP83867
     *
     *  @{
     */
    #define ETHPHY_DP83867_LED_MODE_LINK_OK                         (0x0)
    #define ETHPHY_DP83867_LED_MODE_RX_TX_ACTIVITY                  (0x1)
    #define ETHPHY_DP83867_LED_MODE_TX_ACTIVITY                     (0x2)
    #define ETHPHY_DP83867_LED_MODE_RX_ACTIVITY                     (0x3)
    #define ETHPHY_DP83867_LED_MODE_COLLISION_DETECTED              (0x4)
    #define ETHPHY_DP83867_LED_MODE_1000BT_LINK_UP                  (0x5)
    #define ETHPHY_DP83867_LED_MODE_100BTX_LINK_UP                  (0x6)
    #define ETHPHY_DP83867_LED_MODE_10BT_LINK_UP                    (0x7)
    #define ETHPHY_DP83867_LED_MODE_10_OR_100BT_LINK_UP             (0x8)
    #define ETHPHY_DP83867_LED_MODE_100_OR_1000BT_LINK_UP           (0x9)
    #define ETHPHY_DP83867_LED_MODE_FULL_DUPLEX                     (0xA)
    #define ETHPHY_DP83867_LED_MODE_LINK_OK_AND_BLINK_ON_RX_TX      (0xB)
    #define ETHPHY_DP83867_LED_MODE_RX_ERROR_OR_TX_ERROR            (0xD)
    #define ETHPHY_DP83867_LED_MODE_RX_ERROR                        (0xE)
    /** @} */
    
    /**
     *  \anchor ETHPHY_DP83867_LED_BLINK_RATES
     *  \name ETHPHY DP83867 LED BLINK RATES
     *
     *  Different blink rates for LED present in ETHPHY DP83867
     *
     *  @{
     */
    #define ETHPHY_DP83867_LED_BLINK_RATE_50_MS                     (0x0)
    #define ETHPHY_DP83867_LED_BLINK_RATE_100_MS                    (0x1)
    #define ETHPHY_DP83867_LED_BLINK_RATE_200_MS                    (0x2)
    #define ETHPHY_DP83867_LED_BLINK_RATE_500_MS                    (0x3)
    /** @} */
    
    /**
     *  \anchor ETHPHY_DP83867_FAST_LINKDOWN_MODES
     *  \name ETHPHY DP83867 FAST LINKDOWN MODES
     *
     *  Different modes for fast link down detection in ETHPHY DP83867
     *
     *  @{
     */
    #define ETHPHY_DP83867_FAST_LINKDOWN_MODE_ENERGY_LOST           (1u<<0)
    #define ETHPHY_DP83867_FAST_LINKDOWN_MODE_MSE                   (1u<<1)
    #define ETHPHY_DP83867_FAST_LINKDOWN_MODE_MLT3_ERRORS           (1u<<2)
    #define ETHPHY_DP83867_FAST_LINKDOWN_MODE_RX_ERR                (1u<<3)
    #define ETHPHY_DP83867_FAST_LINKDOWN_MODE_DESCRAMBLER_SYNC_LOSS (1u<<4)
    /** @} */
    
    #define ETHPHY_DP83867_CMD_PRINT_REGISTERS                      (21U)
    #define ETHPHY_DP83867_CMD_ANAR_100MB                           (22U)
    #define ETHPHY_DP83867_CMD_DISABLE_ROBUST_AUTOMIDX              (23U)
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    /**
     * \brief Data structure to ETHPHY_DP83867 Object
     */
    typedef struct ETHPHY_DP83867_Object_s {
        uint32_t reserved; /**< reserved for future use */
    } ETHPHY_DP83867_Object;
    
    /**
     * \brief Data structure to be passed when calling \ref ETHPHY_command with
     *        \ref ETHPHY_CMD_CONFIGURE_LED_SOURCE for DP83867 PHY
     */
    typedef struct ETHPHY_DP83867_LedSourceConfig_s
    {
        uint32_t ledNum; /**< LED number from \ref ETHPHY_DP83867_LEDS */
        uint32_t mode;   /**< LED mode from \ref ETHPHY_DP83867_LED_MODES */
    } ETHPHY_DP83867_LedSourceConfig;
    
    /**
     * \brief Data structure to be passed when calling \ref ETHPHY_command with
     *        \ref ETHPHY_CMD_CONFIGURE_LED_BLINK_RATE for DP83867 PHY
     */
    typedef struct ETHPHY_DP83867_LedBlinkRateConfig_s
    {
        uint32_t rate; /**< LED Blink Rate. Allowed values are
                            \ref ETHPHY_DP83867_LED_BLINK_RATES */
    } ETHPHY_DP83867_LedBlinkRateConfig;
    
    /**
     * \brief Data structure to be passed when calling \ref ETHPHY_command with
     *        \ref ETHPHY_CMD_ENABLE_FAST_LINK_DOWN_DETECTION for DP83867 PHY
     */
    typedef struct ETHPHY_DP83867_FastLinkDownDetectionConfig_s
    {
        uint32_t mode; /**< Fast link down detection mode. One or more mode can
                            be passed from \ref ETHPHY_DP83867_FAST_LINKDOWN_MODES.
                            If multiple modes are used, the value of this parameter
                            should be Bitwise OR of individual modes. */
    } ETHPHY_DP83867_FastLinkDownDetectionConfig;
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    extern ETHPHY_Fxns gEthPhyFxns_DP83867;
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* #ifndef ETHPHY_DP83867_H_ */
    
    /** @} */

  • PS: In case you wonder which ICSS I'm using, I'm using ICSS1.

  • Hello again Aaron,

    MDIO_LINK_REG (0x300B240C) value is 1, thus polarity must be HIGH. I have it configured that way.

    MDIO PHY Alive Reg (0x300B2408) value is 9. Do you know what does it mean?

    Thanks in advance,

    Álvaro

  • Hello Alvaro,

    MDIO_LINK_REG (0x300B240C) value is 1, thus polarity must be HIGH. I have it configured that way.
    • Value is 1 when the SubDevice is connected to the network by plugging in the ethernet cable, right?
    MDIO PHY Alive Reg (0x300B2408) value is 9. Do you know what does it mean?
    • Value of 9 means that bit0 and bit3 is set. This implies the MDIO Phy Address to be configured in sysconfig is 0 and 3. Anyway this seems to be correct from the PHY Reg values you shared earlier. Do confirm if sysconfig is configured for PHY address 0 and 3.
    You can find below the code I wrote and diff with the originial tiesc_ethphyInit function and 83869 phy driver.
    • I'll review this and get back to you.

    Regards,
    Aaron

  • Hi Aaron,

    Thanks for the feedback.

    Yes it's correct, the network cable is connected to the subdevice. And the phy adresses are correct, 

  • Thank you Alvaro. Give me sometime to look into this. The main points looks to be taken care of. I'll look a bit deeper and see what may be going wrong.

    Regards,
    Aaron

  • Hello Aaron,

    I’m still stuck but I want to share with you some findings I made:

    • I investigated the PRU-ICSS-EtherCAT_Slave_01.00.10.00 because there is an example for AM65x IDK with the 83867IR phy. I found out that, apart from the default phy configuration the register 0x172 is written with the value 0x60. I tested that but it didn’t change anything.
    • If possible, I would really appreciate if someone could read the phy register values and ESC register 0x110 on the AM65x IDK.
    • First time I read the 0x110 ESC register, it tells me 0x5501 (no link), however after a second read it always tells 0x5711. It means:
      o There is a physical link on port 0 (bit 4). Good.
      o Loop port 0 is closed (bit 8). This is strange, it should be open.
      o Communication stablished on port 0 (bit 9). Sounds good.
    • Please have a look to the EtherCAT ESC datasheet section 2 (Registers). On Table 23, the register 0x111 possible values are specified. I expect to read 0x55 when I have no cable and 0x56 when I plug the cable. 0x57 is unspecified value because the next foreseen value is 0x59.

    If you have some idea why this is happening, I’d appreciate to hear that.

    PS: I see that accidentally I didn't add the phy restart call at the end of the phy configuration in the tiesc_ethphyInit function. I set it back but I see no difference.

    Best regards,
    Álvaro

  • Hi Alvaro,

    As discussed, make sure that the PHY address is mapped correctly to MII instance. I also reviewed tiesc_ethphyInit() you defined. Looks to be fine.

    Regards,
    Aaron

  • Hi Aaron,

    I'm sorry but I'm not following you. How do I that? Could you please provide more information?

    To wrap it up, what I see is this:

    • The phy address is read correctly from the sysconfig files in the tiesc_socParamsInit function.
    • bsp_init functions calls bsp_pruss_mdio_init. The phy addresses from sysconfig are written over MDIO to the ESC_ADDR_TI_PORT0_PHYADDR and ESC_ADDR_TI_PORT1_PHYADDR registers.
    • bsp_pruss_mdio_init function calls tiesc_ethphyInit. This functions configures the phy registers and performs a phy soft-reset.

    Thus the initalization should be fine, it's all TI code. We already double checked the MDIO phy alive registers and saw that the values are correct.

    As I said, I'd appreciate some clarification regarding the phy address mapping to MII.

    Best regards,

    Álvaro

  • Hi Alvaro,

    Can you share the MII_RT_RXCFG0, MII_RT_RXCFG1, MII_RT_TXCFG0 and MII_RT_TXCFG1 register values (Register spaces 0x300B2000, 0x300B2004, 0x300B2010 and 0x300B2014) respectively. You can refer to Section 6.4.14.11 PRU_MII_RT_MII_RT Registers of AM64x/AM243x: Technical Reference Manual.

    Also, can you swap the MDIO Phy Addresses (0 -> 3 and 3 -> 0) and try swapping the port while connecting.

    Regards,
    Aaron

  • Hi Aaron,

    I swapped the phy addresses and the cable but it didnt work out. These are the results of the combinations:

    1. Cable in IN port and default phy address: ESC reg 0x110 = 0x5711 (link but port closed)
    2. Cable in IN port and swapped phy address:  ESC reg 0x110 = 0x5501 (no link and port closed)
    3. Cable in OUT port and default phy address: ESC reg 0x110 = 0x5D21 (link but port closed)
    4. Cable in OUT port and swapped phy address:  ESC reg 0x110 = 0x5501 (no link and port closed)

    As you can see, with the default phy addreess, the values are more senseful and show at least a link. I still wonder why it is not able to open the port.

    Regarding to the PRU register values, with my default configuration, the values are these:

    PRU_ICSSG1_PR1_MII_RT_PR1_MII_RT_CFG_PR1_MII_RT__PR1_MII_RT_CFG__REGS_rxcfg0
    00000041

    PRU_ICSSG1_PR1_MII_RT_PR1_MII_RT_CFG_PR1_MII_RT__PR1_MII_RT_CFG__REGS_rxcfg1
    00000059

    PRU_ICSSG1_PR1_MII_RT_PR1_MII_RT_CFG_PR1_MII_RT__PR1_MII_RT_CFG__REGS_txcfg0
    00480500

    PRU_ICSSG1_PR1_MII_RT_PR1_MII_RT_CFG_PR1_MII_RT__PR1_MII_RT_CFG__REGS_txcfg1
    00480401

    I tried to understand the values but I'm not able to interpret the meaning clearly. I hope you can understand it better than me.

    Kind regards,

    Álvaro

  • Hi Aaron,

    I edited my previous post because I read the ESC values with MDIO mode disabled. In that mode I always read 0x5501 in ESC register 0x110.

    The values above are with manual MDIO mode enabled.

  • Thanks Alvaro. I'll review the values and get back to you.

    Regards,
    Aaron

  • Hi Aaron,

    I'm still stuck with the issue but I'ld like to share some findings. If I disable the enhanced link detection, then on port 0, it still tells me 0x5711 (link but port closed). However, on port 1, the value is 0x5921 (link and port open). I tried to scan but nothing happened.

    In addition to that, I switched the cable from port 1 to port 0 and the register 0x110 value didt not update, it kept the value 0x5921 (link and port open on port 1). Idk if its related to the enhanced link detection. I need to look more into this.

    Another thing is that, if I enable the enhanced link detection, although its written to a propietary register and so on, it does not reflect in the ESC register 0x8 (ESC Features bit 6) or in the ESC register 0x141 (ESC Configuration bit 4 and bit 5).

    I tried the TI example on the EVM and I saw the same issue on those registers. This problem does not cause the issue I'm facing but I think it'd like to report it so its fixed on an upcoming SDK release.

    Kind regards,

    Álvaro

  • Hi Aaron,

    I'm still stuck with the problem. Do you have any update? I'm still wondering why the PRU keeps the port closed although there is a physical link.

    Best regards,

    Álvaro

  • Sorry Alvaro for the delay.

    I tried the TI example on the EVM and I saw the same issue on those registers. This problem does not cause the issue I'm facing but I think it'd like to report it so its fixed on an upcoming SDK release.
    • We will recheck this from our side and confirm.
    I tried to understand the values but I'm not able to interpret the meaning clearly. I hope you can understand it better than me.
    • The values looks to be fine.
    I'm still wondering why the PRU keeps the port closed although there is a physical link.
    • We still suspect if the PHY pins are correctly muxed to the MII instance. Give me some time to understand this issue. I'll get back to you by Thursday EOD.

    Regards,
    Aaron

  • Hi Aaron,

    Thanks for your feedback. Sorry to bother you again but I tried a new approach.

    I tried to read the phy register values over MII interface. The ESC registers 0x510 to 0x515 are intended for MII management over EtherCAT and PDI interface.

    I tried to read on the AM243x-EVM Board the phy register values but it didn't work out. I did the following:

    • I wrote to the ESC register 0x512 the phy address I want to read (15).
    • I wrote to the ESC register 0x513 the phy register I want to read (1 - BMSR).
    • I try to read the ESC register 0x514 but the value is always 0.

    Do you know by any chance if these 0x510 MII Interface registers are correcly implemented and if so, how should I use instead?

    Kind regards,

    Álvaro

  • Hi Aaron,

    do you have any update on this matter?

    Best,

    Álvaro

  • Hi Alvaro,

    I don't have an update from my side for this as of now. 

    I tried to read on the AM243x-EVM Board the phy register values but it didn't work out. I did the following:
    • This looks to be MII-to-PHY muxing issue. 

    Please expect a reply by Thursday (as I'm out today and tomorrow is a holiday).

    Regards,
    Aaron

  • Hi Aaron,

    It has been a 3 weeks since the last post. We are still facing the same issues. Could we move this a bit forward?

    Thanks in advance,

    Álvaro

  • Hi Alvaro, 

    I compared the PHY registers with the working and non-working scenarios but didn't see any obvious changes between them. I couldn't spend more time here due to other priority tasks. I'll review the ESC registers and the API changes and update you.

    Regards,
    Aaron  

  • Hi Alvaro,

    The firmware looks for a good frame and based on that, the DL Status is updated based on the availability of good frame. Also, do you have a wireshark log for these scenarios, to verify if there is any errors in the EtherCAT communication in the network?

    Regards,
    Aaron

  • Following the previous message, can you provide the values observed in 0x0E00 and 0xE04 Registers?

    Regards,
    Aaron

  • Hi Aaron,

    The register values are 0 on both cases.

    We looked with Wireshark and we saw the 3 ECAT BWR frames from the master but not coming back with the WC incremented.

    Kind regards,

    Álvaro

  • Hi Alvaro,

    The register values are 0 on both cases.
    • Okay that confirms no valid frames in either of the ports.

    Do review the mux control registers in DP83869 and DP83867 and let us know of any change that can affect the communication.

    Regards,
    Aaron

  • We finally managed to find the issue, EtherCAT is working finally. The issue is that we were using the MDIO_phyRegWrite function to write to the 0x0172 phy register. The problem is that this function is intended to be used with the IEEE standard phy registers only. Using the function MDIO_phyExtRegWrite solved the issue.