+ uint16_t reg;
+ time_t start;
+
+ // Wait for auto-negotation to complete
+ start = timer_clock();
+ do {
+ reg = phy_hw_read(NIC_PHY_ADDR, NIC_PHY_BMSR);
+ if (timer_clock() - start > 2000)
+ {
+ kprintf("eth error: auto-negotiation timeout\n");
+ return;
+ }
+ }
+ while (!(reg & NIC_PHY_BMSR_ANCOMPL));
+
+ reg = phy_hw_read(NIC_PHY_ADDR, NIC_PHY_ANLPAR);
+
+ if ((reg & NIC_PHY_ANLPAR_TX_FDX) || (reg & NIC_PHY_ANLPAR_TX_HDX))
+ {
+ LOG_INFO("eth: 100BASE-TX\n");
+ EMAC_NCFGR |= BV(EMAC_SPD);
+ }
+ else
+ {
+ LOG_INFO("eth: 10BASE-T\n");
+ EMAC_NCFGR &= ~BV(EMAC_SPD);
+ }
+
+ if ((reg & NIC_PHY_ANLPAR_TX_FDX) || (reg & NIC_PHY_ANLPAR_10_FDX))
+ {
+ LOG_INFO("eth: full duplex\n");
+ EMAC_NCFGR |= BV(EMAC_FD);
+ }
+ else
+ {
+ LOG_INFO("eth: half duplex\n");
+ EMAC_NCFGR &= ~BV(EMAC_FD);
+ }
+}