aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon_xmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/falcon_xmac.c')
-rw-r--r--drivers/net/sfc/falcon_xmac.c50
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 */ 247static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
248static 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
272static bool falcon_xmac_check_fault(struct efx_nic *efx)
273{
274 return !falcon_check_xaui_link_up(efx, 5);
269} 275}
270 276
271static void falcon_reconfigure_xmac(struct efx_nic *efx) 277static 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
344static void falcon_xmac_irq(struct efx_nic *efx) 350void 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
360static 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
370struct efx_mac_operations falcon_xmac_operations = { 361struct 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};