linux/drivers/net/ethernet/sfc/tenxpress.c
<<
>>
Prefs
   1/****************************************************************************
   2 * Driver for Solarflare network controllers and boards
   3 * Copyright 2007-2011 Solarflare Communications Inc.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published
   7 * by the Free Software Foundation, incorporated herein by reference.
   8 */
   9
  10#include <linux/delay.h>
  11#include <linux/rtnetlink.h>
  12#include <linux/seq_file.h>
  13#include <linux/slab.h>
  14#include "efx.h"
  15#include "mdio_10g.h"
  16#include "nic.h"
  17#include "phy.h"
  18#include "workarounds.h"
  19
  20/* We expect these MMDs to be in the package. */
  21#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD       | \
  22                                 MDIO_DEVS_PCS          | \
  23                                 MDIO_DEVS_PHYXS        | \
  24                                 MDIO_DEVS_AN)
  25
  26#define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |      \
  27                           (1 << LOOPBACK_PCS) |        \
  28                           (1 << LOOPBACK_PMAPMD) |     \
  29                           (1 << LOOPBACK_PHYXS_WS))
  30
  31/* We complain if we fail to see the link partner as 10G capable this many
  32 * times in a row (must be > 1 as sampling the autoneg. registers is racy)
  33 */
  34#define MAX_BAD_LP_TRIES        (5)
  35
  36/* Extended control register */
  37#define PMA_PMD_XCONTROL_REG    49152
  38#define PMA_PMD_EXT_GMII_EN_LBN 1
  39#define PMA_PMD_EXT_GMII_EN_WIDTH 1
  40#define PMA_PMD_EXT_CLK_OUT_LBN 2
  41#define PMA_PMD_EXT_CLK_OUT_WIDTH 1
  42#define PMA_PMD_LNPGA_POWERDOWN_LBN 8
  43#define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1
  44#define PMA_PMD_EXT_CLK312_WIDTH 1
  45#define PMA_PMD_EXT_LPOWER_LBN  12
  46#define PMA_PMD_EXT_LPOWER_WIDTH 1
  47#define PMA_PMD_EXT_ROBUST_LBN  14
  48#define PMA_PMD_EXT_ROBUST_WIDTH 1
  49#define PMA_PMD_EXT_SSR_LBN     15
  50#define PMA_PMD_EXT_SSR_WIDTH   1
  51
  52/* extended status register */
  53#define PMA_PMD_XSTATUS_REG     49153
  54#define PMA_PMD_XSTAT_MDIX_LBN  14
  55#define PMA_PMD_XSTAT_FLP_LBN   (12)
  56
  57/* LED control register */
  58#define PMA_PMD_LED_CTRL_REG    49159
  59#define PMA_PMA_LED_ACTIVITY_LBN        (3)
  60
  61/* LED function override register */
  62#define PMA_PMD_LED_OVERR_REG   49161
  63/* Bit positions for different LEDs (there are more but not wired on SFE4001)*/
  64#define PMA_PMD_LED_LINK_LBN    (0)
  65#define PMA_PMD_LED_SPEED_LBN   (2)
  66#define PMA_PMD_LED_TX_LBN      (4)
  67#define PMA_PMD_LED_RX_LBN      (6)
  68/* Override settings */
  69#define PMA_PMD_LED_AUTO        (0)     /* H/W control */
  70#define PMA_PMD_LED_ON          (1)
  71#define PMA_PMD_LED_OFF         (2)
  72#define PMA_PMD_LED_FLASH       (3)
  73#define PMA_PMD_LED_MASK        3
  74/* All LEDs under hardware control */
  75/* Green and Amber under hardware control, Red off */
  76#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
  77
  78#define PMA_PMD_SPEED_ENABLE_REG 49192
  79#define PMA_PMD_100TX_ADV_LBN    1
  80#define PMA_PMD_100TX_ADV_WIDTH  1
  81#define PMA_PMD_1000T_ADV_LBN    2
  82#define PMA_PMD_1000T_ADV_WIDTH  1
  83#define PMA_PMD_10000T_ADV_LBN   3
  84#define PMA_PMD_10000T_ADV_WIDTH 1
  85#define PMA_PMD_SPEED_LBN        4
  86#define PMA_PMD_SPEED_WIDTH      4
  87
  88/* Misc register defines */
  89#define PCS_CLOCK_CTRL_REG      55297
  90#define PLL312_RST_N_LBN 2
  91
  92#define PCS_SOFT_RST2_REG       55302
  93#define SERDES_RST_N_LBN 13
  94#define XGXS_RST_N_LBN 12
  95
  96#define PCS_TEST_SELECT_REG     55303   /* PRM 10.5.8 */
  97#define CLK312_EN_LBN 3
  98
  99/* PHYXS registers */
 100#define PHYXS_XCONTROL_REG      49152
 101#define PHYXS_RESET_LBN         15
 102#define PHYXS_RESET_WIDTH       1
 103
 104#define PHYXS_TEST1         (49162)
 105#define LOOPBACK_NEAR_LBN   (8)
 106#define LOOPBACK_NEAR_WIDTH (1)
 107
 108/* Boot status register */
 109#define PCS_BOOT_STATUS_REG             53248
 110#define PCS_BOOT_FATAL_ERROR_LBN        0
 111#define PCS_BOOT_PROGRESS_LBN           1
 112#define PCS_BOOT_PROGRESS_WIDTH         2
 113#define PCS_BOOT_PROGRESS_INIT          0
 114#define PCS_BOOT_PROGRESS_WAIT_MDIO     1
 115#define PCS_BOOT_PROGRESS_CHECKSUM      2
 116#define PCS_BOOT_PROGRESS_JUMP          3
 117#define PCS_BOOT_DOWNLOAD_WAIT_LBN      3
 118#define PCS_BOOT_CODE_STARTED_LBN       4
 119
 120/* 100M/1G PHY registers */
 121#define GPHY_XCONTROL_REG       49152
 122#define GPHY_ISOLATE_LBN        10
 123#define GPHY_ISOLATE_WIDTH      1
 124#define GPHY_DUPLEX_LBN         8
 125#define GPHY_DUPLEX_WIDTH       1
 126#define GPHY_LOOPBACK_NEAR_LBN  14
 127#define GPHY_LOOPBACK_NEAR_WIDTH 1
 128
 129#define C22EXT_STATUS_REG       49153
 130#define C22EXT_STATUS_LINK_LBN  2
 131#define C22EXT_STATUS_LINK_WIDTH 1
 132
 133#define C22EXT_MSTSLV_CTRL                      49161
 134#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN      8
 135#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN      9
 136
 137#define C22EXT_MSTSLV_STATUS                    49162
 138#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN     10
 139#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN     11
 140
 141/* Time to wait between powering down the LNPGA and turning off the power
 142 * rails */
 143#define LNPGA_PDOWN_WAIT        (HZ / 5)
 144
 145struct tenxpress_phy_data {
 146        enum efx_loopback_mode loopback_mode;
 147        enum efx_phy_mode phy_mode;
 148        int bad_lp_tries;
 149};
 150
 151static int tenxpress_init(struct efx_nic *efx)
 152{
 153        /* Enable 312.5 MHz clock */
 154        efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
 155                       1 << CLK312_EN_LBN);
 156
 157        /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
 158        efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
 159                          1 << PMA_PMA_LED_ACTIVITY_LBN, true);
 160        efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
 161                       SFX7101_PMA_PMD_LED_DEFAULT);
 162
 163        return 0;
 164}
 165
 166static int tenxpress_phy_probe(struct efx_nic *efx)
 167{
 168        struct tenxpress_phy_data *phy_data;
 169
 170        /* Allocate phy private storage */
 171        phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
 172        if (!phy_data)
 173                return -ENOMEM;
 174        efx->phy_data = phy_data;
 175        phy_data->phy_mode = efx->phy_mode;
 176
 177        efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS;
 178        efx->mdio.mode_support = MDIO_SUPPORTS_C45;
 179
 180        efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS;
 181
 182        efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg |
 183                                 ADVERTISED_10000baseT_Full);
 184
 185        return 0;
 186}
 187
 188static int tenxpress_phy_init(struct efx_nic *efx)
 189{
 190        int rc;
 191
 192        falcon_board(efx)->type->init_phy(efx);
 193
 194        if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
 195                rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 196                if (rc < 0)
 197                        return rc;
 198
 199                rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 200                if (rc < 0)
 201                        return rc;
 202        }
 203
 204        rc = tenxpress_init(efx);
 205        if (rc < 0)
 206                return rc;
 207
 208        /* Reinitialise flow control settings */
 209        efx_link_set_wanted_fc(efx, efx->wanted_fc);
 210        efx_mdio_an_reconfigure(efx);
 211
 212        schedule_timeout_uninterruptible(HZ / 5); /* 200ms */
 213
 214        /* Let XGXS and SerDes out of reset */
 215        falcon_reset_xaui(efx);
 216
 217        return 0;
 218}
 219
 220/* Perform a "special software reset" on the PHY. The caller is
 221 * responsible for saving and restoring the PHY hardware registers
 222 * properly, and masking/unmasking LASI */
 223static int tenxpress_special_reset(struct efx_nic *efx)
 224{
 225        int rc, reg;
 226
 227        /* The XGMAC clock is driven from the SFX7101 312MHz clock, so
 228         * a special software reset can glitch the XGMAC sufficiently for stats
 229         * requests to fail. */
 230        falcon_stop_nic_stats(efx);
 231
 232        /* Initiate reset */
 233        reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
 234        reg |= (1 << PMA_PMD_EXT_SSR_LBN);
 235        efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 236
 237        mdelay(200);
 238
 239        /* Wait for the blocks to come out of reset */
 240        rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
 241        if (rc < 0)
 242                goto out;
 243
 244        /* Try and reconfigure the device */
 245        rc = tenxpress_init(efx);
 246        if (rc < 0)
 247                goto out;
 248
 249        /* Wait for the XGXS state machine to churn */
 250        mdelay(10);
 251out:
 252        falcon_start_nic_stats(efx);
 253        return rc;
 254}
 255
 256static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 257{
 258        struct tenxpress_phy_data *pd = efx->phy_data;
 259        bool bad_lp;
 260        int reg;
 261
 262        if (link_ok) {
 263                bad_lp = false;
 264        } else {
 265                /* Check that AN has started but not completed. */
 266                reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
 267                if (!(reg & MDIO_AN_STAT1_LPABLE))
 268                        return; /* LP status is unknown */
 269                bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
 270                if (bad_lp)
 271                        pd->bad_lp_tries++;
 272        }
 273
 274        /* Nothing to do if all is well and was previously so. */
 275        if (!pd->bad_lp_tries)
 276                return;
 277
 278        /* Use the RX (red) LED as an error indicator once we've seen AN
 279         * failure several times in a row, and also log a message. */
 280        if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
 281                reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
 282                                    PMA_PMD_LED_OVERR_REG);
 283                reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
 284                if (!bad_lp) {
 285                        reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
 286                } else {
 287                        reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN;
 288                        netif_err(efx, link, efx->net_dev,
 289                                  "appears to be plugged into a port"
 290                                  " that is not 10GBASE-T capable. The PHY"
 291                                  " supports 10GBASE-T ONLY, so no link can"
 292                                  " be established\n");
 293                }
 294                efx_mdio_write(efx, MDIO_MMD_PMAPMD,
 295                               PMA_PMD_LED_OVERR_REG, reg);
 296                pd->bad_lp_tries = bad_lp;
 297        }
 298}
 299
 300static bool sfx7101_link_ok(struct efx_nic *efx)
 301{
 302        return efx_mdio_links_ok(efx,
 303                                 MDIO_DEVS_PMAPMD |
 304                                 MDIO_DEVS_PCS |
 305                                 MDIO_DEVS_PHYXS);
 306}
 307
 308static void tenxpress_ext_loopback(struct efx_nic *efx)
 309{
 310        efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
 311                          1 << LOOPBACK_NEAR_LBN,
 312                          efx->loopback_mode == LOOPBACK_PHYXS);
 313}
 314
 315static void tenxpress_low_power(struct efx_nic *efx)
 316{
 317        efx_mdio_set_mmds_lpower(
 318                efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
 319                TENXPRESS_REQUIRED_DEVS);
 320}
 321
 322static int tenxpress_phy_reconfigure(struct efx_nic *efx)
 323{
 324        struct tenxpress_phy_data *phy_data = efx->phy_data;
 325        bool phy_mode_change, loop_reset;
 326
 327        if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
 328                phy_data->phy_mode = efx->phy_mode;
 329                return 0;
 330        }
 331
 332        phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
 333                           phy_data->phy_mode != PHY_MODE_NORMAL);
 334        loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, LOOPBACKS_EXTERNAL(efx)) ||
 335                      LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
 336
 337        if (loop_reset || phy_mode_change) {
 338                tenxpress_special_reset(efx);
 339                falcon_reset_xaui(efx);
 340        }
 341
 342        tenxpress_low_power(efx);
 343        efx_mdio_transmit_disable(efx);
 344        efx_mdio_phy_reconfigure(efx);
 345        tenxpress_ext_loopback(efx);
 346        efx_mdio_an_reconfigure(efx);
 347
 348        phy_data->loopback_mode = efx->loopback_mode;
 349        phy_data->phy_mode = efx->phy_mode;
 350
 351        return 0;
 352}
 353
 354static void
 355tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
 356
 357/* Poll for link state changes */
 358static bool tenxpress_phy_poll(struct efx_nic *efx)
 359{
 360        struct efx_link_state old_state = efx->link_state;
 361
 362        efx->link_state.up = sfx7101_link_ok(efx);
 363        efx->link_state.speed = 10000;
 364        efx->link_state.fd = true;
 365        efx->link_state.fc = efx_mdio_get_pause(efx);
 366
 367        sfx7101_check_bad_lp(efx, efx->link_state.up);
 368
 369        return !efx_link_state_equal(&efx->link_state, &old_state);
 370}
 371
 372static void sfx7101_phy_fini(struct efx_nic *efx)
 373{
 374        int reg;
 375
 376        /* Power down the LNPGA */
 377        reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
 378        efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 379
 380        /* Waiting here ensures that the board fini, which can turn
 381         * off the power to the PHY, won't get run until the LNPGA
 382         * powerdown has been given long enough to complete. */
 383        schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */
 384}
 385
 386static void tenxpress_phy_remove(struct efx_nic *efx)
 387{
 388        kfree(efx->phy_data);
 389        efx->phy_data = NULL;
 390}
 391
 392
 393/* Override the RX, TX and link LEDs */
 394void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 395{
 396        int reg;
 397
 398        switch (mode) {
 399        case EFX_LED_OFF:
 400                reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
 401                        (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
 402                        (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
 403                break;
 404        case EFX_LED_ON:
 405                reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
 406                        (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
 407                        (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
 408                break;
 409        default:
 410                reg = SFX7101_PMA_PMD_LED_DEFAULT;
 411                break;
 412        }
 413
 414        efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
 415}
 416
 417static const char *const sfx7101_test_names[] = {
 418        "bist"
 419};
 420
 421static const char *sfx7101_test_name(struct efx_nic *efx, unsigned int index)
 422{
 423        if (index < ARRAY_SIZE(sfx7101_test_names))
 424                return sfx7101_test_names[index];
 425        return NULL;
 426}
 427
 428static int
 429sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 430{
 431        int rc;
 432
 433        if (!(flags & ETH_TEST_FL_OFFLINE))
 434                return 0;
 435
 436        /* BIST is automatically run after a special software reset */
 437        rc = tenxpress_special_reset(efx);
 438        results[0] = rc ? -1 : 1;
 439
 440        efx_mdio_an_reconfigure(efx);
 441
 442        return rc;
 443}
 444
 445static void
 446tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 447{
 448        u32 adv = 0, lpa = 0;
 449        int reg;
 450
 451        reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
 452        if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
 453                adv |= ADVERTISED_10000baseT_Full;
 454        reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
 455        if (reg & MDIO_AN_10GBT_STAT_LP10G)
 456                lpa |= ADVERTISED_10000baseT_Full;
 457
 458        mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
 459
 460        /* In loopback, the PHY automatically brings up the correct interface,
 461         * but doesn't advertise the correct speed. So override it */
 462        if (LOOPBACK_EXTERNAL(efx))
 463                ethtool_cmd_speed_set(ecmd, SPEED_10000);
 464}
 465
 466static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 467{
 468        if (!ecmd->autoneg)
 469                return -EINVAL;
 470
 471        return efx_mdio_set_settings(efx, ecmd);
 472}
 473
 474static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
 475{
 476        efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
 477                          MDIO_AN_10GBT_CTRL_ADV10G,
 478                          advertising & ADVERTISED_10000baseT_Full);
 479}
 480
 481const struct efx_phy_operations falcon_sfx7101_phy_ops = {
 482        .probe            = tenxpress_phy_probe,
 483        .init             = tenxpress_phy_init,
 484        .reconfigure      = tenxpress_phy_reconfigure,
 485        .poll             = tenxpress_phy_poll,
 486        .fini             = sfx7101_phy_fini,
 487        .remove           = tenxpress_phy_remove,
 488        .get_settings     = tenxpress_get_settings,
 489        .set_settings     = tenxpress_set_settings,
 490        .set_npage_adv    = sfx7101_set_npage_adv,
 491        .test_alive       = efx_mdio_test_alive,
 492        .test_name        = sfx7101_test_name,
 493        .run_tests        = sfx7101_run_tests,
 494};
 495