]> git.sur5r.net Git - freertos/blob - Demo/Common/ethernet/lwip-1.4.0/ports/MicroBlaze-Ethernet-Lite/SP605_PHY.c
Start to re-arrange files to include FreeRTOS+ in main download.
[freertos] / Demo / Common / ethernet / lwip-1.4.0 / ports / MicroBlaze-Ethernet-Lite / SP605_PHY.c
1 /*\r
2  * Code provided by Xilinx.
3  */\r
4 \r
5 /* BSP includes. */\r
6 #include "xemaclite.h"\r
7 \r
8 /* lwIP includes. */\r
9 #include "lwip/opt.h"\r
10 \r
11 \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
18 \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
39 \r
40 #define PHY_DETECT_REG                                                  1\r
41 #define PHY_DETECT_MASK                                                 0x1808\r
42 \r
43 static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance);\r
44 \r
45 unsigned short vInitialisePHY( XEmacLite *pxEMACLiteInstance )\r
46 {\r
47 u16 control;\r
48 u16 status;\r
49 u16 partner_capabilities;\r
50 u16 partner_capabilities_1000;\r
51 u16 phylinkspeed;\r
52 u32 phy_addr = detect_phy_emaclite(pxEMACLiteInstance);\r
53 \r
54         /* Dont advertise PHY speed of 1000 Mbps */\r
55         XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,\r
56                                 IEEE_1000_ADVERTISE_REG_OFFSET,\r
57                                 0);\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
62 \r
63         XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
64                                      IEEE_CONTROL_REG_OFFSET,\r
65                                      &control);\r
66         control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |\r
67                                         IEEE_STAT_AUTONEGOTIATE_RESTART);\r
68 \r
69         XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,\r
70                                 IEEE_CONTROL_REG_OFFSET,\r
71                                 control);\r
72 \r
73         /* Read PHY control and status registers is successful. */\r
74         XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
75                                      IEEE_CONTROL_REG_OFFSET,\r
76                                      &control);\r
77         XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
78                                      IEEE_STATUS_REG_OFFSET,\r
79                                      &status);\r
80 \r
81         if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) &&\r
82                         (status & IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {\r
83 \r
84                 while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {\r
85                         XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
86                                                      IEEE_STATUS_REG_OFFSET,\r
87                                                      &status);\r
88                 }\r
89 \r
90                 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
91                                              IEEE_PARTNER_ABILITIES_1_REG_OFFSET,\r
92                                              &partner_capabilities);\r
93 \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
99                 }\r
100 \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
103 \r
104                 xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",\r
105                                 __FUNCTION__);\r
106                 return 10;\r
107 \r
108 \r
109         } else {\r
110 \r
111                 /* Update TEMAC speed accordingly */\r
112                 if (status & IEEE_STAT_1GBPS_EXTENSIONS) {\r
113 \r
114                         /* Get commanded link speed */\r
115                         phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;\r
116 \r
117                         switch (phylinkspeed) {\r
118                                 case (IEEE_CTRL_LINKSPEED_1000M):\r
119                                         return 1000;\r
120                                 case (IEEE_CTRL_LINKSPEED_100M):\r
121                                         return 100;\r
122                                 case (IEEE_CTRL_LINKSPEED_10M):\r
123                                         return 10;\r
124                                 default:\r
125                                         xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",\r
126                                                         __FUNCTION__, phylinkspeed);\r
127                                         return 10;\r
128                         }\r
129 \r
130                 } else {\r
131 \r
132                         return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;\r
133 \r
134                 }\r
135 \r
136         }\r
137 }\r
138 \r
139 \r
140 static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance)\r
141 {\r
142         u16 phy_reg;\r
143         u32 phy_addr;\r
144 \r
145         for (phy_addr = 31; phy_addr > 0; phy_addr--) {\r
146                 XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr, PHY_DETECT_REG, &phy_reg);\r
147 \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
153                         return phy_addr;\r
154                 }\r
155         }\r
156 \r
157         LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: No PHY detected.  Assuming a PHY at address 0\r\n"));\r
158 \r
159         /* default to zero */\r
160         return 0;\r
161 }\r
162 \r
163 \r