diff options
-rw-r--r-- | drivers/net/sfc/ethtool.c | 18 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.c | 15 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.h | 20 | ||||
-rw-r--r-- | drivers/net/sfc/falcon_xmac.c | 2 | ||||
-rw-r--r-- | drivers/net/sfc/mdio_10g.c | 4 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 35 | ||||
-rw-r--r-- | drivers/net/sfc/qt202x_phy.c | 12 | ||||
-rw-r--r-- | drivers/net/sfc/selftest.c | 5 | ||||
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 49 |
9 files changed, 95 insertions, 65 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index e86cbca75ea8..4fe874052e3e 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -365,9 +365,21 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, efx_fill_test(n++, strings, data, &tests->registers, "core", 0, "registers", NULL); - for (i = 0; i < efx->phy_op->num_tests; i++) - efx_fill_test(n++, strings, data, &tests->phy[i], - "phy", 0, efx->phy_op->test_names[i], NULL); + if (efx->phy_op->run_tests != NULL) { + EFX_BUG_ON_PARANOID(efx->phy_op->test_name == NULL); + + for (i = 0; true; ++i) { + const char *name; + + EFX_BUG_ON_PARANOID(i >= EFX_MAX_PHY_TESTS); + name = efx->phy_op->test_name(efx, i); + if (name == NULL) + break; + + efx_fill_test(n++, strings, data, &tests->phy[i], + "phy", 0, name, NULL); + } + } /* Loopback tests */ for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 63e6734d8341..29d45376e4c9 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2291,19 +2291,12 @@ static int falcon_probe_port(struct efx_nic *efx) return -ENODEV; } - if (efx->phy_op->macs & EFX_XMAC) - efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | - (1 << LOOPBACK_XGXS) | - (1 << LOOPBACK_XAUI)); - if (efx->phy_op->macs & EFX_GMAC) - efx->loopback_modes |= (1 << LOOPBACK_GMAC); - efx->loopback_modes |= efx->phy_op->loopbacks; - - /* Set up MDIO structure for PHY */ - efx->mdio.mmds = efx->phy_op->mmds; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + /* Fill out MDIO structure and loopback modes */ efx->mdio.mdio_read = falcon_mdio_read; efx->mdio.mdio_write = falcon_mdio_write; + rc = efx->phy_op->probe(efx); + if (rc != 0) + return rc; /* Initial assumption */ efx->link_state.speed = 10000; diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index 875b58e94e8e..3085ecfaceed 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h @@ -38,6 +38,26 @@ static inline bool efx_nic_is_dual_func(struct efx_nic *efx) return efx_nic_rev(efx) < EFX_REV_FALCON_B0; } +enum { + PHY_TYPE_NONE = 0, + PHY_TYPE_TXC43128 = 1, + PHY_TYPE_88E1111 = 2, + PHY_TYPE_SFX7101 = 3, + PHY_TYPE_QT2022C2 = 4, + PHY_TYPE_PM8358 = 6, + PHY_TYPE_SFT9001A = 8, + PHY_TYPE_QT2025C = 9, + PHY_TYPE_SFT9001B = 10, +}; + +#define FALCON_XMAC_LOOPBACKS \ + ((1 << LOOPBACK_XGMII) | \ + (1 << LOOPBACK_XGXS) | \ + (1 << LOOPBACK_XAUI)) + +#define FALCON_GMAC_LOOPBACKS \ + (1 << LOOPBACK_GMAC) + /** * struct falcon_board_type - board operations and type information * @id: Board type id, as found in NVRAM diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 83da79279a95..643622df6e62 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -137,7 +137,7 @@ static bool falcon_xaui_link_ok(struct efx_nic *efx) /* If the link is up, then check the phy side of the xaui link */ if (efx->link_state.up && link_ok) - if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) + if (efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) link_ok = efx_mdio_phyxgxs_lane_sync(efx); return link_ok; diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index e6ca988abbb5..20e627431d27 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -15,6 +15,7 @@ #include "net_driver.h" #include "mdio_10g.h" #include "workarounds.h" +#include "falcon.h" unsigned efx_mdio_id_oui(u32 id) { @@ -312,8 +313,7 @@ void efx_mdio_an_reconfigure(struct efx_nic *efx) /* Enable and restart AN */ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); reg |= MDIO_AN_CTRL1_ENABLE; - if (!(EFX_WORKAROUND_15195(efx) && - LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) + if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_EXTERNAL(efx))) reg |= MDIO_AN_CTRL1_RESTART; if (xnp) reg |= MDIO_AN_CTRL1_XNP; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index cd2debb0a552..452f83510b0d 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -428,19 +428,6 @@ enum efx_int_mode { }; #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI) -enum phy_type { - PHY_TYPE_NONE = 0, - PHY_TYPE_TXC43128 = 1, - PHY_TYPE_88E1111 = 2, - PHY_TYPE_SFX7101 = 3, - PHY_TYPE_QT2022C2 = 4, - PHY_TYPE_PM8358 = 6, - PHY_TYPE_SFT9001A = 8, - PHY_TYPE_QT2025C = 9, - PHY_TYPE_SFT9001B = 10, - PHY_TYPE_MAX /* Insert any new items before this */ -}; - #define EFX_IS10G(efx) ((efx)->link_state.speed == 10000) enum nic_state { @@ -483,12 +470,6 @@ enum efx_fc_type { EFX_FC_AUTO = 4, }; -/* Supported MAC bit-mask */ -enum efx_mac_type { - EFX_GMAC = 1, - EFX_XMAC = 2, -}; - /** * struct efx_link_state - Current state of the link * @up: Link is up @@ -524,6 +505,8 @@ struct efx_mac_operations { /** * struct efx_phy_operations - Efx PHY operations table + * @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds, + * efx->loopback_modes. * @init: Initialise PHY * @fini: Shut down PHY * @reconfigure: Reconfigure PHY (e.g. for new link parameters) @@ -533,15 +516,12 @@ struct efx_mac_operations { * @set_settings: Set ethtool settings. Serialised by the mac_lock. * @set_npage_adv: Set abilities advertised in (Extended) Next Page * (only needed where AN bit is set in mmds) - * @num_tests: Number of PHY-specific tests/results - * @test_names: Names of the tests/results + * @test_name: Get the name of a PHY-specific test/result * @run_tests: Run tests and record results as appropriate. * Flags are the ethtool tests flags. - * @mmds: MMD presence mask - * @loopbacks: Supported loopback modes mask */ struct efx_phy_operations { - enum efx_mac_type macs; + int (*probe) (struct efx_nic *efx); int (*init) (struct efx_nic *efx); void (*fini) (struct efx_nic *efx); int (*reconfigure) (struct efx_nic *efx); @@ -551,11 +531,8 @@ struct efx_phy_operations { int (*set_settings) (struct efx_nic *efx, struct ethtool_cmd *ecmd); void (*set_npage_adv) (struct efx_nic *efx, u32); - u32 num_tests; - const char *const *test_names; + const char *(*test_name) (struct efx_nic *efx, unsigned int index); int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); - int mmds; - unsigned loopbacks; }; /** @@ -806,7 +783,7 @@ struct efx_nic { struct efx_mac_operations *mac_op; unsigned char mac_address[ETH_ALEN]; - enum phy_type phy_type; + unsigned int phy_type; struct mutex mdio_lock; struct efx_phy_operations *phy_op; void *phy_data; diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 49a5ab5efb9a..22b0e89ba8f2 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -135,6 +135,14 @@ static int qt202x_reset_phy(struct efx_nic *efx) return rc; } +static int qt202x_phy_probe(struct efx_nic *efx) +{ + efx->mdio.mmds = QT202X_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + return 0; +} + static int qt202x_phy_init(struct efx_nic *efx) { struct qt202x_phy_data *phy_data; @@ -224,13 +232,11 @@ static void qt202x_phy_fini(struct efx_nic *efx) } struct efx_phy_operations falcon_qt202x_phy_ops = { - .macs = EFX_XMAC, + .probe = qt202x_phy_probe, .init = qt202x_phy_init, .reconfigure = qt202x_phy_reconfigure, .poll = qt202x_phy_poll, .fini = qt202x_phy_fini, .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, - .mmds = QT202X_REQUIRED_DEVS, - .loopbacks = QT202X_LOOPBACKS, }; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 9a240536debc..16258d83b703 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -100,7 +100,7 @@ static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) } if (EFX_IS10G(efx)) { - rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0); + rc = efx_mdio_check_mmds(efx, efx->mdio.mmds, 0); if (rc) goto out; } @@ -253,9 +253,6 @@ static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests, if (!efx->phy_op->run_tests) return 0; - EFX_BUG_ON_PARANOID(efx->phy_op->num_tests == 0 || - efx->phy_op->num_tests > EFX_MAX_PHY_TESTS); - mutex_lock(&efx->mac_lock); rc = efx->phy_op->run_tests(efx, tests->phy, flags); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 0dfb2275a158..8de97a9f2719 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -298,6 +298,23 @@ static int tenxpress_init(struct efx_nic *efx) return 0; } +static int sfx7101_phy_probe(struct efx_nic *efx) +{ + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + return 0; +} + +static int sft9001_phy_probe(struct efx_nic *efx) +{ + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->loopback_modes = (SFT9001_LOOPBACKS | FALCON_XMAC_LOOPBACKS | + FALCON_GMAC_LOOPBACKS); + return 0; +} + static int tenxpress_phy_init(struct efx_nic *efx) { struct tenxpress_phy_data *phy_data; @@ -512,7 +529,7 @@ static int tenxpress_phy_reconfigure(struct efx_nic *efx) phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && phy_data->phy_mode != PHY_MODE_NORMAL); - loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || + loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) || LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); if (loop_reset || phy_mode_change) { @@ -627,6 +644,13 @@ static const char *const sfx7101_test_names[] = { "bist" }; +static const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index) +{ + if (index < ARRAY_SIZE(sfx7101_test_names)) + return sfx7101_test_names[index]; + return NULL; +} + static int sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) { @@ -656,6 +680,13 @@ static const char *const sft9001_test_names[] = { "cable.pairD.length", }; +static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index) +{ + if (index < ARRAY_SIZE(sft9001_test_names)) + return sft9001_test_names[index]; + return NULL; +} + static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) { int rc = 0, rc2, i, ctrl_reg, res_reg; @@ -758,7 +789,7 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) * but doesn't advertise the correct speed. So override it */ if (efx->loopback_mode == LOOPBACK_GPHY) ecmd->speed = SPEED_1000; - else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) + else if (LOOPBACK_EXTERNAL(efx)) ecmd->speed = SPEED_10000; } @@ -788,7 +819,7 @@ static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) } struct efx_phy_operations falcon_sfx7101_phy_ops = { - .macs = EFX_XMAC, + .probe = sfx7101_phy_probe, .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, .poll = tenxpress_phy_poll, @@ -796,15 +827,12 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { .get_settings = tenxpress_get_settings, .set_settings = tenxpress_set_settings, .set_npage_adv = sfx7101_set_npage_adv, - .num_tests = ARRAY_SIZE(sfx7101_test_names), - .test_names = sfx7101_test_names, + .test_name = sfx7101_test_name, .run_tests = sfx7101_run_tests, - .mmds = TENXPRESS_REQUIRED_DEVS, - .loopbacks = SFX7101_LOOPBACKS, }; struct efx_phy_operations falcon_sft9001_phy_ops = { - .macs = EFX_GMAC | EFX_XMAC, + .probe = sft9001_phy_probe, .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, .poll = tenxpress_phy_poll, @@ -812,9 +840,6 @@ struct efx_phy_operations falcon_sft9001_phy_ops = { .get_settings = tenxpress_get_settings, .set_settings = tenxpress_set_settings, .set_npage_adv = sft9001_set_npage_adv, - .num_tests = ARRAY_SIZE(sft9001_test_names), - .test_names = sft9001_test_names, + .test_name = sft9001_test_name, .run_tests = sft9001_run_tests, - .mmds = TENXPRESS_REQUIRED_DEVS, - .loopbacks = SFT9001_LOOPBACKS, }; |