Hello,
I have a custom board highly inspired by the BeagleBone Black that has one Ethernet port. This port is connected to an external phy on CPU gmii2_xxx signals. There is no phy connected to the gmii1_xxxx port. Also, this phy is connected on the mdio bus with address 0.
I am trying to get this phy to register as a functional eth0 device in linux and I haven't found a way. I was able to make it work in u-boot 2015-04 by doing the following modifications:
In my board file board.c:
// Before
static struct cpsw_slave_data cpsw_slaves[] = {
{
.slave_reg_ofs = 0x208,
.sliver_reg_ofs = 0xd80,
.phy_addr = 0,
},
{
.slave_reg_ofs = 0x308,
.sliver_reg_ofs = 0xdc0,
.phy_addr = 1,
},
};
// After
static struct cpsw_slave_data cpsw_slaves[] = {
{
.slave_reg_ofs = 0x308,
.sliver_reg_ofs = 0xdc0,
.phy_addr = 0,
},
{
.slave_reg_ofs = 0x208,
.sliver_reg_ofs = 0xd80,
.phy_addr = 1,
},
};
In my mux.c file being compiled along my board file, I made sure the pin mux was set properly:
static struct module_pin_mux mii2_pin_mux[] = {
{OFFSET(gpmc_wpn), MODE(1) | RXACTIVE}, /* MII2_RXERR */
{OFFSET(gpmc_a0), MODE(1)}, /* MII2_TXEN */
{OFFSET(gpmc_a1), MODE(1) | RXACTIVE}, /* MII2_RXDV */
{OFFSET(gpmc_a2), MODE(1)}, /* MII2_TXD3 */
{OFFSET(gpmc_a3), MODE(1)}, /* MII2_TXD2 */
{OFFSET(gpmc_a4), MODE(1)}, /* MII2_TXD1 */
{OFFSET(gpmc_a5), MODE(1)}, /* MII2_TXD0 */
{OFFSET(gpmc_a6), MODE(1) | RXACTIVE}, /* MII2_TXCLK */
{OFFSET(gpmc_a7), MODE(1) | RXACTIVE}, /* MII2_RXCLK */
{OFFSET(gpmc_a8), MODE(1) | RXACTIVE}, /* MII2_RXD3 */
{OFFSET(gpmc_a9), MODE(1) | RXACTIVE}, /* MII2_RXD2 */
{OFFSET(gpmc_a10), MODE(1) | RXACTIVE}, /* MII2_RXD1 */
{OFFSET(gpmc_a11), MODE(1) | RXACTIVE}, /* MII2_RXD0 */
{OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
{OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
{-1},
};
void enable_board_pin_mux(void)
{
...
configure_module_pin_mux(mii2_pin_mux);
...
}
In the drivers/net/cpsw.c file, I changed:
// Before
static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
{
if (priv->host_port == 0)
return slave_num + 1;
else
return slave_num;
}
//After
static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
{
return 2;
}
This was enough to make the ethernet port fully functionnal in u-boot.
For Linux, I tried many different settings in the device tree with no results. Here is what I believe should work but doesn't:
mac: ethernet@4a100000 {
compatible = "ti,cpsw";
ti,hwmods = "cpgmac0";
clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
clock-names = "fck", "cpts";
cpdma_channels = <8>;
ale_entries = <1024>;
bd_ram_size = <0x2000>;
no_bd_ram = <0>;
rx_descs = <64>;
mac_control = <0x20>;
slaves = <2>;
active_slave = <1>; // <---------------------------- INSTEAD OF 0
cpts_clock_mult = <0x80000000>;
cpts_clock_shift = <29>;
reg = <0x4a100000 0x800
0x4a101200 0x100>;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
/*
* c0_rx_thresh_pend
* c0_rx_pend
* c0_tx_pend
* c0_misc_pend
*/
interrupts = <40 41 42 43>;
ranges;
syscon = <&cm>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&cpsw_default>;
pinctrl-1 = <&cpsw_sleep>;
status = "okay";
davinci_mdio: mdio@4a101000 {
compatible = "ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
bus_freq = <1000000>;
reg = <0x4a101000 0x100>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&davinci_mdio_default>;
pinctrl-1 = <&davinci_mdio_sleep>;
status = "okay";
};
cpsw_emac0: slave@4a100200 {
/* Filled in by U-Boot */
mac-address = [ 00 00 00 00 00 00 ];
phy_id = <&davinci_mdio>, <1>; // <------------------THIS PHY IS UNUSED, ADDRESS 1 IS DUMMY
phy-mode = "mii";
};
cpsw_emac1: slave@4a100300 {
/* Filled in by U-Boot */
mac-address = [ 00 00 00 00 00 00 ];
phy_id = <&davinci_mdio>, <0>; // <------------------emac1 phy address is 0
phy-mode = "mii";
};
phy_sel: cpsw-phy-sel@44e10650 {
compatible = "ti,am3352-cpsw-phy-sel";
reg= <0x44e10650 0x4>;
reg-names = "gmii-sel";
};
};
This registers eth0 in linux but it does not seem to use emac1:
[...]
[ 7.229462] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
[ 7.235843] davinci_mdio 4a101000.mdio: detected phy mask fffffffe
[ 7.247930] libphy: 4a101000.mdio: probed
[ 7.252251] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8710/LAN8720
[ 7.262763] cpsw 4a100000.ethernet: Detected MACID = d0:5f:b8:f5:f9:aa
[...]
[ 10.957585] net eth0: initializing cpsw version 1.12 (0)
[ 10.992743] net eth0: phy found : id is : 0x7c0f1
[ 10.997762] libphy: PHY 4a101000.mdio:01 not found
[ 11.002851] net eth0: phy 4a101000.mdio:01 not found on slave 1 // <----------------------------- Slave 1 was assigned ID 0, this doesn't make sense ?!
[ 11.067328] net eth0: BQL enabled
[...]
[ 14.070123] cpsw 4a100000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
# ifconfig
eth0 Link encap:Ethernet HWaddr d0:5f:b8:f5:f9:aa
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:684 (684.0 B)
Interrupt:167
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:160 errors:0 dropped:0 overruns:0 frame:0
TX packets:160 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:12960 (12.6 KiB) TX bytes:12960 (12.6 KiB)
How can I get a PHY connected to emac1 through gmii2_xxx signals and having an MDIO address of 0 to work on linux ? I am running Debian with kernel 3.18.
Any help appreciated, thanks,
Guillaume