diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-02-22 13:28:34 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2006-02-23 17:07:07 -0500 |
commit | 0781191cf69b7635e0d3ea55c6019e789d1936fa (patch) | |
tree | 439cf41fdfe02dd501d3820095f96c3a0e2a45f7 /drivers | |
parent | a9cdab869ec343ccc601484fb535813e16c25f70 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/skge.c | 37 |
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 | ||
924 | static void genesis_init(struct skge_hw *hw) | 928 | static 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 | ||