Hi All,
we are using lan8740 (two of them) in dual emac mode(RMII) for a custom board using AM3352 (based on am335x-evmsk). These lan8740 phys are connected to LAN9500 usb-ethernet phys on the custom board. After configuring the dts file we find the device getting registered from the below logs, But the ethernet link shows it is down. The LAN9500 is connected to PC on the USB side.
--LAN8740--LAN9500--PC
AM3352->|
--LAN8740--LAN9500--PC
libphy: Fixed MDIO Bus: probed
[ 1.227588] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
[ 1.233735] davinci_mdio 4a101000.mdio: detected phy mask ffffffbe
[ 1.241397] libphy: 4a101000.mdio: probed
[ 1.245440] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8740--------->
[ 1.254018] davinci_mdio 4a101000.mdio: phy[6]: device 4a101000.mdio:06, driver SMSC LAN8740--------->
[ 1.263367] cpsw 4a100000.ethernet: Detected MACID = 68:9e:19:87:e8:ad
[ 1.271077] cpsw 4a100000.ethernet: cpsw: Detected MACID = 68:9e:19:87:e8:af
net eth1: initializing cpsw version 1.12 (0)
net eth0: initialized cpsw ale version 1.4
net eth1: phy found : id is : 0x7c111
IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
net eth0: initializing cpsw version 1.12 (0)
net eth0: phy found : id is : 0x7c111
IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
It seems that the auto negotiation is failing. But the root cause for this is not clear
As per the data sheet of LAN8740 it says a hardware reset is required. "A hardware reset (nRST assertion) is required following power-up." But we dont find any code/patch for linux kernel implementing such a hardware reset.
There is a provision in dt file to set the "reset-gpios" and "reset-delay-us" in the MDIO Controller Device Tree Bindings
- reset-gpios : array of GPIO specifier for PHY hardware reset control
- reset-delay-us : reset assertion time [in microseconds]
We are exploring the possibility of using the above dt options to implement hardware reset. But we have our doubts since we did not find any such implementation for lan8740. The custom board has a onboard switch to hardware reset the lan8740. We tried hardware reset after uboot and before kernel boot using the switch but still the auto negotiation failed for lan8740.
Our questions are
1) Is hardware reset after power-on mandatory for lan8740?
If yes what is the best method to deliver this hardware reset (through above mentioned dt configurations) ?
2) Is there any method to test the lan8740 (Ex: HW loopback, etc).
Below we have the Device Tree (am335x-evmsk.dts) with all configuration of Ethernet PHY (Kindly suggest if any changes needs to be done)
cpsw_default: cpsw_default {
pinctrl-single,pins = <
/* Slave 1 */
0x144 ( PIN_INPUT_PULLDOWN | MUX_MODE0 ) /* (H18) rmii1_refclk.rmii1_refclk */
0x10c ( PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* (H17) mii1_crs.rmii1_crs_dv */
0x110 ( PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* (J15) mii1_rxer.rmii1_rxer */
0x114 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (J16) mii1_txen.rmii1_txen */
0x128 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (K17) mii1_txd0.rmii1_txd0 */
0x124 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (K16) mii1_txd1.rmii1_txd1 */
0x140 ( PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* (M16) mii1_rxd0.rmii1_rxd0 */
0x13c ( PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* (L15) mii1_rxd1.rmii1_rxd1 */
0x98 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) /* (U6) gpmc_wen.gpio2_4 fs-lan8740int */
/*Slave 2*/
0x70 ( PIN_INPUT_PULLDOWN | MUX_MODE3 ) /* (T17) gpmc_wait0.rmii2_crs_dv */
0x74 ( PIN_INPUT_PULLDOWN | MUX_MODE3 ) /* (U17) gpmc_wpn.rmii2_rxer */
0x40 ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (R13) gpmc_a0.rmii2_txen */
0x54 ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (V15) gpmc_a5.rmii2_txd0 */
0x50 ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (R14) gpmc_a4.rmii2_txd1 */
0x6c ( PIN_INPUT_PULLDOWN | MUX_MODE3 ) /* (V17) gpmc_a11.rmii2_rxd0 */
0x68 ( PIN_INPUT_PULLDOWN | MUX_MODE3 ) /* (T16) gpmc_a10.rmii2_rxd1 */
0x108 ( PIN_INPUT_PULLDOWN| MUX_MODE1 ) /* (H16) gmii1_col.rmii2_refclk */
0x14 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) /* (V8) gpmc_ad5.gpio1_5 fs-lan8740 int*/
>;
};
cpsw_sleep: cpsw_sleep {
pinctrl-single,pins = <
/* Slave 1 reset value */
0x98 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_int */
0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_crs_dv */
0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rxer */
0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_txen */
0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td1 */
0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_td0 */
0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd1 */
0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_rd0 */
0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii1_refclk */
/* Slave 2 reset value*/
0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_txen */
0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td1 */
0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_td0 */
0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd1 */
0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rd0 */
0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_crs_dv */
0x74 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_rxer */
0x14 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_int */
0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* rmii2_refclk */
>;
};
davinci_mdio_default: davinci_mdio_default {
pinctrl-single,pins = <
/* MDIO */
0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
>;
};
davinci_mdio_sleep: davinci_mdio_sleep {
pinctrl-single,pins = <
/* MDIO reset value */
0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
>;
};
&mac {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&cpsw_default>;
pinctrl-1 = <&cpsw_sleep>;
dual_emac = <1>;
status = "okay";
};
&davinci_mdio {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&davinci_mdio_default>;
pinctrl-1 = <&davinci_mdio_sleep>;
status = "okay";
};
&cpsw_emac0 {
phy_id = <&davinci_mdio>, <0>;
phy-mode = "rmii";
dual_emac_res_vlan = <2>;
};
&cpsw_emac1 {
phy_id = <&davinci_mdio>, <6>;
phy-mode = "rmii";
dual_emac_res_vlan = <3>;
};
&phy_sel {
rmii-clock-ext;