aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-02-22 13:28:34 -0500
committerFrancois Romieu <romieu@fr.zoreil.com>2006-02-23 17:07:07 -0500
commit0781191cf69b7635e0d3ea55c6019e789d1936fa (patch)
tree439cf41fdfe02dd501d3820095f96c3a0e2a45f7
parenta9cdab869ec343ccc601484fb535813e16c25f70 (diff)
skge: genesis phy initialzation
The SysKonnect Genesis based board would fail on initialization with phy_read errors caused by not waiting for last phy write. Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
-rw-r--r--drivers/net/skge.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 869c7cfb99a4..af2e6782031b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -879,13 +879,12 @@ static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
879 int i; 879 int i;
880 880
881 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 881 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
882 xm_read16(hw, port, XM_PHY_DATA); 882 *val = xm_read16(hw, port, XM_PHY_DATA);
883 883
884 /* Need to wait for external PHY */
885 for (i = 0; i < PHY_RETRIES; i++) { 884 for (i = 0; i < PHY_RETRIES; i++) {
886 udelay(1);
887 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) 885 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
888 goto ready; 886 goto ready;
887 udelay(1);
889 } 888 }
890 889
891 return -ETIMEDOUT; 890 return -ETIMEDOUT;
@@ -918,7 +917,12 @@ static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
918 917
919 ready: 918 ready:
920 xm_write16(hw, port, XM_PHY_DATA, val); 919 xm_write16(hw, port, XM_PHY_DATA, val);
921 return 0; 920 for (i = 0; i < PHY_RETRIES; i++) {
921 if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
922 return 0;
923 udelay(1);
924 }
925 return -ETIMEDOUT;
922} 926}
923 927
924static void genesis_init(struct skge_hw *hw) 928static void genesis_init(struct skge_hw *hw)
@@ -1168,13 +1172,17 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1168 u32 r; 1172 u32 r;
1169 const u8 zero[6] = { 0 }; 1173 const u8 zero[6] = { 0 };
1170 1174
1171 /* Clear MIB counters */ 1175 for (i = 0; i < 10; i++) {
1172 xm_write16(hw, port, XM_STAT_CMD, 1176 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
1173 XM_SC_CLR_RXC | XM_SC_CLR_TXC); 1177 MFF_SET_MAC_RST);
1174 /* Clear two times according to Errata #3 */ 1178 if (skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST)
1175 xm_write16(hw, port, XM_STAT_CMD, 1179 goto reset_ok;
1176 XM_SC_CLR_RXC | XM_SC_CLR_TXC); 1180 udelay(1);
1181 }
1177 1182
1183 printk(KERN_WARNING PFX "%s: genesis reset failed\n", dev->name);
1184
1185 reset_ok:
1178 /* Unreset the XMAC. */ 1186 /* Unreset the XMAC. */
1179 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); 1187 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
1180 1188
@@ -1191,7 +1199,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1191 r |= GP_DIR_2|GP_IO_2; 1199 r |= GP_DIR_2|GP_IO_2;
1192 1200
1193 skge_write32(hw, B2_GP_IO, r); 1201 skge_write32(hw, B2_GP_IO, r);
1194 skge_read32(hw, B2_GP_IO); 1202
1195 1203
1196 /* Enable GMII interface */ 1204 /* Enable GMII interface */
1197 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1205 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
@@ -1205,6 +1213,13 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1205 for (i = 1; i < 16; i++) 1213 for (i = 1; i < 16; i++)
1206 xm_outaddr(hw, port, XM_EXM(i), zero); 1214 xm_outaddr(hw, port, XM_EXM(i), zero);
1207 1215
1216 /* Clear MIB counters */
1217 xm_write16(hw, port, XM_STAT_CMD,
1218 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
1219 /* Clear two times according to Errata #3 */
1220 xm_write16(hw, port, XM_STAT_CMD,
1221 XM_SC_CLR_RXC | XM_SC_CLR_TXC);
1222
1208 /* configure Rx High Water Mark (XM_RX_HI_WM) */ 1223 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1209 xm_write16(hw, port, XM_RX_HI_WM, 1450); 1224 xm_write16(hw, port, XM_RX_HI_WM, 1450);
1210 1225