Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /****************************************************************************
0003  * Driver for Solarflare network controllers and boards
0004  * Copyright 2007-2011 Solarflare Communications Inc.
0005  */
0006 
0007 #include <linux/delay.h>
0008 #include <linux/rtnetlink.h>
0009 #include <linux/seq_file.h>
0010 #include <linux/slab.h>
0011 #include "efx.h"
0012 #include "mdio_10g.h"
0013 #include "nic.h"
0014 #include "phy.h"
0015 #include "workarounds.h"
0016 
0017 /* We expect these MMDs to be in the package. */
0018 #define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD   | \
0019                  MDIO_DEVS_PCS      | \
0020                  MDIO_DEVS_PHYXS    | \
0021                  MDIO_DEVS_AN)
0022 
0023 #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |  \
0024                (1 << LOOPBACK_PCS) |    \
0025                (1 << LOOPBACK_PMAPMD) | \
0026                (1 << LOOPBACK_PHYXS_WS))
0027 
0028 /* We complain if we fail to see the link partner as 10G capable this many
0029  * times in a row (must be > 1 as sampling the autoneg. registers is racy)
0030  */
0031 #define MAX_BAD_LP_TRIES    (5)
0032 
0033 /* Extended control register */
0034 #define PMA_PMD_XCONTROL_REG    49152
0035 #define PMA_PMD_EXT_GMII_EN_LBN 1
0036 #define PMA_PMD_EXT_GMII_EN_WIDTH 1
0037 #define PMA_PMD_EXT_CLK_OUT_LBN 2
0038 #define PMA_PMD_EXT_CLK_OUT_WIDTH 1
0039 #define PMA_PMD_LNPGA_POWERDOWN_LBN 8
0040 #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
0041 #define PMA_PMD_EXT_CLK312_WIDTH 1
0042 #define PMA_PMD_EXT_LPOWER_LBN  12
0043 #define PMA_PMD_EXT_LPOWER_WIDTH 1
0044 #define PMA_PMD_EXT_ROBUST_LBN  14
0045 #define PMA_PMD_EXT_ROBUST_WIDTH 1
0046 #define PMA_PMD_EXT_SSR_LBN 15
0047 #define PMA_PMD_EXT_SSR_WIDTH   1
0048 
0049 /* extended status register */
0050 #define PMA_PMD_XSTATUS_REG 49153
0051 #define PMA_PMD_XSTAT_MDIX_LBN  14
0052 #define PMA_PMD_XSTAT_FLP_LBN   (12)
0053 
0054 /* LED control register */
0055 #define PMA_PMD_LED_CTRL_REG    49159
0056 #define PMA_PMA_LED_ACTIVITY_LBN    (3)
0057 
0058 /* LED function override register */
0059 #define PMA_PMD_LED_OVERR_REG   49161
0060 /* Bit positions for different LEDs (there are more but not wired on SFE4001)*/
0061 #define PMA_PMD_LED_LINK_LBN    (0)
0062 #define PMA_PMD_LED_SPEED_LBN   (2)
0063 #define PMA_PMD_LED_TX_LBN  (4)
0064 #define PMA_PMD_LED_RX_LBN  (6)
0065 /* Override settings */
0066 #define PMA_PMD_LED_AUTO    (0) /* H/W control */
0067 #define PMA_PMD_LED_ON      (1)
0068 #define PMA_PMD_LED_OFF     (2)
0069 #define PMA_PMD_LED_FLASH   (3)
0070 #define PMA_PMD_LED_MASK    3
0071 /* All LEDs under hardware control */
0072 /* Green and Amber under hardware control, Red off */
0073 #define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
0074 
0075 #define PMA_PMD_SPEED_ENABLE_REG 49192
0076 #define PMA_PMD_100TX_ADV_LBN    1
0077 #define PMA_PMD_100TX_ADV_WIDTH  1
0078 #define PMA_PMD_1000T_ADV_LBN    2
0079 #define PMA_PMD_1000T_ADV_WIDTH  1
0080 #define PMA_PMD_10000T_ADV_LBN   3
0081 #define PMA_PMD_10000T_ADV_WIDTH 1
0082 #define PMA_PMD_SPEED_LBN        4
0083 #define PMA_PMD_SPEED_WIDTH      4
0084 
0085 /* Misc register defines */
0086 #define PCS_CLOCK_CTRL_REG  55297
0087 #define PLL312_RST_N_LBN 2
0088 
0089 #define PCS_SOFT_RST2_REG   55302
0090 #define SERDES_RST_N_LBN 13
0091 #define XGXS_RST_N_LBN 12
0092 
0093 #define PCS_TEST_SELECT_REG 55303   /* PRM 10.5.8 */
0094 #define CLK312_EN_LBN 3
0095 
0096 /* PHYXS registers */
0097 #define PHYXS_XCONTROL_REG  49152
0098 #define PHYXS_RESET_LBN     15
0099 #define PHYXS_RESET_WIDTH   1
0100 
0101 #define PHYXS_TEST1         (49162)
0102 #define LOOPBACK_NEAR_LBN   (8)
0103 #define LOOPBACK_NEAR_WIDTH (1)
0104 
0105 /* Boot status register */
0106 #define PCS_BOOT_STATUS_REG     53248
0107 #define PCS_BOOT_FATAL_ERROR_LBN    0
0108 #define PCS_BOOT_PROGRESS_LBN       1
0109 #define PCS_BOOT_PROGRESS_WIDTH     2
0110 #define PCS_BOOT_PROGRESS_INIT      0
0111 #define PCS_BOOT_PROGRESS_WAIT_MDIO 1
0112 #define PCS_BOOT_PROGRESS_CHECKSUM  2
0113 #define PCS_BOOT_PROGRESS_JUMP      3
0114 #define PCS_BOOT_DOWNLOAD_WAIT_LBN  3
0115 #define PCS_BOOT_CODE_STARTED_LBN   4
0116 
0117 /* 100M/1G PHY registers */
0118 #define GPHY_XCONTROL_REG   49152
0119 #define GPHY_ISOLATE_LBN    10
0120 #define GPHY_ISOLATE_WIDTH  1
0121 #define GPHY_DUPLEX_LBN     8
0122 #define GPHY_DUPLEX_WIDTH   1
0123 #define GPHY_LOOPBACK_NEAR_LBN  14
0124 #define GPHY_LOOPBACK_NEAR_WIDTH 1
0125 
0126 #define C22EXT_STATUS_REG       49153
0127 #define C22EXT_STATUS_LINK_LBN  2
0128 #define C22EXT_STATUS_LINK_WIDTH 1
0129 
0130 #define C22EXT_MSTSLV_CTRL          49161
0131 #define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN  8
0132 #define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN  9
0133 
0134 #define C22EXT_MSTSLV_STATUS            49162
0135 #define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
0136 #define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
0137 
0138 /* Time to wait between powering down the LNPGA and turning off the power
0139  * rails */
0140 #define LNPGA_PDOWN_WAIT    (HZ / 5)
0141 
0142 struct tenxpress_phy_data {
0143     enum ef4_loopback_mode loopback_mode;
0144     enum ef4_phy_mode phy_mode;
0145     int bad_lp_tries;
0146 };
0147 
0148 static int tenxpress_init(struct ef4_nic *efx)
0149 {
0150     /* Enable 312.5 MHz clock */
0151     ef4_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
0152                1 << CLK312_EN_LBN);
0153 
0154     /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
0155     ef4_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
0156               1 << PMA_PMA_LED_ACTIVITY_LBN, true);
0157     ef4_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
0158                SFX7101_PMA_PMD_LED_DEFAULT);
0159 
0160     return 0;
0161 }
0162 
0163 static int tenxpress_phy_probe(struct ef4_nic *efx)
0164 {
0165     struct tenxpress_phy_data *phy_data;
0166 
0167     /* Allocate phy private storage */
0168     phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
0169     if (!phy_data)
0170         return -ENOMEM;
0171     efx->phy_data = phy_data;
0172     phy_data->phy_mode = efx->phy_mode;
0173 
0174     efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
0175     efx->mdio.mode_support = MDIO_SUPPORTS_C45;
0176 
0177     efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
0178 
0179     efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
0180                  ADVERTISED_10000baseT_Full);
0181 
0182     return 0;
0183 }
0184 
0185 static int tenxpress_phy_init(struct ef4_nic *efx)
0186 {
0187     int rc;
0188 
0189     falcon_board(efx)->type->init_phy(efx);
0190 
0191     if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
0192         rc = ef4_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
0193         if (rc < 0)
0194             return rc;
0195 
0196         rc = ef4_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
0197         if (rc < 0)
0198             return rc;
0199     }
0200 
0201     rc = tenxpress_init(efx);
0202     if (rc < 0)
0203         return rc;
0204 
0205     /* Reinitialise flow control settings */
0206     ef4_link_set_wanted_fc(efx, efx->wanted_fc);
0207     ef4_mdio_an_reconfigure(efx);
0208 
0209     schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
0210 
0211     /* Let XGXS and SerDes out of reset */
0212     falcon_reset_xaui(efx);
0213 
0214     return 0;
0215 }
0216 
0217 /* Perform a "special software reset" on the PHY. The caller is
0218  * responsible for saving and restoring the PHY hardware registers
0219  * properly, and masking/unmasking LASI */
0220 static int tenxpress_special_reset(struct ef4_nic *efx)
0221 {
0222     int rc, reg;
0223 
0224     /* The XGMAC clock is driven from the SFX7101 312MHz clock, so
0225      * a special software reset can glitch the XGMAC sufficiently for stats
0226      * requests to fail. */
0227     falcon_stop_nic_stats(efx);
0228 
0229     /* Initiate reset */
0230     reg = ef4_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
0231     reg |= (1 << PMA_PMD_EXT_SSR_LBN);
0232     ef4_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
0233 
0234     mdelay(200);
0235 
0236     /* Wait for the blocks to come out of reset */
0237     rc = ef4_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
0238     if (rc < 0)
0239         goto out;
0240 
0241     /* Try and reconfigure the device */
0242     rc = tenxpress_init(efx);
0243     if (rc < 0)
0244         goto out;
0245 
0246     /* Wait for the XGXS state machine to churn */
0247     mdelay(10);
0248 out:
0249     falcon_start_nic_stats(efx);
0250     return rc;
0251 }
0252 
0253 static void sfx7101_check_bad_lp(struct ef4_nic *efx, bool link_ok)
0254 {
0255     struct tenxpress_phy_data *pd = efx->phy_data;
0256     bool bad_lp;
0257     int reg;
0258 
0259     if (link_ok) {
0260         bad_lp = false;
0261     } else {
0262         /* Check that AN has started but not completed. */
0263         reg = ef4_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
0264         if (!(reg & MDIO_AN_STAT1_LPABLE))
0265             return; /* LP status is unknown */
0266         bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
0267         if (bad_lp)
0268             pd->bad_lp_tries++;
0269     }
0270 
0271     /* Nothing to do if all is well and was previously so. */
0272     if (!pd->bad_lp_tries)
0273         return;
0274 
0275     /* Use the RX (red) LED as an error indicator once we've seen AN
0276      * failure several times in a row, and also log a message. */
0277     if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
0278         reg = ef4_mdio_read(efx, MDIO_MMD_PMAPMD,
0279                     PMA_PMD_LED_OVERR_REG);
0280         reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
0281         if (!bad_lp) {
0282             reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
0283         } else {
0284             reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN;
0285             netif_err(efx, link, efx->net_dev,
0286                   "appears to be plugged into a port"
0287                   " that is not 10GBASE-T capable. The PHY"
0288                   " supports 10GBASE-T ONLY, so no link can"
0289                   " be established\n");
0290         }
0291         ef4_mdio_write(efx, MDIO_MMD_PMAPMD,
0292                    PMA_PMD_LED_OVERR_REG, reg);
0293         pd->bad_lp_tries = bad_lp;
0294     }
0295 }
0296 
0297 static bool sfx7101_link_ok(struct ef4_nic *efx)
0298 {
0299     return ef4_mdio_links_ok(efx,
0300                  MDIO_DEVS_PMAPMD |
0301                  MDIO_DEVS_PCS |
0302                  MDIO_DEVS_PHYXS);
0303 }
0304 
0305 static void tenxpress_ext_loopback(struct ef4_nic *efx)
0306 {
0307     ef4_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
0308               1 << LOOPBACK_NEAR_LBN,
0309               efx->loopback_mode == LOOPBACK_PHYXS);
0310 }
0311 
0312 static void tenxpress_low_power(struct ef4_nic *efx)
0313 {
0314     ef4_mdio_set_mmds_lpower(
0315         efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
0316         TENXPRESS_REQUIRED_DEVS);
0317 }
0318 
0319 static int tenxpress_phy_reconfigure(struct ef4_nic *efx)
0320 {
0321     struct tenxpress_phy_data *phy_data = efx->phy_data;
0322     bool phy_mode_change, loop_reset;
0323 
0324     if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
0325         phy_data->phy_mode = efx->phy_mode;
0326         return 0;
0327     }
0328 
0329     phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
0330                phy_data->phy_mode != PHY_MODE_NORMAL);
0331     loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
0332               LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
0333 
0334     if (loop_reset || phy_mode_change) {
0335         tenxpress_special_reset(efx);
0336         falcon_reset_xaui(efx);
0337     }
0338 
0339     tenxpress_low_power(efx);
0340     ef4_mdio_transmit_disable(efx);
0341     ef4_mdio_phy_reconfigure(efx);
0342     tenxpress_ext_loopback(efx);
0343     ef4_mdio_an_reconfigure(efx);
0344 
0345     phy_data->loopback_mode = efx->loopback_mode;
0346     phy_data->phy_mode = efx->phy_mode;
0347 
0348     return 0;
0349 }
0350 
0351 /* Poll for link state changes */
0352 static bool tenxpress_phy_poll(struct ef4_nic *efx)
0353 {
0354     struct ef4_link_state old_state = efx->link_state;
0355 
0356     efx->link_state.up = sfx7101_link_ok(efx);
0357     efx->link_state.speed = 10000;
0358     efx->link_state.fd = true;
0359     efx->link_state.fc = ef4_mdio_get_pause(efx);
0360 
0361     sfx7101_check_bad_lp(efx, efx->link_state.up);
0362 
0363     return !ef4_link_state_equal(&efx->link_state, &old_state);
0364 }
0365 
0366 static void sfx7101_phy_fini(struct ef4_nic *efx)
0367 {
0368     int reg;
0369 
0370     /* Power down the LNPGA */
0371     reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
0372     ef4_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
0373 
0374     /* Waiting here ensures that the board fini, which can turn
0375      * off the power to the PHY, won't get run until the LNPGA
0376      * powerdown has been given long enough to complete. */
0377     schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
0378 }
0379 
0380 static void tenxpress_phy_remove(struct ef4_nic *efx)
0381 {
0382     kfree(efx->phy_data);
0383     efx->phy_data = NULL;
0384 }
0385 
0386 
0387 /* Override the RX, TX and link LEDs */
0388 void tenxpress_set_id_led(struct ef4_nic *efx, enum ef4_led_mode mode)
0389 {
0390     int reg;
0391 
0392     switch (mode) {
0393     case EF4_LED_OFF:
0394         reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
0395             (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
0396             (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
0397         break;
0398     case EF4_LED_ON:
0399         reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
0400             (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
0401             (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
0402         break;
0403     default:
0404         reg = SFX7101_PMA_PMD_LED_DEFAULT;
0405         break;
0406     }
0407 
0408     ef4_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
0409 }
0410 
0411 static const char *const sfx7101_test_names[] = {
0412     "bist"
0413 };
0414 
0415 static const char *sfx7101_test_name(struct ef4_nic *efx, unsigned int index)
0416 {
0417     if (index < ARRAY_SIZE(sfx7101_test_names))
0418         return sfx7101_test_names[index];
0419     return NULL;
0420 }
0421 
0422 static int
0423 sfx7101_run_tests(struct ef4_nic *efx, int *results, unsigned flags)
0424 {
0425     int rc;
0426 
0427     if (!(flags & ETH_TEST_FL_OFFLINE))
0428         return 0;
0429 
0430     /* BIST is automatically run after a special software reset */
0431     rc = tenxpress_special_reset(efx);
0432     results[0] = rc ? -1 : 1;
0433 
0434     ef4_mdio_an_reconfigure(efx);
0435 
0436     return rc;
0437 }
0438 
0439 static void
0440 tenxpress_get_link_ksettings(struct ef4_nic *efx,
0441                  struct ethtool_link_ksettings *cmd)
0442 {
0443     u32 adv = 0, lpa = 0;
0444     int reg;
0445 
0446     reg = ef4_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
0447     if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
0448         adv |= ADVERTISED_10000baseT_Full;
0449     reg = ef4_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
0450     if (reg & MDIO_AN_10GBT_STAT_LP10G)
0451         lpa |= ADVERTISED_10000baseT_Full;
0452 
0453     mdio45_ethtool_ksettings_get_npage(&efx->mdio, cmd, adv, lpa);
0454 
0455     /* In loopback, the PHY automatically brings up the correct interface,
0456      * but doesn't advertise the correct speed. So override it */
0457     if (LOOPBACK_EXTERNAL(efx))
0458         cmd->base.speed = SPEED_10000;
0459 }
0460 
0461 static int
0462 tenxpress_set_link_ksettings(struct ef4_nic *efx,
0463                  const struct ethtool_link_ksettings *cmd)
0464 {
0465     if (!cmd->base.autoneg)
0466         return -EINVAL;
0467 
0468     return ef4_mdio_set_link_ksettings(efx, cmd);
0469 }
0470 
0471 static void sfx7101_set_npage_adv(struct ef4_nic *efx, u32 advertising)
0472 {
0473     ef4_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
0474               MDIO_AN_10GBT_CTRL_ADV10G,
0475               advertising & ADVERTISED_10000baseT_Full);
0476 }
0477 
0478 const struct ef4_phy_operations falcon_sfx7101_phy_ops = {
0479     .probe        = tenxpress_phy_probe,
0480     .init             = tenxpress_phy_init,
0481     .reconfigure      = tenxpress_phy_reconfigure,
0482     .poll             = tenxpress_phy_poll,
0483     .fini             = sfx7101_phy_fini,
0484     .remove       = tenxpress_phy_remove,
0485     .get_link_ksettings = tenxpress_get_link_ksettings,
0486     .set_link_ksettings = tenxpress_set_link_ksettings,
0487     .set_npage_adv    = sfx7101_set_npage_adv,
0488     .test_alive   = ef4_mdio_test_alive,
0489     .test_name    = sfx7101_test_name,
0490     .run_tests    = sfx7101_run_tests,
0491 };