
Hi,
I'm developing a custom board based on the AT91RM9200dk. In u-boot prompt, every time a enter a network command such as tftp or ping I get a message like this:
"MAC: error during MII initialization"
Although the command actually seems to work I was a little concerned. After taking a look at cpu/arm920t/at91rm9200/ether.c and cpu/arm920t/at91rm9200/dm9161.c I realized the problem was at the function UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac) in dm9161.c. Apparently, the link status bit at BMSR register is indicating link down even when it's not.
I googled for it and found at http://www.davicom.com.tw/page1.aspx?no=149749 a FAQ for dm9000A-8 related to a similar register as follows:
"(...) Q1: There are two methods for checking Link status as below: 1) NSR: 01H bit 6 2) PHY BMSR: 01 bit 2 Could you explain what difference is between 1) and 2)? A1: 1) NSR: 01H bit: PHY link status now 2) PHY BMSR: 01 bit 2: the register will read two times. You can see below table for the meaning
Read first times Read second time meaning 0 0 Link fail 0 1 Link fail before and link ok now 1 0 No any meaning 1 1 Link ok (...)"
So I tried reading the BMSR register twice and it got the job done. Did anybody notice this issue ?
--- a/cpu/arm920t/at91rm9200/dm9161.c 2008-08-12 11:08:38.000000000 -0300 +++ b/cpu/arm920t/at91rm9200/dm9161.c 2008-09-02 16:26:05.000000000 -0300 @@ -70,13 +70,16 @@ */ UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac) { - unsigned short stat1, stat2; - - if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1)) - return FALSE; + unsigned short stat1, stat2, i; + + for (i = 2; i; --i) + if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1)) + return FALSE;
- if (!(stat1 & DM9161_LINK_STATUS)) /* link status up? */ + if (!(stat1 & DM9161_LINK_STATUS)) { /* link status up? */ + printf("Link down\n"); return FALSE; + }
if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2)) return FALSE;
--
Regards
NĂcolas