aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sfc/mdio_10g.c4
-rw-r--r--drivers/net/sfc/tenxpress.c27
-rw-r--r--drivers/net/sfc/workarounds.h5
3 files changed, 18 insertions, 18 deletions
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a16428113d..7f09ab581945 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,7 @@
15#include "net_driver.h" 15#include "net_driver.h"
16#include "mdio_10g.h" 16#include "mdio_10g.h"
17#include "boards.h" 17#include "boards.h"
18#include "workarounds.h"
18 19
19int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, 20int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
20 int spins, int spintime) 21 int spins, int spintime)
@@ -517,6 +518,9 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
517 reg |= BMCR_ANENABLE | BMCR_ANRESTART; 518 reg |= BMCR_ANENABLE | BMCR_ANRESTART;
518 else 519 else
519 reg &= ~BMCR_ANENABLE; 520 reg &= ~BMCR_ANENABLE;
521 if (EFX_WORKAROUND_15195(efx)
522 && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
523 reg &= ~BMCR_ANRESTART;
520 if (xnp) 524 if (xnp)
521 reg |= 1 << MDIO_AN_CTRL_XNP_LBN; 525 reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
522 else 526 else
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 80c8d6e3131e..bc2833f9cbe4 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -511,7 +511,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
511{ 511{
512 struct tenxpress_phy_data *phy_data = efx->phy_data; 512 struct tenxpress_phy_data *phy_data = efx->phy_data;
513 struct ethtool_cmd ecmd; 513 struct ethtool_cmd ecmd;
514 bool phy_mode_change, loop_reset, loop_toggle, loopback; 514 bool phy_mode_change, loop_reset;
515 515
516 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { 516 if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
517 phy_data->phy_mode = efx->phy_mode; 517 phy_data->phy_mode = efx->phy_mode;
@@ -522,12 +522,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
522 522
523 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && 523 phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
524 phy_data->phy_mode != PHY_MODE_NORMAL); 524 phy_data->phy_mode != PHY_MODE_NORMAL);
525 loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
526 loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
527 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || 525 loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
528 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); 526 LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
529 527
530 if (loop_reset || loop_toggle || loopback || phy_mode_change) { 528 if (loop_reset || phy_mode_change) {
531 int rc; 529 int rc;
532 530
533 efx->phy_op->get_settings(efx, &ecmd); 531 efx->phy_op->get_settings(efx, &ecmd);
@@ -542,20 +540,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
542 falcon_reset_xaui(efx); 540 falcon_reset_xaui(efx);
543 } 541 }
544 542
545 if (efx->phy_type != PHY_TYPE_SFX7101) {
546 /* Only change autoneg once, on coming out or
547 * going into loopback */
548 if (loop_toggle)
549 ecmd.autoneg = !loopback;
550 if (loopback) {
551 ecmd.duplex = DUPLEX_FULL;
552 if (efx->loopback_mode == LOOPBACK_GPHY)
553 ecmd.speed = SPEED_1000;
554 else
555 ecmd.speed = SPEED_10000;
556 }
557 }
558
559 rc = efx->phy_op->set_settings(efx, &ecmd); 543 rc = efx->phy_op->set_settings(efx, &ecmd);
560 WARN_ON(rc); 544 WARN_ON(rc);
561 } 545 }
@@ -813,6 +797,13 @@ static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
813 ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? 797 ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
814 DUPLEX_FULL : DUPLEX_HALF); 798 DUPLEX_FULL : DUPLEX_HALF);
815 } 799 }
800
801 /* In loopback, the PHY automatically brings up the correct interface,
802 * but doesn't advertise the correct speed. So override it */
803 if (efx->loopback_mode == LOOPBACK_GPHY)
804 ecmd->speed = SPEED_1000;
805 else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS)
806 ecmd->speed = SPEED_10000;
816} 807}
817 808
818static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 809static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 797a0cf7cd6b..420fe153ea2f 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -19,6 +19,8 @@
19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) 19#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
20#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) 20#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
21#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) 21#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
22#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
23 (efx)->phy_type == PHY_TYPE_SFT9001B)
22 24
23/* XAUI resets if link not detected */ 25/* XAUI resets if link not detected */
24#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS 26#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -56,4 +58,7 @@
56/* Need to keep AN enabled */ 58/* Need to keep AN enabled */
57#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A 59#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
58 60
61/* Don't restart AN in near-side loopback */
62#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
63
59#endif /* EFX_WORKAROUNDS_H */ 64#endif /* EFX_WORKAROUNDS_H */