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.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index b875c7b292df..a74b7931a3c4 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -241,7 +241,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, int enable)
241{ 241{
242 efx_dword_t reg; 242 efx_dword_t reg;
243 243
244 if (FALCON_REV(efx) < FALCON_REV_B0) 244 if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx))
245 return; 245 return;
246 246
247 /* Flush the ISR */ 247 /* Flush the ISR */
@@ -288,6 +288,9 @@ int falcon_xaui_link_ok(struct efx_nic *efx)
288 efx_dword_t reg; 288 efx_dword_t reg;
289 int align_done, sync_status, link_ok = 0; 289 int align_done, sync_status, link_ok = 0;
290 290
291 if (LOOPBACK_INTERNAL(efx))
292 return 1;
293
291 /* Read link status */ 294 /* Read link status */
292 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC); 295 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
293 296
@@ -378,6 +381,61 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
378 falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC); 381 falcon_xmac_writel(efx, &reg, XM_ADR_HI_REG_MAC);
379} 382}
380 383
384static void falcon_reconfigure_xgxs_core(struct efx_nic *efx)
385{
386 efx_dword_t reg;
387 int xgxs_loopback = (efx->loopback_mode == LOOPBACK_XGXS) ? 1 : 0;
388 int xaui_loopback = (efx->loopback_mode == LOOPBACK_XAUI) ? 1 : 0;
389 int xgmii_loopback =
390 (efx->loopback_mode == LOOPBACK_XGMII) ? 1 : 0;
391
392 /* XGXS block is flaky and will need to be reset if moving
393 * into our out of XGMII, XGXS or XAUI loopbacks. */
394 if (EFX_WORKAROUND_5147(efx)) {
395 int old_xgmii_loopback, old_xgxs_loopback, old_xaui_loopback;
396 int reset_xgxs;
397
398 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
399 old_xgxs_loopback = EFX_DWORD_FIELD(reg, XX_XGXS_LB_EN);
400 old_xgmii_loopback = EFX_DWORD_FIELD(reg, XX_XGMII_LB_EN);
401
402 falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
403 old_xaui_loopback = EFX_DWORD_FIELD(reg, XX_LPBKA);
404
405 /* The PHY driver may have turned XAUI off */
406 reset_xgxs = ((xgxs_loopback != old_xgxs_loopback) ||
407 (xaui_loopback != old_xaui_loopback) ||
408 (xgmii_loopback != old_xgmii_loopback));
409 if (reset_xgxs) {
410 falcon_xmac_readl(efx, &reg, XX_PWR_RST_REG_MAC);
411 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
412 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
413 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
414 udelay(1);
415 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSTX_EN, 0);
416 EFX_SET_DWORD_FIELD(reg, XX_RSTXGXSRX_EN, 0);
417 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
418 udelay(1);
419 }
420 }
421
422 falcon_xmac_readl(efx, &reg, XX_CORE_STAT_REG_MAC);
423 EFX_SET_DWORD_FIELD(reg, XX_FORCE_SIG,
424 (xgxs_loopback || xaui_loopback) ?
425 XX_FORCE_SIG_DECODE_FORCED : 0);
426 EFX_SET_DWORD_FIELD(reg, XX_XGXS_LB_EN, xgxs_loopback);
427 EFX_SET_DWORD_FIELD(reg, XX_XGMII_LB_EN, xgmii_loopback);
428 falcon_xmac_writel(efx, &reg, XX_CORE_STAT_REG_MAC);
429
430 falcon_xmac_readl(efx, &reg, XX_SD_CTL_REG_MAC);
431 EFX_SET_DWORD_FIELD(reg, XX_LPBKD, xaui_loopback);
432 EFX_SET_DWORD_FIELD(reg, XX_LPBKC, xaui_loopback);
433 EFX_SET_DWORD_FIELD(reg, XX_LPBKB, xaui_loopback);
434 EFX_SET_DWORD_FIELD(reg, XX_LPBKA, xaui_loopback);
435 falcon_xmac_writel(efx, &reg, XX_SD_CTL_REG_MAC);
436}
437
438
381/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails 439/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
382 * to come back up. Bash it until it comes back up */ 440 * to come back up. Bash it until it comes back up */
383static int falcon_check_xaui_link_up(struct efx_nic *efx) 441static int falcon_check_xaui_link_up(struct efx_nic *efx)
@@ -386,7 +444,8 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx)
386 tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; 444 tries = EFX_WORKAROUND_5147(efx) ? 5 : 1;
387 max_tries = tries; 445 max_tries = tries;
388 446
389 if (efx->phy_type == PHY_TYPE_NONE) 447 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
448 (efx->phy_type == PHY_TYPE_NONE))
390 return 0; 449 return 0;
391 450
392 while (tries) { 451 while (tries) {
@@ -412,8 +471,13 @@ void falcon_reconfigure_xmac(struct efx_nic *efx)
412 falcon_mask_status_intr(efx, 0); 471 falcon_mask_status_intr(efx, 0);
413 472
414 falcon_deconfigure_mac_wrapper(efx); 473 falcon_deconfigure_mac_wrapper(efx);
474
475 efx->tx_disabled = LOOPBACK_INTERNAL(efx);
415 efx->phy_op->reconfigure(efx); 476 efx->phy_op->reconfigure(efx);
477
478 falcon_reconfigure_xgxs_core(efx);
416 falcon_reconfigure_xmac_core(efx); 479 falcon_reconfigure_xmac_core(efx);
480
417 falcon_reconfigure_mac_wrapper(efx); 481 falcon_reconfigure_mac_wrapper(efx);
418 482
419 /* Ensure XAUI link is up */ 483 /* Ensure XAUI link is up */
@@ -500,6 +564,10 @@ int falcon_check_xmac(struct efx_nic *efx)
500 unsigned xaui_link_ok; 564 unsigned xaui_link_ok;
501 int rc; 565 int rc;
502 566
567 if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
568 (efx->phy_type == PHY_TYPE_NONE))
569 return 0;
570
503 falcon_mask_status_intr(efx, 0); 571 falcon_mask_status_intr(efx, 0);
504 xaui_link_ok = falcon_xaui_link_ok(efx); 572 xaui_link_ok = falcon_xaui_link_ok(efx);
505 573