2 * Code provided by Xilinx.
6 #include "xemaclite.h"
\r
9 #include "lwip/opt.h"
\r
12 /* Advertisement control register. */
\r
13 #define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
\r
14 #define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
\r
15 #define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
\r
16 #define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
\r
17 #define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_10HALF | ADVERTISE_100HALF)
\r
19 /* PHY registers/offsets. */
\r
20 #define IEEE_CONTROL_REG_OFFSET 0
\r
21 #define IEEE_STATUS_REG_OFFSET 1
\r
22 #define IEEE_AUTONEGO_ADVERTISE_REG 4
\r
23 #define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
\r
24 #define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
\r
25 #define IEEE_1000_ADVERTISE_REG_OFFSET 9
\r
26 #define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
\r
27 #define IEEE_CTRL_LINKSPEED_MASK 0x0040
\r
28 #define IEEE_CTRL_LINKSPEED_1000M 0x0040
\r
29 #define IEEE_CTRL_LINKSPEED_100M 0x2000
\r
30 #define IEEE_CTRL_LINKSPEED_10M 0x0000
\r
31 #define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
\r
32 #define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
\r
33 #define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
\r
34 #define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
\r
35 #define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
\r
36 #define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
\r
37 #define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
\r
38 #define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
\r
40 #define PHY_DETECT_REG 1
\r
41 #define PHY_DETECT_MASK 0x1808
\r
43 static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance);
\r
45 unsigned short vInitialisePHY( XEmacLite *pxEMACLiteInstance )
\r
49 u16 partner_capabilities;
\r
50 u16 partner_capabilities_1000;
\r
52 u32 phy_addr = detect_phy_emaclite(pxEMACLiteInstance);
\r
54 /* Dont advertise PHY speed of 1000 Mbps */
\r
55 XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
\r
56 IEEE_1000_ADVERTISE_REG_OFFSET,
\r
58 /* Advertise PHY speed of 100 and 10 Mbps */
\r
59 XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
\r
60 IEEE_AUTONEGO_ADVERTISE_REG,
\r
61 ADVERTISE_100_AND_10);
\r
63 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
64 IEEE_CONTROL_REG_OFFSET,
\r
66 control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
\r
67 IEEE_STAT_AUTONEGOTIATE_RESTART);
\r
69 XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
\r
70 IEEE_CONTROL_REG_OFFSET,
\r
73 /* Read PHY control and status registers is successful. */
\r
74 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
75 IEEE_CONTROL_REG_OFFSET,
\r
77 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
78 IEEE_STATUS_REG_OFFSET,
\r
81 if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) &&
\r
82 (status & IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
\r
84 while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
\r
85 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
86 IEEE_STATUS_REG_OFFSET,
\r
90 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
91 IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
\r
92 &partner_capabilities);
\r
94 if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
\r
95 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
\r
96 IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
\r
97 &partner_capabilities_1000);
\r
98 if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS) return 1000;
\r
101 if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS) return 100;
\r
102 if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS) return 10;
\r
104 xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
\r
111 /* Update TEMAC speed accordingly */
\r
112 if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
\r
114 /* Get commanded link speed */
\r
115 phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
\r
117 switch (phylinkspeed) {
\r
118 case (IEEE_CTRL_LINKSPEED_1000M):
\r
120 case (IEEE_CTRL_LINKSPEED_100M):
\r
122 case (IEEE_CTRL_LINKSPEED_10M):
\r
125 xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
\r
126 __FUNCTION__, phylinkspeed);
\r
132 return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
\r
140 static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance)
\r
145 for (phy_addr = 31; phy_addr > 0; phy_addr--) {
\r
146 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr, PHY_DETECT_REG, &phy_reg);
\r
148 if ((phy_reg != 0xFFFF) &&
\r
149 ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
\r
150 /* Found a valid PHY address */
\r
151 LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected at address %d.\r\n", phy_addr));
\r
152 LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected.\r\n"));
\r
157 LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: No PHY detected. Assuming a PHY at address 0\r\n"));
\r
159 /* default to zero */
\r