--- /dev/null
+/*\r
+ * Code provided by Xilinx.
+ */\r
+\r
+/* BSP includes. */\r
+#include "xemaclite.h"\r
+\r
+/* lwIP includes. */\r
+#include "lwip/opt.h"\r
+\r
+\r
+/* Advertisement control register. */\r
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */\r
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */\r
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */\r
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */\r
+#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_10HALF | ADVERTISE_100HALF)\r
+\r
+/* PHY registers/offsets. */\r
+#define IEEE_CONTROL_REG_OFFSET 0\r
+#define IEEE_STATUS_REG_OFFSET 1\r
+#define IEEE_AUTONEGO_ADVERTISE_REG 4\r
+#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5\r
+#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10\r
+#define IEEE_1000_ADVERTISE_REG_OFFSET 9\r
+#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040\r
+#define IEEE_CTRL_LINKSPEED_MASK 0x0040\r
+#define IEEE_CTRL_LINKSPEED_1000M 0x0040\r
+#define IEEE_CTRL_LINKSPEED_100M 0x2000\r
+#define IEEE_CTRL_LINKSPEED_10M 0x0000\r
+#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000\r
+#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008\r
+#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020\r
+#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200\r
+#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100\r
+#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00\r
+#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380\r
+#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060\r
+\r
+#define PHY_DETECT_REG 1\r
+#define PHY_DETECT_MASK 0x1808\r
+\r
+static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance);\r
+\r
+unsigned short vInitialisePHY( XEmacLite *pxEMACLiteInstance )\r
+{\r
+u16 control;\r
+u16 status;\r
+u16 partner_capabilities;\r
+u16 partner_capabilities_1000;\r
+u16 phylinkspeed;\r
+u32 phy_addr = detect_phy_emaclite(pxEMACLiteInstance);\r
+\r
+ /* Dont advertise PHY speed of 1000 Mbps */\r
+ XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,\r
+ IEEE_1000_ADVERTISE_REG_OFFSET,\r
+ 0);\r
+ /* Advertise PHY speed of 100 and 10 Mbps */\r
+ XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,\r
+ IEEE_AUTONEGO_ADVERTISE_REG,\r
+ ADVERTISE_100_AND_10);\r
+\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_CONTROL_REG_OFFSET,\r
+ &control);\r
+ control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |\r
+ IEEE_STAT_AUTONEGOTIATE_RESTART);\r
+\r
+ XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,\r
+ IEEE_CONTROL_REG_OFFSET,\r
+ control);\r
+\r
+ /* Read PHY control and status registers is successful. */\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_CONTROL_REG_OFFSET,\r
+ &control);\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_STATUS_REG_OFFSET,\r
+ &status);\r
+\r
+ if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) &&\r
+ (status & IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {\r
+\r
+ while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_STATUS_REG_OFFSET,\r
+ &status);\r
+ }\r
+\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_PARTNER_ABILITIES_1_REG_OFFSET,\r
+ &partner_capabilities);\r
+\r
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,\r
+ IEEE_PARTNER_ABILITIES_3_REG_OFFSET,\r
+ &partner_capabilities_1000);\r
+ if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS) return 1000;\r
+ }\r
+\r
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS) return 100;\r
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS) return 10;\r
+\r
+ xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",\r
+ __FUNCTION__);\r
+ return 10;\r
+\r
+\r
+ } else {\r
+\r
+ /* Update TEMAC speed accordingly */\r
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {\r
+\r
+ /* Get commanded link speed */\r
+ phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;\r
+\r
+ switch (phylinkspeed) {\r
+ case (IEEE_CTRL_LINKSPEED_1000M):\r
+ return 1000;\r
+ case (IEEE_CTRL_LINKSPEED_100M):\r
+ return 100;\r
+ case (IEEE_CTRL_LINKSPEED_10M):\r
+ return 10;\r
+ default:\r
+ xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",\r
+ __FUNCTION__, phylinkspeed);\r
+ return 10;\r
+ }\r
+\r
+ } else {\r
+\r
+ return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;\r
+\r
+ }\r
+\r
+ }\r
+}\r
+\r
+\r
+static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance)\r
+{\r
+ u16 phy_reg;\r
+ u32 phy_addr;\r
+\r
+ for (phy_addr = 31; phy_addr > 0; phy_addr--) {\r
+ XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr, PHY_DETECT_REG, &phy_reg);\r
+\r
+ if ((phy_reg != 0xFFFF) &&\r
+ ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {\r
+ /* Found a valid PHY address */\r
+ LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected at address %d.\r\n", phy_addr));\r
+ LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected.\r\n"));\r
+ return phy_addr;\r
+ }\r
+ }\r
+\r
+ LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: No PHY detected. Assuming a PHY at address 0\r\n"));\r
+\r
+ /* default to zero */\r
+ return 0;\r
+}\r
+\r
+\r