
i've just been handed an issue regarding a modified version of u-boot v2015.07 and an unreliable designware MAC i'm hoping someone can give me some guidance on while i continue to dig through the code and continue testing.
ARM-based target board has, among other things, an ethernet debug port that is used for downloading and flashing firmware images while in u-boot. problem is that, after coming up in u-boot, the debug port is totally inoperative anywhere from 1/3 to 1/2 of the time (reportedly no packet traffic at all). if one resets a few times, eventually the port is operational. there is no apparent pattern, and no predictable number of retries until the port works.
for the testers, i configured u-boot to include the mdio command to let them poke around, then went to the DW data sheet, where i found the following in the GMAC register map:
reg 48: 0x00C0 AN Control Register reg 49: 0x00C4 AN Status Register
further down in the data sheet, a couple useful bits from the status register:
5 ANC Auto-Negotiation Complete 2 LS Link Status
one of the testers, armed with this information and an ability to poke around the registers, *assures* me that there is a direct correlation between the debug port working, and those two bits from the status register both being set to one. both one -- working. both zero -- dead. given my assumption that those two bits simply display the current situation (you can't just set them), this suggests that *something* related to the dwmac is not being initialized properly when u-boot comes up.
i can also see register:
reg 54: 0x00D8 SGMII/RGMII/SMII Control and Status Register
but have yet to dig into that; that's today's project.
there is, AFAICT, a single line change to the v2015.07 designware.c file for this target board, down around line 267 (clearly modifying settings in the AN control register):
... snip ... #ifdef CONFIG_DW_AXI_BURST_LEN writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus); #endif
* Enable Auto-Negotiation and External loopback (same way as * linux driver does it) to get this driver to work. */
====> writel(readl((u32)mac_p + 0xc0) | (1<<12) | (1<<14), (u32)mac_p + 0xc0);
/* Start up the PHY */ ret = phy_startup(priv->phydev); ... snip ...
the line marked "====>" is the line added to the source file. from the data sheet, the two bits being set in the AN control register are:
14 ELE loopback enable 12 ANE auto-negotiation enable
despite the comment that that line is necessary to get the driver to work, it is still unreliable as i've already described.
finally, the configuration for this board does *not* include CONFIG_RESET_PHY_R, so there is no invocation of a board-specific reset_phy() routine in common/board_r.c:
#ifdef CONFIG_CMD_NET static int initr_net(void) { puts("Net: "); eth_initialize(); #if defined(CONFIG_RESET_PHY_R) <=== NOT configured debug("Reset Ethernet PHY\n"); reset_phy(); #endif return 0; } #endif
which makes me wonder if there *should* be a reset_phy() routine defined for this board (whatever it might need to do).
bottom line: has anyone else had this sort of maddeningly unreliable behaviour with a designware MAC? have there been any bug fixes since v2015.07 that might be applicable here? (i'm about to dig into the git log to see what's happened since then.) does that single line change to designware.c to set ELE and ANE in the AN control register look familiar to anyone, as in, has anyone else needed to do something similar?
totally open to advice here.
rday