diff options
Diffstat (limited to 'drivers/net/sfc/falcon_xmac.c')
-rw-r--r-- | drivers/net/sfc/falcon_xmac.c | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index e57545de60ff..784260f63d4c 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
@@ -98,7 +98,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) | |||
98 | 98 | ||
99 | /* We can only use this interrupt to signal the negative edge of | 99 | /* We can only use this interrupt to signal the negative edge of |
100 | * xaui_align [we have to poll the positive edge]. */ | 100 | * xaui_align [we have to poll the positive edge]. */ |
101 | if (!efx->mac_up) | 101 | if (efx->xmac_poll_required) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Flush the ISR */ | 104 | /* Flush the ISR */ |
@@ -243,29 +243,35 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | 245 | ||
246 | /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails | 246 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ |
247 | * to come back up. Bash it until it comes back up */ | 247 | static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) |
248 | static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | ||
249 | { | 248 | { |
250 | efx->mac_up = falcon_xaui_link_ok(efx); | 249 | bool mac_up = falcon_xaui_link_ok(efx); |
251 | 250 | ||
252 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || | 251 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || |
253 | efx_phy_mode_disabled(efx->phy_mode)) | 252 | efx_phy_mode_disabled(efx->phy_mode)) |
254 | /* XAUI link is expected to be down */ | 253 | /* XAUI link is expected to be down */ |
255 | return; | 254 | return mac_up; |
256 | 255 | ||
257 | falcon_stop_nic_stats(efx); | 256 | falcon_stop_nic_stats(efx); |
258 | 257 | ||
259 | while (!efx->mac_up && tries) { | 258 | while (!mac_up && tries) { |
260 | EFX_LOG(efx, "bashing xaui\n"); | 259 | EFX_LOG(efx, "bashing xaui\n"); |
261 | falcon_reset_xaui(efx); | 260 | falcon_reset_xaui(efx); |
262 | udelay(200); | 261 | udelay(200); |
263 | 262 | ||
264 | efx->mac_up = falcon_xaui_link_ok(efx); | 263 | mac_up = falcon_xaui_link_ok(efx); |
265 | --tries; | 264 | --tries; |
266 | } | 265 | } |
267 | 266 | ||
268 | falcon_start_nic_stats(efx); | 267 | falcon_start_nic_stats(efx); |
268 | |||
269 | return mac_up; | ||
270 | } | ||
271 | |||
272 | static bool falcon_xmac_check_fault(struct efx_nic *efx) | ||
273 | { | ||
274 | return !falcon_check_xaui_link_up(efx, 5); | ||
269 | } | 275 | } |
270 | 276 | ||
271 | static void falcon_reconfigure_xmac(struct efx_nic *efx) | 277 | static void falcon_reconfigure_xmac(struct efx_nic *efx) |
@@ -277,7 +283,7 @@ static void falcon_reconfigure_xmac(struct efx_nic *efx) | |||
277 | 283 | ||
278 | falcon_reconfigure_mac_wrapper(efx); | 284 | falcon_reconfigure_mac_wrapper(efx); |
279 | 285 | ||
280 | falcon_check_xaui_link_up(efx, 5); | 286 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5); |
281 | falcon_mask_status_intr(efx, true); | 287 | falcon_mask_status_intr(efx, true); |
282 | } | 288 | } |
283 | 289 | ||
@@ -341,35 +347,19 @@ static void falcon_update_stats_xmac(struct efx_nic *efx) | |||
341 | mac_stats->rx_control * 64); | 347 | mac_stats->rx_control * 64); |
342 | } | 348 | } |
343 | 349 | ||
344 | static void falcon_xmac_irq(struct efx_nic *efx) | 350 | void falcon_poll_xmac(struct efx_nic *efx) |
345 | { | ||
346 | /* The XGMII link has a transient fault, which indicates either: | ||
347 | * - there's a transient xgmii fault | ||
348 | * - falcon's end of the xaui link may need a kick | ||
349 | * - the wire-side link may have gone down, but the lasi/poll() | ||
350 | * hasn't noticed yet. | ||
351 | * | ||
352 | * We only want to even bother polling XAUI if we're confident it's | ||
353 | * not (1) or (3). In both cases, the only reliable way to spot this | ||
354 | * is to wait a bit. We do this here by forcing the mac link state | ||
355 | * to down, and waiting for the mac poll to come round and check | ||
356 | */ | ||
357 | efx->mac_up = false; | ||
358 | } | ||
359 | |||
360 | static void falcon_poll_xmac(struct efx_nic *efx) | ||
361 | { | 351 | { |
362 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || efx->mac_up) | 352 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || |
353 | !efx->xmac_poll_required) | ||
363 | return; | 354 | return; |
364 | 355 | ||
365 | falcon_mask_status_intr(efx, false); | 356 | falcon_mask_status_intr(efx, false); |
366 | falcon_check_xaui_link_up(efx, 1); | 357 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1); |
367 | falcon_mask_status_intr(efx, true); | 358 | falcon_mask_status_intr(efx, true); |
368 | } | 359 | } |
369 | 360 | ||
370 | struct efx_mac_operations falcon_xmac_operations = { | 361 | struct efx_mac_operations falcon_xmac_operations = { |
371 | .reconfigure = falcon_reconfigure_xmac, | 362 | .reconfigure = falcon_reconfigure_xmac, |
372 | .update_stats = falcon_update_stats_xmac, | 363 | .update_stats = falcon_update_stats_xmac, |
373 | .irq = falcon_xmac_irq, | 364 | .check_fault = falcon_xmac_check_fault, |
374 | .poll = falcon_poll_xmac, | ||
375 | }; | 365 | }; |