]> git.sur5r.net Git - freertos/commitdiff
Add in necessary functionality to autonegotiate using the EthernetLite interface...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 6 Aug 2011 08:28:25 +0000 (08:28 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 6 Aug 2011 08:28:25 +0000 (08:28 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1537 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/Common/ethernet/lwip-1.4.0/ports/MicroBlaze-Ethernet-Lite/SP605_PHY.c [new file with mode: 0644]

diff --git a/Demo/Common/ethernet/lwip-1.4.0/ports/MicroBlaze-Ethernet-Lite/SP605_PHY.c b/Demo/Common/ethernet/lwip-1.4.0/ports/MicroBlaze-Ethernet-Lite/SP605_PHY.c
new file mode 100644 (file)
index 0000000..003af44
--- /dev/null
@@ -0,0 +1,163 @@
+/*\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