/*! * \brief Configure the internal PHY. * * Reset the PHY and initiate auto-negotiation. */ int NicPhyConfig(void) { u_short phy_sor; u_short phy_sr; u_short phy_to; u_short mode; /* * Reset the PHY and wait until this self clearing bit * becomes zero. We sleep 63 ms before each poll and * give up after 3 retries. */ NicPhyWrite(NIC_PHYCR, PHYCR_RST); for (phy_to = 0;; phy_to++) { Delay(1); if ((NicPhyRead(NIC_PHYCR) & PHYCR_RST) == 0) break; if (phy_to > 3) { return -1; } } Delay(1); /* Store PHY status output. */ phy_sor = NicPhyRead(NIC_PHYSOR); /* Enable PHY interrupts. */ NicPhyWrite(NIC_PHYMSK, PHYMSK_MLOSSSYN | PHYMSK_MCWRD | PHYMSK_MSSD | PHYMSK_MESD | PHYMSK_MRPOL | PHYMSK_MJAB | PHYMSK_MSPDDT | PHYMSK_MDPLDT); /* Set RPC register. */ mode = RPCR_ANEG | RPCR_LEDA_PAT | RPCR_LEDB_PAT; nic_bs(0); nic_outw(NIC_RPCR, mode); /* * Advertise our capabilities, initiate auto negotiation * and wait until this has been completed. */ NicPhyWrite(NIC_PHYANAD, PHYANAD_TX_FDX | PHYANAD_TX_HDX | PHYANAD_10FDX | PHYANAD_10_HDX | PHYANAD_CSMA); for (phy_to = 0, phy_sr = 0;; phy_to++) { /* Give up after long time wait. */ if (phy_to >= 1024) { return -1; } /* Restart auto negotiation every 4 seconds or on failures. */ if ((phy_to & 127) == 0 /* || (phy_sr & PHYSR_REM_FLT) != 0 */ ) { NicPhyWrite(NIC_PHYCR, PHYCR_ANEG_EN | PHYCR_ANEG_RST); Delay(2); } /* Check if link status detected. */ phy_sr = NicPhyRead(NIC_PHYSR); if (phy_sr & PHYSR_ANEG_ACK) break; Delay(3); } return 0; }
/*! * \brief Configure the internal PHY. * * Reset the PHY and initiate auto-negotiation. */ static int NicPhyConfig(phantom_device_t * dev) { u_int16_t phy_sor; u_int16_t phy_sr; u_int16_t phy_to; u_int16_t mode; /* * Reset the PHY and wait until this self clearing bit * becomes zero. We sleep 63 ms before each poll and * give up after 3 retries. */ //printf("Reset PHY.."); NicPhyWrite(dev, NIC_PHYCR, PHYCR_RST); for (phy_to = 0;; phy_to++) { NutSleep(63); if ((NicPhyRead(dev, NIC_PHYCR) & PHYCR_RST) == 0) break; if (phy_to > 3) return -1; } //printf("OK\n"); /* Store PHY status output. */ phy_sor = NicPhyRead(dev, NIC_PHYSOR); /* Enable PHY interrupts. */ NicPhyWrite(dev, NIC_PHYMSK, PHYMSK_MLOSSSYN | PHYMSK_MCWRD | PHYMSK_MSSD | PHYMSK_MESD | PHYMSK_MRPOL | PHYMSK_MJAB | PHYMSK_MSPDDT | PHYMSK_MDPLDT); /* Set RPC register. */ mode = RPCR_ANEG | RPCR_LEDA_PAT | RPCR_LEDB_PAT; nic_bs(0); nic_outw(NIC_RPCR, mode); #ifdef NIC_FIXED /* Disable link. */ phy_sr = NicPhyRead(NIC_PHYCFR1); NicPhyWrite(NIC_PHYCFR1, phy_sr | 0x8000); NutSleep(63); /* Set fixed capabilities. */ NicPhyWrite(NIC_PHYCR, NIC_FIXED); nic_bs(0); nic_outw(NIC_RPCR, mode); /* Enable link. */ phy_sr = NicPhyRead(NIC_PHYCFR1); NicPhyWrite(NIC_PHYCFR1, phy_sr & ~0x8000); phy_sr = NicPhyRead(NIC_PHYCFR1); #else /* * Advertise our capabilities, initiate auto negotiation * and wait until this has been completed. */ //printf("Negotiate.."); NicPhyWrite(dev, NIC_PHYANAD, PHYANAD_TX_FDX | PHYANAD_TX_HDX | PHYANAD_10FDX | PHYANAD_10_HDX | PHYANAD_CSMA); NutSleep(63); for (phy_to = 0, phy_sr = 0;; phy_to++) { /* Give up after 10 seconds. */ if (phy_to >= 1024) return -1; /* Restart auto negotiation every 4 seconds or on failures. */ if ((phy_to & 127) == 0 /* || (phy_sr & PHYSR_REM_FLT) != 0 */ ) { NicPhyWrite(dev, NIC_PHYCR, PHYCR_ANEG_EN | PHYCR_ANEG_RST); //printf("Restart.."); NutSleep(63); } /* Check if we are done. */ phy_sr = NicPhyRead(dev, NIC_PHYSR); //printf("[SR %04X]", phy_sr); if (phy_sr & PHYSR_ANEG_ACK) break; NutSleep(63); } //printf("OK\n"); #endif return 0; }