diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-09-01 07:49:25 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-24 18:54:36 -0400 |
commit | c8fcc49c542a2312c706ebf76dcfe5266b39ee13 (patch) | |
tree | a2d5bb988c4de5bfcc3e95a4eca44e44503ac470 /drivers/net/sfc | |
parent | ef08af03ef85373901a2ca0241617e6e7e42685d (diff) |
sfc: Serialise tenxpress_special_reset() with statistics fetches
On some boards 10Xpress feeds a 156 MHz clock to the Falcon XMAC. MAC
statistics DMA can fail while this clock is stopped during a PHY reset.
From: Steve Hodgson <shodgson@solarflare.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 77e7f3a94b25..2ad3d8d12f42 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -214,7 +214,10 @@ static int tenxpress_special_reset(struct efx_nic *efx) | |||
214 | { | 214 | { |
215 | int rc, reg; | 215 | int rc, reg; |
216 | 216 | ||
217 | EFX_TRACE(efx, "%s\n", __func__); | 217 | /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so |
218 | * a special software reset can glitch the XGMAC sufficiently for stats | ||
219 | * requests to fail. Since we don't ofen special_reset, just lock. */ | ||
220 | spin_lock(&efx->stats_lock); | ||
218 | 221 | ||
219 | /* Initiate reset */ | 222 | /* Initiate reset */ |
220 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | 223 | reg = mdio_clause45_read(efx, efx->mii.phy_id, |
@@ -223,20 +226,22 @@ static int tenxpress_special_reset(struct efx_nic *efx) | |||
223 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | 226 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, |
224 | PMA_PMD_EXT_CTRL_REG, reg); | 227 | PMA_PMD_EXT_CTRL_REG, reg); |
225 | 228 | ||
226 | msleep(200); | 229 | mdelay(200); |
227 | 230 | ||
228 | /* Wait for the blocks to come out of reset */ | 231 | /* Wait for the blocks to come out of reset */ |
229 | rc = mdio_clause45_wait_reset_mmds(efx, | 232 | rc = mdio_clause45_wait_reset_mmds(efx, |
230 | TENXPRESS_REQUIRED_DEVS); | 233 | TENXPRESS_REQUIRED_DEVS); |
231 | if (rc < 0) | 234 | if (rc < 0) |
232 | return rc; | 235 | goto unlock; |
233 | 236 | ||
234 | /* Try and reconfigure the device */ | 237 | /* Try and reconfigure the device */ |
235 | rc = tenxpress_init(efx); | 238 | rc = tenxpress_init(efx); |
236 | if (rc < 0) | 239 | if (rc < 0) |
237 | return rc; | 240 | goto unlock; |
238 | 241 | ||
239 | return 0; | 242 | unlock: |
243 | spin_unlock(&efx->stats_lock); | ||
244 | return rc; | ||
240 | } | 245 | } |
241 | 246 | ||
242 | static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp) | 247 | static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp) |