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.

DP83825I: PHY detects link, but kernel says eth0: link is not ready

Part Number: DP83825I

Hello Everyone,

We are using DP83825I to interface with our custom imx7 boards.  Here is my device tree

&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;

clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_50M_CLK>;
clock-names = "ipg", "ahb", "ptp", "enet_clk_ref";
assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
assigned-clock-rates = <0>, <100000000>;
phy-mode = "rmii";
phy-handle = <&ethphy0>;
phy-supply = <&enet3v3>; /*Ethernet power enable*/
/delete-property/ fsl,magic-packet;
phy-reset-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>;
phy-reset-duration = <2>;
phy-reset-post-delay = <50>;
pinctrl-assert-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
status = "okay";

mdio {
#address-cells = <1>;
#size-cells = <0>;

ethphy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
device-type = "ethernet-phy";
};
};
};

pinctrl_enet1: enet1grp {
fsl,pins = <
MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 (MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 (MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL (MX7D_PAD_CTL_DSE_X2)

MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 (MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 (MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_ENET1_RGMII_RXC__ENET1_RX_ER (MX7D_PAD_CTL_DSE_X2)

MX7D_PAD_ENET1_TX_CLK__CCM_ENET_REF_CLK1 (MX7D_PAD_SION | MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_EPDC_BDR0__CCM_ENET_REF_CLK2 (MX7D_PAD_SION | MX7D_PAD_CTL_DSE_X2)

MX7D_PAD_SD2_WP__ENET1_MDC (MX7D_PAD_CTL_DSE_X2)
MX7D_PAD_SD2_CD_B__ENET1_MDIO (MX7D_PAD_CTL_DSE_X2)

MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL (MX7D_PAD_CTL_DSE_X2)

MX7D_PAD_LCD_DATA21__GPIO3_IO26 (MX7D_PAD_CTL_PUS_100K_DOWN | MX7D_PAD_CTL_PUE | MX7D_PAD_CTL_SRE_SLOW | MX7D_PAD_CTL_DSE_X1) /* n_ENET_RST */
MX7D_PAD_LCD_DATA19__GPIO3_IO24 (MX7D_PAD_CTL_PUS_100K_DOWN | MX7D_PAD_CTL_PUE | MX7D_PAD_CTL_SRE_SLOW | MX7D_PAD_CTL_DSE_X1) /* n_ENET_PWDN */
>;
};

PHY is detected as DP8382S.  I read register 0x01 BMSR it gives value 0x786D, i.e link detected. However, kernel shows eth0 link is not ready. ethtool says link not detected.

Clk lines is active

Activity on RD1 and CRS_DV

All the transmit signals from the iMX7, however, are quiet. No activity at all. 

What can possibly be the problem? Any help is appreciated.

Thanks,

Asma

  • Hi Asma,

    I will direct your post to the drivers and software team. The DP83825I appears to be functioning properly and they can provide insight to the software you provided.

    Regards,
    Justin 

  • That would be great. I am really looking forward to it

  • Hi ,

    Any update on this? 

    Any kind of help is really appreciated.

  • Hello

    The BMSR status is read in the genphy_update_link in the phy core this function is polled and is a generic Linux function.

    https://elixir.bootlin.com/linux/latest/source/drivers/net/phy/phy_device.c#L2149

    The 825 driver only manages the interrupts and WoL.  The 825 driver does not report the link status that is the PHY cores responsibility.

    If the device is reporting the 0x786d in the BMSR I would want you to put some debug statements in the genphy_update_link function to figure out what the core is reading.

    Dan

  • Hi Asma,

    Can you provide the kernel revision you are using and the kernel log while the PHY is initialized and link is established?

    Regards,
    Justin 

  • Hi Justin and Dan,

    Thank you so much for your response. I am using kernel revision 4.19.35. I have updated driver using DP83825 patch.

    I am sorry earlier I said the link is detected. I was wrong but it was for some other thing.  I am not able to detect any link, 

    Here is the output of all PHY registers I read through phytool.

    root@qt850:~# phytool read eth0/0/0x00
    
    0x3100
    
    root@qt850:~# phytool read eth0/0/0x01
    
    0x7849
    
    Link is not detected
    
    root@qt850:~# phytool read eth0/0/0x02
    
    0x2000
    
    root@qt850:~# phytool read eth0/0/0x03
    
    0xa140
    
    root@qt850:~# phytool read eth0/0/0x04
    
    0x0401
    
    root@qt850:~# phytool read eth0/0/0x05
    
    0xc1e1
    
    root@qt850:~# phytool read eth0/0/0x06
    
    0x000f
    
    root@qt850:~# phytool read eth0/0/0x07
    
    0x2001
    
    root@qt850:~# phytool read eth0/0/0x08
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x09
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x0a
    
    0x0100
    
    root@qt850:~# phytool read eth0/0/0x0b
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x0c
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x0d
    
    0x401f
    
    root@qt850:~# phytool read eth0/0/0x0e
    
    0x1081
    
    root@qt850:~# phytool read eth0/0/0x0f
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x10
    
    0x1002
    
    Link is not established, auto neg is not completed, Half duplex mode
    
     
    
    root@qt850:~# phytool read eth0/0/0x11
    
    0x0108
    
    root@qt850:~# phytool read eth0/0/0x12
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x13
    
    0x6800
    
    root@qt850:~# phytool read eth0/0/0x14
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x15
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x16
    
    0x0100
    
    root@qt850:~# phytool read eth0/0/0x17
    
    0x0060
    
    root@qt850:~# phytool read eth0/0/0x18
    
    0x0480
    
    root@qt850:~# phytool read eth0/0/0x19
    
    0x8000
    
     
    
    root@qt850:~# phytool read eth0/0/0x1a
    
    0x0010
    
    root@qt850:~# phytool read eth0/0/0x1b
    
    0x007d
    
    root@qt850:~# phytool read eth0/0/0x1c
    
    0x05ee
    
    root@qt850:~# phytool read eth0/0/0x1d
    
    0000
    
    root@qt850:~# phytool read eth0/0/0x1e
    
    0x0102
    
    root@qt850:~# phytool read eth0/0/0x1f
    
    0000

    Dan Murphy (1554927) I checked the register you asked in genphy update link. Its not detecting any link. And here is the driver code, I have modified it a bit to set it in master mode 

    /*
     * Driver for the Texas Instruments DP83822 PHY
     *
     * Copyright (C) 2017 Texas Instruments Inc.
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     */
    
    #include <linux/ethtool.h>
    #include <linux/etherdevice.h>
    #include <linux/kernel.h>
    #include <linux/mii.h>
    #include <linux/module.h>
    #include <linux/of.h>
    #include <linux/phy.h>
    #include <linux/netdevice.h>
    
    #define DP83822_PHY_ID	        0x2000a240
    #define DP83825S_PHY_ID		0x2000a140
    #define DP83825I_PHY_ID		0x2000a150
    #define DP83825CM_PHY_ID	0x2000a160
    #define DP83825CS_PHY_ID	0x2000a170
    #define DP83826C_PHY_ID		0x2000a130
    #define DP83826NC_PHY_ID	0x2000a110
    #define DP83822_DEVADDR		0x1f
    
    #define MII_DP83822_PHYSCR	0x11
    #define MII_DP83822_MISR1	0x12
    #define MII_DP83822_MISR2	0x13
    #define MII_DP83822_RCSR	0x17
    #define MII_DP83822_RESET_CTRL	0x1f
    
    #define DP83822_HW_RESET	BIT(15)
    #define DP83822_SW_RESET	BIT(14)
    
    /* PHYSCR Register Fields */
    #define DP83822_PHYSCR_INT_OE		BIT(0) /* Interrupt Output Enable */
    #define DP83822_PHYSCR_INTEN		BIT(1) /* Interrupt Enable */
    
    /* MISR1 bits */
    #define DP83822_RX_ERR_HF_INT_EN	BIT(0)
    #define DP83822_FALSE_CARRIER_HF_INT_EN	BIT(1)
    #define DP83822_ANEG_COMPLETE_INT_EN	BIT(2)
    #define DP83822_DUP_MODE_CHANGE_INT_EN	BIT(3)
    #define DP83822_SPEED_CHANGED_INT_EN	BIT(4)
    #define DP83822_LINK_STAT_INT_EN	BIT(5)
    #define DP83822_ENERGY_DET_INT_EN	BIT(6)
    #define DP83822_LINK_QUAL_INT_EN	BIT(7)
    
    /* MISR2 bits */
    #define DP83822_JABBER_DET_INT_EN	BIT(0)
    #define DP83822_WOL_PKT_INT_EN		BIT(1)
    #define DP83822_SLEEP_MODE_INT_EN	BIT(2)
    #define DP83822_MDI_XOVER_INT_EN	BIT(3)
    #define DP83822_LB_FIFO_INT_EN		BIT(4)
    #define DP83822_PAGE_RX_INT_EN		BIT(5)
    #define DP83822_ANEG_ERR_INT_EN		BIT(6)
    #define DP83822_EEE_ERROR_CHANGE_INT_EN	BIT(7)
    
    /* INT_STAT1 bits */
    #define DP83822_WOL_INT_EN	BIT(4)
    #define DP83822_WOL_INT_STAT	BIT(12)
    
    #define MII_DP83822_RXSOP1	0x04a5
    #define	MII_DP83822_RXSOP2	0x04a6
    #define	MII_DP83822_RXSOP3	0x04a7
    
    /* WoL Registers */
    #define	MII_DP83822_WOL_CFG	0x04a0
    #define	MII_DP83822_WOL_STAT	0x04a1
    #define	MII_DP83822_WOL_DA1	0x04a2
    #define	MII_DP83822_WOL_DA2	0x04a3
    #define	MII_DP83822_WOL_DA3	0x04a4
    
    /* WoL bits */
    #define DP83822_WOL_MAGIC_EN	BIT(0)
    #define DP83822_WOL_SECURE_ON	BIT(5)
    #define DP83822_WOL_EN		BIT(7)
    #define DP83822_WOL_INDICATION_SEL BIT(8)
    #define DP83822_WOL_CLR_INDICATION BIT(11)
    #define DP83822_WOL_GPIO 0x302
    
    /* RCSR Register bits */
    #define DP83825_SOR1_ADDR        (0x0467)
    #define DP83822_RCSR_CLOCK_SELECT	BIT(7)
    
    /* Additions for GPIO3 control */
    #define DP83822_IOCTRL1_ADDR        (0x0462)
    #define DP83822_IOCTRL1_GPIO3_CLOCK (BIT(9) | BIT(8))
    #define DP83822_IOCTRL1_GPIO3_MASK  (BIT(10) | BIT(9) | BIT(8))
    #define DP83822_IOCTRL1_CLK_SRC_MASTER      (BIT(14))
    #define DP83822_IOCTRL1_CLK_SRC_MASK        (BIT(14) | BIT(13) | BIT(12))
    #define DP83822_DEV_ADDR            (0x1F)
    
    static int dp83822_ack_interrupt(struct phy_device *phydev)
    {
    	int err;
    
    	err = phy_read(phydev, MII_DP83822_MISR1);
    	if (err < 0)
    		return err;
    
    	err = phy_read(phydev, MII_DP83822_MISR2);
    	if (err < 0)
    		return err;
    
    	return 0;
    }
    
    static int dp83822_set_wol(struct phy_device *phydev,
    			   struct ethtool_wolinfo *wol)
    {
    	struct net_device *ndev = phydev->attached_dev;
    	u16 value;
    	const u8 *mac;
    
    	if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
    		mac = (const u8 *)ndev->dev_addr;
    
    		if (!is_valid_ether_addr(mac))
    			return -EINVAL;
    
    		/* MAC addresses start with byte 5, but stored in mac[0].
    		 * 822 PHYs store bytes 4|5, 2|3, 0|1
    		 */
    		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
    			      (mac[1] << 8) | mac[0]);
    		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
    			      (mac[3] << 8) | mac[2]);
    		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
    			      (mac[5] << 8) | mac[4]);
    
    		value = phy_read_mmd(phydev, DP83822_DEVADDR,
    				     MII_DP83822_WOL_CFG);
    		if (wol->wolopts & WAKE_MAGIC)
    			value |= DP83822_WOL_MAGIC_EN;
    		else
    			value &= ~DP83822_WOL_MAGIC_EN;
    
    		if (wol->wolopts & WAKE_MAGICSECURE) {
    			phy_write_mmd(phydev, DP83822_DEVADDR,
    				      MII_DP83822_RXSOP1,
    				      (wol->sopass[1] << 8) | wol->sopass[0]);
    			phy_write_mmd(phydev, DP83822_DEVADDR,
    				      MII_DP83822_RXSOP2,
    				      (wol->sopass[3] << 8) | wol->sopass[2]);
    			phy_write_mmd(phydev, DP83822_DEVADDR,
    				      MII_DP83822_RXSOP3,
    				      (wol->sopass[5] << 8) | wol->sopass[4]);
    			value |= DP83822_WOL_SECURE_ON;
    		} else {
    			value &= ~DP83822_WOL_SECURE_ON;
    		}
    
    		value |= (DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
    			  DP83822_WOL_CLR_INDICATION);
    		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
    			      value);
    	} else {
    		value = phy_read_mmd(phydev, DP83822_DEVADDR,
    				     MII_DP83822_WOL_CFG);
    		value &= ~DP83822_WOL_EN;
    		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
    			      value);
    	}
    
    	return 0;
    }
    
    static void dp83822_get_wol(struct phy_device *phydev,
    			    struct ethtool_wolinfo *wol)
    {
    	int value;
    	u16 sopass_val;
    
    	wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
    	wol->wolopts = 0;
    
    	value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
    
    	if (value & DP83822_WOL_MAGIC_EN)
    		wol->wolopts |= WAKE_MAGIC;
    
    	if (value & DP83822_WOL_SECURE_ON) {
    		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
    					  MII_DP83822_RXSOP1);
    		wol->sopass[0] = (sopass_val & 0xff);
    		wol->sopass[1] = (sopass_val >> 8);
    
    		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
    					  MII_DP83822_RXSOP2);
    		wol->sopass[2] = (sopass_val & 0xff);
    		wol->sopass[3] = (sopass_val >> 8);
    
    		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
    					  MII_DP83822_RXSOP3);
    		wol->sopass[4] = (sopass_val & 0xff);
    		wol->sopass[5] = (sopass_val >> 8);
    
    		wol->wolopts |= WAKE_MAGICSECURE;
    	}
    
    	/* WoL is not enabled so set wolopts to 0 */
    	if (!(value & DP83822_WOL_EN))
    		wol->wolopts = 0;
    }
    
    static int dp83822_config_intr(struct phy_device *phydev)
    {
    	int misr_status;
    	int physcr_status;
    	int err;
    
    	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
    		misr_status = phy_read(phydev, MII_DP83822_MISR1);
    		if (misr_status < 0)
    			return misr_status;
    
    		misr_status |= (DP83822_RX_ERR_HF_INT_EN |
    				DP83822_FALSE_CARRIER_HF_INT_EN |
    				DP83822_ANEG_COMPLETE_INT_EN |
    				DP83822_DUP_MODE_CHANGE_INT_EN |
    				DP83822_SPEED_CHANGED_INT_EN |
    				DP83822_LINK_STAT_INT_EN |
    				DP83822_ENERGY_DET_INT_EN |
    				DP83822_LINK_QUAL_INT_EN);
    
    		err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
    		if (err < 0)
    			return err;
    
    		misr_status = phy_read(phydev, MII_DP83822_MISR2);
    		if (misr_status < 0)
    			return misr_status;
    
    		misr_status |= (DP83822_JABBER_DET_INT_EN |
    				DP83822_WOL_PKT_INT_EN |
    				DP83822_SLEEP_MODE_INT_EN |
    				DP83822_MDI_XOVER_INT_EN |
    				DP83822_LB_FIFO_INT_EN |
    				DP83822_PAGE_RX_INT_EN |
    				DP83822_ANEG_ERR_INT_EN |
    				DP83822_EEE_ERROR_CHANGE_INT_EN);
    
    		err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
    		if (err < 0)
    			return err;
    
    		physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
    		if (physcr_status < 0)
    			return physcr_status;
    
    		physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
    
    	} else {
    		err = phy_write(phydev, MII_DP83822_MISR1, 0);
    		if (err < 0)
    			return err;
    
    		err = phy_write(phydev, MII_DP83822_MISR1, 0);
    		if (err < 0)
    			return err;
    
    		physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
    		if (physcr_status < 0)
    			return physcr_status;
    
    		physcr_status &= ~DP83822_PHYSCR_INTEN;
    	}
    
    	return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
    }
    
    static int dp83822_config_init(struct phy_device *phydev)
    {
    	int err;
    	int value;
    
    	err = genphy_config_init(phydev);
    	if (err < 0)
    		return err;
    
        value = phy_read(phydev, MII_DP83822_RCSR);
    
        value &= ~(DP83822_RCSR_CLOCK_SELECT);
        phy_write(phydev, MII_DP83822_RCSR, value);
    
        value = phy_read_mmd(phydev, DP83822_DEV_ADDR, DP83825_SOR1_ADDR);
    
        value &= ~(BIT(3));
    	err = phy_write_mmd(phydev, DP83822_DEV_ADDR, DP83825_SOR1_ADDR, value );
    value = phy_read_mmd(phydev, DP83822_DEV_ADDR, DP83825_SOR1_ADDR); pr_warn("SOR1 = %d", value); //Disable WOL so we can go to sleep value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); value = DP83822_WOL_MAGIC_EN | DP83822_WOL_SECURE_ON | DP83822_WOL_EN; return phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value); } static int dp83822_phy_reset(struct phy_device *phydev) { int err; err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET); if (err < 0) return err; while(DP83822_SW_RESET & phy_read(phydev, MII_DP83822_RESET_CTRL)); dp83822_config_init(phydev); return 0; } static int dp83822_suspend(struct phy_device *phydev) { int value; value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); if (!(value & DP83822_WOL_EN)) genphy_suspend(phydev); return 0; } static int dp83822_resume(struct phy_device *phydev) { int value; genphy_resume(phydev); value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value | DP83822_WOL_CLR_INDICATION); return 0; } #define DP83822_PHY_DRIVER(_id, _name) \ { \ PHY_ID_MATCH_MODEL(_id), \ .phy_id_mask = 0xfffffff0, \ .name = (_name), \ .features = PHY_BASIC_FEATURES, \ /* PHY_BASIC_FEATURES */ \ .soft_reset = dp83822_phy_reset, \ .config_init = dp83822_config_init, \ .get_wol = dp83822_get_wol, \ .set_wol = dp83822_set_wol, \ .ack_interrupt = dp83822_ack_interrupt, \ .config_intr = dp83822_config_intr, \ .suspend = dp83822_suspend, \ .resume = dp83822_resume, \ } static struct phy_driver dp83822_driver[] = { DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"), DP83822_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"), DP83822_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"), DP83822_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"), DP83822_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"), DP83822_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"), DP83822_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"), }; module_phy_driver(dp83822_driver); static struct mdio_device_id __maybe_unused dp83822_tbl[] = { { DP83822_PHY_ID, 0xfffffff0 }, { DP83825I_PHY_ID, 0xfffffff0 }, { DP83826C_PHY_ID, 0xfffffff0 }, { DP83826NC_PHY_ID, 0xfffffff0 }, { DP83825S_PHY_ID, 0xfffffff0 }, { DP83825CM_PHY_ID, 0xfffffff0 }, { DP83825CS_PHY_ID, 0xfffffff0 }, { }, }; MODULE_DEVICE_TABLE(mdio, dp83822_tbl); MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver"); MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com"); MODULE_LICENSE("GPL v2");

    Could you please have a look if I am doing anything wrong? Any help is really appreciated

  • Hello

    OK I reviewed the code.

    First you cannot write to the SOR1 register it is read only

        err = phy_write_mmd(phydev, DP83822_DEV_ADDR, DP83825_SOR1_ADDR, value );

    Next the code says to disable WoL but the code snippet is enabling WoL

    //Disable WOL so we can go to sleep

    value = DP83822_WOL_MAGIC_EN | DP83822_WOL_SECURE_ON | DP83822_WOL_EN; // This sets all the bits to 1

    And I am not sure this code below is doing anything as the default for BIT(7) is 0 and that appears to be what you are setting

    value = phy_read(phydev, MII_DP83822_RCSR);

    What is the value of SOR1 and SOR2?

    Dan

    value &= ~(DP83822_RCSR_CLOCK_SELECT);

    phy_write(phydev, MII_DP83822_RCSR, value);

    Maybe you should take a look at the current upstreamed driver.  It properly disables WoL

    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/phy/dp83822.c

  • Hi Dan,

    In DP83825I datasheet, For SOR1  register it does not mention it is read only, from what I understand I can configure bit 3 and bit 0 as no R type mentioned. Same goes for SOR2.




    I have updated my driver to the same link, but no output changes.
    Value of SOR1 and SOR2 I am getting is as follows:
    SOR1 = 0x533
    SOR2 = 0x1290

    BMSR = 0x7849

    BMCR = 0x3100,

    Which gives auto-negotiation not completed. 

    Could you tell me, how to set in a master mode without using bootstrap?

    Also, in device tree, what should be the pin configurations for the following pins, Pull up/Pull down?

    RX_D0, RX_D1,TX_D0,TX_D1 and  CRS_DV.

    Thanks,

    Asma

  • Hi Asma,

    You cannot write to registers SOR1 or SOR2, they should be treated as read only. These registers are providing information about what bootstrap configurations are being latched at powerup and reset. 

    The DP83825I device is strapped into RMII Master mode from register 0x0467[3]=0.

    Can you give a description of which modes of operation you are targeting and I can provide the bootstrap configuration or register writes to achieve that?

    Regards,
    Justin 

  • Hi Justin,

    I am targetting for RMII Master mode.

    Thanks,

    Asma

  • Hi Asma,

    Can you confirm the device is configured in that mode through register 0x0017[7]=0?

    Regards,
    Justin 

  • Hi Justin,

    I am getting the value of 0x0017 as 0x60, so yes the 7th bit is 0.

    Does that mean my settings are right?

    I am still not getting the link, Will it be helpful if I share schematics or the register values of all registers from 0x00 to 0x1F?

    Regards,

    Asma

  • Hi Asma,

    Yes that would be helpful. Can you clarify under what conditions you are able to detect link and when you are not? My initial understanding was that the PHY could link but was not detected by the software, has that changed?

    Regards,
    Justin 

  • Hi Asma,

    I am closing this thread since I have not heard a response. If you need assistance, please create a new post and reference this thread.

    Regards,
    Justin