linux/drivers/net/sfc/falcon_boards.c
<<
>>
Prefs
   1/****************************************************************************
   2 * Driver for Solarflare Solarstorm network controllers and boards
   3 * Copyright 2007-2010 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/rtnetlink.h>
  11
  12#include "net_driver.h"
  13#include "phy.h"
  14#include "efx.h"
  15#include "nic.h"
  16#include "workarounds.h"
  17
  18/* Macros for unpacking the board revision */
  19/* The revision info is in host byte order. */
  20#define FALCON_BOARD_TYPE(_rev) (_rev >> 8)
  21#define FALCON_BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
  22#define FALCON_BOARD_MINOR(_rev) (_rev & 0xf)
  23
  24/* Board types */
  25#define FALCON_BOARD_SFE4001 0x01
  26#define FALCON_BOARD_SFE4002 0x02
  27#define FALCON_BOARD_SFE4003 0x03
  28#define FALCON_BOARD_SFN4112F 0x52
  29
  30/* Board temperature is about 15°C above ambient when air flow is
  31 * limited.  The maximum acceptable ambient temperature varies
  32 * depending on the PHY specifications but the critical temperature
  33 * above which we should shut down to avoid damage is 80°C. */
  34#define FALCON_BOARD_TEMP_BIAS  15
  35#define FALCON_BOARD_TEMP_CRIT  (80 + FALCON_BOARD_TEMP_BIAS)
  36
  37/* SFC4000 datasheet says: 'The maximum permitted junction temperature
  38 * is 125°C; the thermal design of the environment for the SFC4000
  39 * should aim to keep this well below 100°C.' */
  40#define FALCON_JUNC_TEMP_MIN    0
  41#define FALCON_JUNC_TEMP_MAX    90
  42#define FALCON_JUNC_TEMP_CRIT   125
  43
  44/*****************************************************************************
  45 * Support for LM87 sensor chip used on several boards
  46 */
  47#define LM87_REG_TEMP_HW_INT_LOCK       0x13
  48#define LM87_REG_TEMP_HW_EXT_LOCK       0x14
  49#define LM87_REG_TEMP_HW_INT            0x17
  50#define LM87_REG_TEMP_HW_EXT            0x18
  51#define LM87_REG_TEMP_EXT1              0x26
  52#define LM87_REG_TEMP_INT               0x27
  53#define LM87_REG_ALARMS1                0x41
  54#define LM87_REG_ALARMS2                0x42
  55#define LM87_IN_LIMITS(nr, _min, _max)                  \
  56        0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
  57#define LM87_AIN_LIMITS(nr, _min, _max)                 \
  58        0x3B + (nr), _max, 0x1A + (nr), _min
  59#define LM87_TEMP_INT_LIMITS(_min, _max)                \
  60        0x39, _max, 0x3A, _min
  61#define LM87_TEMP_EXT1_LIMITS(_min, _max)               \
  62        0x37, _max, 0x38, _min
  63
  64#define LM87_ALARM_TEMP_INT             0x10
  65#define LM87_ALARM_TEMP_EXT1            0x20
  66
  67#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
  68
  69static int efx_poke_lm87(struct i2c_client *client, const u8 *reg_values)
  70{
  71        while (*reg_values) {
  72                u8 reg = *reg_values++;
  73                u8 value = *reg_values++;
  74                int rc = i2c_smbus_write_byte_data(client, reg, value);
  75                if (rc)
  76                        return rc;
  77        }
  78        return 0;
  79}
  80
  81static const u8 falcon_lm87_common_regs[] = {
  82        LM87_REG_TEMP_HW_INT_LOCK, FALCON_BOARD_TEMP_CRIT,
  83        LM87_REG_TEMP_HW_INT, FALCON_BOARD_TEMP_CRIT,
  84        LM87_TEMP_EXT1_LIMITS(FALCON_JUNC_TEMP_MIN, FALCON_JUNC_TEMP_MAX),
  85        LM87_REG_TEMP_HW_EXT_LOCK, FALCON_JUNC_TEMP_CRIT,
  86        LM87_REG_TEMP_HW_EXT, FALCON_JUNC_TEMP_CRIT,
  87        0
  88};
  89
  90static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
  91                         const u8 *reg_values)
  92{
  93        struct falcon_board *board = falcon_board(efx);
  94        struct i2c_client *client = i2c_new_device(&board->i2c_adap, info);
  95        int rc;
  96
  97        if (!client)
  98                return -EIO;
  99
 100        /* Read-to-clear alarm/interrupt status */
 101        i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
 102        i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
 103
 104        rc = efx_poke_lm87(client, reg_values);
 105        if (rc)
 106                goto err;
 107        rc = efx_poke_lm87(client, falcon_lm87_common_regs);
 108        if (rc)
 109                goto err;
 110
 111        board->hwmon_client = client;
 112        return 0;
 113
 114err:
 115        i2c_unregister_device(client);
 116        return rc;
 117}
 118
 119static void efx_fini_lm87(struct efx_nic *efx)
 120{
 121        i2c_unregister_device(falcon_board(efx)->hwmon_client);
 122}
 123
 124static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
 125{
 126        struct i2c_client *client = falcon_board(efx)->hwmon_client;
 127        bool temp_crit, elec_fault, is_failure;
 128        u16 alarms;
 129        s32 reg;
 130
 131        /* If link is up then do not monitor temperature */
 132        if (EFX_WORKAROUND_7884(efx) && efx->link_state.up)
 133                return 0;
 134
 135        reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
 136        if (reg < 0)
 137                return reg;
 138        alarms = reg;
 139        reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
 140        if (reg < 0)
 141                return reg;
 142        alarms |= reg << 8;
 143        alarms &= mask;
 144
 145        temp_crit = false;
 146        if (alarms & LM87_ALARM_TEMP_INT) {
 147                reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_INT);
 148                if (reg < 0)
 149                        return reg;
 150                if (reg > FALCON_BOARD_TEMP_CRIT)
 151                        temp_crit = true;
 152        }
 153        if (alarms & LM87_ALARM_TEMP_EXT1) {
 154                reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_EXT1);
 155                if (reg < 0)
 156                        return reg;
 157                if (reg > FALCON_JUNC_TEMP_CRIT)
 158                        temp_crit = true;
 159        }
 160        elec_fault = alarms & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1);
 161        is_failure = temp_crit || elec_fault;
 162
 163        if (alarms)
 164                netif_err(efx, hw, efx->net_dev,
 165                          "LM87 detected a hardware %s (status %02x:%02x)"
 166                          "%s%s%s%s\n",
 167                          is_failure ? "failure" : "problem",
 168                          alarms & 0xff, alarms >> 8,
 169                          (alarms & LM87_ALARM_TEMP_INT) ?
 170                          "; board is overheating" : "",
 171                          (alarms & LM87_ALARM_TEMP_EXT1) ?
 172                          "; controller is overheating" : "",
 173                          temp_crit ? "; reached critical temperature" : "",
 174                          elec_fault ? "; electrical fault" : "");
 175
 176        return is_failure ? -ERANGE : 0;
 177}
 178
 179#else /* !CONFIG_SENSORS_LM87 */
 180
 181static inline int
 182efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
 183              const u8 *reg_values)
 184{
 185        return 0;
 186}
 187static inline void efx_fini_lm87(struct efx_nic *efx)
 188{
 189}
 190static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
 191{
 192        return 0;
 193}
 194
 195#endif /* CONFIG_SENSORS_LM87 */
 196
 197/*****************************************************************************
 198 * Support for the SFE4001 NIC.
 199 *
 200 * The SFE4001 does not power-up fully at reset due to its high power
 201 * consumption.  We control its power via a PCA9539 I/O expander.
 202 * It also has a MAX6647 temperature monitor which we expose to
 203 * the lm90 driver.
 204 *
 205 * This also provides minimal support for reflashing the PHY, which is
 206 * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
 207 * On SFE4001 rev A2 and later this is connected to the 3V3X output of
 208 * the IO-expander.
 209 * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
 210 * exclusive with the network device being open.
 211 */
 212
 213/**************************************************************************
 214 * Support for I2C IO Expander device on SFE4001
 215 */
 216#define PCA9539 0x74
 217
 218#define P0_IN 0x00
 219#define P0_OUT 0x02
 220#define P0_INVERT 0x04
 221#define P0_CONFIG 0x06
 222
 223#define P0_EN_1V0X_LBN 0
 224#define P0_EN_1V0X_WIDTH 1
 225#define P0_EN_1V2_LBN 1
 226#define P0_EN_1V2_WIDTH 1
 227#define P0_EN_2V5_LBN 2
 228#define P0_EN_2V5_WIDTH 1
 229#define P0_EN_3V3X_LBN 3
 230#define P0_EN_3V3X_WIDTH 1
 231#define P0_EN_5V_LBN 4
 232#define P0_EN_5V_WIDTH 1
 233#define P0_SHORTEN_JTAG_LBN 5
 234#define P0_SHORTEN_JTAG_WIDTH 1
 235#define P0_X_TRST_LBN 6
 236#define P0_X_TRST_WIDTH 1
 237#define P0_DSP_RESET_LBN 7
 238#define P0_DSP_RESET_WIDTH 1
 239
 240#define P1_IN 0x01
 241#define P1_OUT 0x03
 242#define P1_INVERT 0x05
 243#define P1_CONFIG 0x07
 244
 245#define P1_AFE_PWD_LBN 0
 246#define P1_AFE_PWD_WIDTH 1
 247#define P1_DSP_PWD25_LBN 1
 248#define P1_DSP_PWD25_WIDTH 1
 249#define P1_RESERVED_LBN 2
 250#define P1_RESERVED_WIDTH 2
 251#define P1_SPARE_LBN 4
 252#define P1_SPARE_WIDTH 4
 253
 254/* Temperature Sensor */
 255#define MAX664X_REG_RSL         0x02
 256#define MAX664X_REG_WLHO        0x0B
 257
 258static void sfe4001_poweroff(struct efx_nic *efx)
 259{
 260        struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
 261        struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
 262
 263        /* Turn off all power rails and disable outputs */
 264        i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
 265        i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff);
 266        i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
 267
 268        /* Clear any over-temperature alert */
 269        i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
 270}
 271
 272static int sfe4001_poweron(struct efx_nic *efx)
 273{
 274        struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
 275        struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
 276        unsigned int i, j;
 277        int rc;
 278        u8 out;
 279
 280        /* Clear any previous over-temperature alert */
 281        rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
 282        if (rc < 0)
 283                return rc;
 284
 285        /* Enable port 0 and port 1 outputs on IO expander */
 286        rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
 287        if (rc)
 288                return rc;
 289        rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
 290                                       0xff & ~(1 << P1_SPARE_LBN));
 291        if (rc)
 292                goto fail_on;
 293
 294        /* If PHY power is on, turn it all off and wait 1 second to
 295         * ensure a full reset.
 296         */
 297        rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
 298        if (rc < 0)
 299                goto fail_on;
 300        out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
 301                       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
 302                       (0 << P0_EN_1V0X_LBN));
 303        if (rc != out) {
 304                netif_info(efx, hw, efx->net_dev, "power-cycling PHY\n");
 305                rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 306                if (rc)
 307                        goto fail_on;
 308                schedule_timeout_uninterruptible(HZ);
 309        }
 310
 311        for (i = 0; i < 20; ++i) {
 312                /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
 313                out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
 314                               (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
 315                               (1 << P0_X_TRST_LBN));
 316                if (efx->phy_mode & PHY_MODE_SPECIAL)
 317                        out |= 1 << P0_EN_3V3X_LBN;
 318
 319                rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 320                if (rc)
 321                        goto fail_on;
 322                msleep(10);
 323
 324                /* Turn on 1V power rail */
 325                out &= ~(1 << P0_EN_1V0X_LBN);
 326                rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 327                if (rc)
 328                        goto fail_on;
 329
 330                netif_info(efx, hw, efx->net_dev,
 331                           "waiting for DSP boot (attempt %d)...\n", i);
 332
 333                /* In flash config mode, DSP does not turn on AFE, so
 334                 * just wait 1 second.
 335                 */
 336                if (efx->phy_mode & PHY_MODE_SPECIAL) {
 337                        schedule_timeout_uninterruptible(HZ);
 338                        return 0;
 339                }
 340
 341                for (j = 0; j < 10; ++j) {
 342                        msleep(100);
 343
 344                        /* Check DSP has asserted AFE power line */
 345                        rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
 346                        if (rc < 0)
 347                                goto fail_on;
 348                        if (rc & (1 << P1_AFE_PWD_LBN))
 349                                return 0;
 350                }
 351        }
 352
 353        netif_info(efx, hw, efx->net_dev, "timed out waiting for DSP boot\n");
 354        rc = -ETIMEDOUT;
 355fail_on:
 356        sfe4001_poweroff(efx);
 357        return rc;
 358}
 359
 360static ssize_t show_phy_flash_cfg(struct device *dev,
 361                                  struct device_attribute *attr, char *buf)
 362{
 363        struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 364        return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
 365}
 366
 367static ssize_t set_phy_flash_cfg(struct device *dev,
 368                                 struct device_attribute *attr,
 369                                 const char *buf, size_t count)
 370{
 371        struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 372        enum efx_phy_mode old_mode, new_mode;
 373        int err;
 374
 375        rtnl_lock();
 376        old_mode = efx->phy_mode;
 377        if (count == 0 || *buf == '0')
 378                new_mode = old_mode & ~PHY_MODE_SPECIAL;
 379        else
 380                new_mode = PHY_MODE_SPECIAL;
 381        if (!((old_mode ^ new_mode) & PHY_MODE_SPECIAL)) {
 382                err = 0;
 383        } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
 384                err = -EBUSY;
 385        } else {
 386                /* Reset the PHY, reconfigure the MAC and enable/disable
 387                 * MAC stats accordingly. */
 388                efx->phy_mode = new_mode;
 389                if (new_mode & PHY_MODE_SPECIAL)
 390                        falcon_stop_nic_stats(efx);
 391                err = sfe4001_poweron(efx);
 392                if (!err)
 393                        err = efx_reconfigure_port(efx);
 394                if (!(new_mode & PHY_MODE_SPECIAL))
 395                        falcon_start_nic_stats(efx);
 396        }
 397        rtnl_unlock();
 398
 399        return err ? err : count;
 400}
 401
 402static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
 403
 404static void sfe4001_fini(struct efx_nic *efx)
 405{
 406        struct falcon_board *board = falcon_board(efx);
 407
 408        netif_info(efx, drv, efx->net_dev, "%s\n", __func__);
 409
 410        device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 411        sfe4001_poweroff(efx);
 412        i2c_unregister_device(board->ioexp_client);
 413        i2c_unregister_device(board->hwmon_client);
 414}
 415
 416static int sfe4001_check_hw(struct efx_nic *efx)
 417{
 418        struct falcon_nic_data *nic_data = efx->nic_data;
 419        s32 status;
 420
 421        /* If XAUI link is up then do not monitor */
 422        if (EFX_WORKAROUND_7884(efx) && !nic_data->xmac_poll_required)
 423                return 0;
 424
 425        /* Check the powered status of the PHY. Lack of power implies that
 426         * the MAX6647 has shut down power to it, probably due to a temp.
 427         * alarm. Reading the power status rather than the MAX6647 status
 428         * directly because the later is read-to-clear and would thus
 429         * start to power up the PHY again when polled, causing us to blip
 430         * the power undesirably.
 431         * We know we can read from the IO expander because we did
 432         * it during power-on. Assume failure now is bad news. */
 433        status = i2c_smbus_read_byte_data(falcon_board(efx)->ioexp_client, P1_IN);
 434        if (status >= 0 &&
 435            (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
 436                return 0;
 437
 438        /* Use board power control, not PHY power control */
 439        sfe4001_poweroff(efx);
 440        efx->phy_mode = PHY_MODE_OFF;
 441
 442        return (status < 0) ? -EIO : -ERANGE;
 443}
 444
 445static struct i2c_board_info sfe4001_hwmon_info = {
 446        I2C_BOARD_INFO("max6647", 0x4e),
 447};
 448
 449/* This board uses an I2C expander to provider power to the PHY, which needs to
 450 * be turned on before the PHY can be used.
 451 * Context: Process context, rtnl lock held
 452 */
 453static int sfe4001_init(struct efx_nic *efx)
 454{
 455        struct falcon_board *board = falcon_board(efx);
 456        int rc;
 457
 458#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
 459        board->hwmon_client =
 460                i2c_new_device(&board->i2c_adap, &sfe4001_hwmon_info);
 461#else
 462        board->hwmon_client =
 463                i2c_new_dummy(&board->i2c_adap, sfe4001_hwmon_info.addr);
 464#endif
 465        if (!board->hwmon_client)
 466                return -EIO;
 467
 468        /* Raise board/PHY high limit from 85 to 90 degrees Celsius */
 469        rc = i2c_smbus_write_byte_data(board->hwmon_client,
 470                                       MAX664X_REG_WLHO, 90);
 471        if (rc)
 472                goto fail_hwmon;
 473
 474        board->ioexp_client = i2c_new_dummy(&board->i2c_adap, PCA9539);
 475        if (!board->ioexp_client) {
 476                rc = -EIO;
 477                goto fail_hwmon;
 478        }
 479
 480        if (efx->phy_mode & PHY_MODE_SPECIAL) {
 481                /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
 482                 * will fail. */
 483                falcon_stop_nic_stats(efx);
 484        }
 485        rc = sfe4001_poweron(efx);
 486        if (rc)
 487                goto fail_ioexp;
 488
 489        rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 490        if (rc)
 491                goto fail_on;
 492
 493        netif_info(efx, hw, efx->net_dev, "PHY is powered on\n");
 494        return 0;
 495
 496fail_on:
 497        sfe4001_poweroff(efx);
 498fail_ioexp:
 499        i2c_unregister_device(board->ioexp_client);
 500fail_hwmon:
 501        i2c_unregister_device(board->hwmon_client);
 502        return rc;
 503}
 504
 505/*****************************************************************************
 506 * Support for the SFE4002
 507 *
 508 */
 509static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
 510
 511static const u8 sfe4002_lm87_regs[] = {
 512        LM87_IN_LIMITS(0, 0x7c, 0x99),          /* 2.5V:  1.8V +/- 10% */
 513        LM87_IN_LIMITS(1, 0x4c, 0x5e),          /* Vccp1: 1.2V +/- 10% */
 514        LM87_IN_LIMITS(2, 0xac, 0xd4),          /* 3.3V:  3.3V +/- 10% */
 515        LM87_IN_LIMITS(3, 0xac, 0xd4),          /* 5V:    5.0V +/- 10% */
 516        LM87_IN_LIMITS(4, 0xac, 0xe0),          /* 12V:   10.8-14V */
 517        LM87_IN_LIMITS(5, 0x3f, 0x4f),          /* Vccp2: 1.0V +/- 10% */
 518        LM87_AIN_LIMITS(0, 0x98, 0xbb),         /* AIN1:  1.66V +/- 10% */
 519        LM87_AIN_LIMITS(1, 0x8a, 0xa9),         /* AIN2:  1.5V +/- 10% */
 520        LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS),
 521        LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
 522        0
 523};
 524
 525static struct i2c_board_info sfe4002_hwmon_info = {
 526        I2C_BOARD_INFO("lm87", 0x2e),
 527        .platform_data  = &sfe4002_lm87_channel,
 528};
 529
 530/****************************************************************************/
 531/* LED allocations. Note that on rev A0 boards the schematic and the reality
 532 * differ: red and green are swapped. Below is the fixed (A1) layout (there
 533 * are only 3 A0 boards in existence, so no real reason to make this
 534 * conditional).
 535 */
 536#define SFE4002_FAULT_LED (2)   /* Red */
 537#define SFE4002_RX_LED    (0)   /* Green */
 538#define SFE4002_TX_LED    (1)   /* Amber */
 539
 540static void sfe4002_init_phy(struct efx_nic *efx)
 541{
 542        /* Set the TX and RX LEDs to reflect status and activity, and the
 543         * fault LED off */
 544        falcon_qt202x_set_led(efx, SFE4002_TX_LED,
 545                              QUAKE_LED_TXLINK | QUAKE_LED_LINK_ACTSTAT);
 546        falcon_qt202x_set_led(efx, SFE4002_RX_LED,
 547                              QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
 548        falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
 549}
 550
 551static void sfe4002_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 552{
 553        falcon_qt202x_set_led(
 554                efx, SFE4002_FAULT_LED,
 555                (mode == EFX_LED_ON) ? QUAKE_LED_ON : QUAKE_LED_OFF);
 556}
 557
 558static int sfe4002_check_hw(struct efx_nic *efx)
 559{
 560        struct falcon_board *board = falcon_board(efx);
 561
 562        /* A0 board rev. 4002s report a temperature fault the whole time
 563         * (bad sensor) so we mask it out. */
 564        unsigned alarm_mask =
 565                (board->major == 0 && board->minor == 0) ?
 566                ~LM87_ALARM_TEMP_EXT1 : ~0;
 567
 568        return efx_check_lm87(efx, alarm_mask);
 569}
 570
 571static int sfe4002_init(struct efx_nic *efx)
 572{
 573        return efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
 574}
 575
 576/*****************************************************************************
 577 * Support for the SFN4112F
 578 *
 579 */
 580static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
 581
 582static const u8 sfn4112f_lm87_regs[] = {
 583        LM87_IN_LIMITS(0, 0x7c, 0x99),          /* 2.5V:  1.8V +/- 10% */
 584        LM87_IN_LIMITS(1, 0x4c, 0x5e),          /* Vccp1: 1.2V +/- 10% */
 585        LM87_IN_LIMITS(2, 0xac, 0xd4),          /* 3.3V:  3.3V +/- 10% */
 586        LM87_IN_LIMITS(4, 0xac, 0xe0),          /* 12V:   10.8-14V */
 587        LM87_IN_LIMITS(5, 0x3f, 0x4f),          /* Vccp2: 1.0V +/- 10% */
 588        LM87_AIN_LIMITS(1, 0x8a, 0xa9),         /* AIN2:  1.5V +/- 10% */
 589        LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS),
 590        LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
 591        0
 592};
 593
 594static struct i2c_board_info sfn4112f_hwmon_info = {
 595        I2C_BOARD_INFO("lm87", 0x2e),
 596        .platform_data  = &sfn4112f_lm87_channel,
 597};
 598
 599#define SFN4112F_ACT_LED        0
 600#define SFN4112F_LINK_LED       1
 601
 602static void sfn4112f_init_phy(struct efx_nic *efx)
 603{
 604        falcon_qt202x_set_led(efx, SFN4112F_ACT_LED,
 605                              QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
 606        falcon_qt202x_set_led(efx, SFN4112F_LINK_LED,
 607                              QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
 608}
 609
 610static void sfn4112f_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 611{
 612        int reg;
 613
 614        switch (mode) {
 615        case EFX_LED_OFF:
 616                reg = QUAKE_LED_OFF;
 617                break;
 618        case EFX_LED_ON:
 619                reg = QUAKE_LED_ON;
 620                break;
 621        default:
 622                reg = QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT;
 623                break;
 624        }
 625
 626        falcon_qt202x_set_led(efx, SFN4112F_LINK_LED, reg);
 627}
 628
 629static int sfn4112f_check_hw(struct efx_nic *efx)
 630{
 631        /* Mask out unused sensors */
 632        return efx_check_lm87(efx, ~0x48);
 633}
 634
 635static int sfn4112f_init(struct efx_nic *efx)
 636{
 637        return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
 638}
 639
 640/*****************************************************************************
 641 * Support for the SFE4003
 642 *
 643 */
 644static u8 sfe4003_lm87_channel = 0x03; /* use AIN not FAN inputs */
 645
 646static const u8 sfe4003_lm87_regs[] = {
 647        LM87_IN_LIMITS(0, 0x67, 0x7f),          /* 2.5V:  1.5V +/- 10% */
 648        LM87_IN_LIMITS(1, 0x4c, 0x5e),          /* Vccp1: 1.2V +/- 10% */
 649        LM87_IN_LIMITS(2, 0xac, 0xd4),          /* 3.3V:  3.3V +/- 10% */
 650        LM87_IN_LIMITS(4, 0xac, 0xe0),          /* 12V:   10.8-14V */
 651        LM87_IN_LIMITS(5, 0x3f, 0x4f),          /* Vccp2: 1.0V +/- 10% */
 652        LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS),
 653        0
 654};
 655
 656static struct i2c_board_info sfe4003_hwmon_info = {
 657        I2C_BOARD_INFO("lm87", 0x2e),
 658        .platform_data  = &sfe4003_lm87_channel,
 659};
 660
 661/* Board-specific LED info. */
 662#define SFE4003_RED_LED_GPIO    11
 663#define SFE4003_LED_ON          1
 664#define SFE4003_LED_OFF         0
 665
 666static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 667{
 668        struct falcon_board *board = falcon_board(efx);
 669
 670        /* The LEDs were not wired to GPIOs before A3 */
 671        if (board->minor < 3 && board->major == 0)
 672                return;
 673
 674        falcon_txc_set_gpio_val(
 675                efx, SFE4003_RED_LED_GPIO,
 676                (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF);
 677}
 678
 679static void sfe4003_init_phy(struct efx_nic *efx)
 680{
 681        struct falcon_board *board = falcon_board(efx);
 682
 683        /* The LEDs were not wired to GPIOs before A3 */
 684        if (board->minor < 3 && board->major == 0)
 685                return;
 686
 687        falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT);
 688        falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF);
 689}
 690
 691static int sfe4003_check_hw(struct efx_nic *efx)
 692{
 693        struct falcon_board *board = falcon_board(efx);
 694
 695        /* A0/A1/A2 board rev. 4003s  report a temperature fault the whole time
 696         * (bad sensor) so we mask it out. */
 697        unsigned alarm_mask =
 698                (board->major == 0 && board->minor <= 2) ?
 699                ~LM87_ALARM_TEMP_EXT1 : ~0;
 700
 701        return efx_check_lm87(efx, alarm_mask);
 702}
 703
 704static int sfe4003_init(struct efx_nic *efx)
 705{
 706        return efx_init_lm87(efx, &sfe4003_hwmon_info, sfe4003_lm87_regs);
 707}
 708
 709static const struct falcon_board_type board_types[] = {
 710        {
 711                .id             = FALCON_BOARD_SFE4001,
 712                .ref_model      = "SFE4001",
 713                .gen_type       = "10GBASE-T adapter",
 714                .init           = sfe4001_init,
 715                .init_phy       = efx_port_dummy_op_void,
 716                .fini           = sfe4001_fini,
 717                .set_id_led     = tenxpress_set_id_led,
 718                .monitor        = sfe4001_check_hw,
 719        },
 720        {
 721                .id             = FALCON_BOARD_SFE4002,
 722                .ref_model      = "SFE4002",
 723                .gen_type       = "XFP adapter",
 724                .init           = sfe4002_init,
 725                .init_phy       = sfe4002_init_phy,
 726                .fini           = efx_fini_lm87,
 727                .set_id_led     = sfe4002_set_id_led,
 728                .monitor        = sfe4002_check_hw,
 729        },
 730        {
 731                .id             = FALCON_BOARD_SFE4003,
 732                .ref_model      = "SFE4003",
 733                .gen_type       = "10GBASE-CX4 adapter",
 734                .init           = sfe4003_init,
 735                .init_phy       = sfe4003_init_phy,
 736                .fini           = efx_fini_lm87,
 737                .set_id_led     = sfe4003_set_id_led,
 738                .monitor        = sfe4003_check_hw,
 739        },
 740        {
 741                .id             = FALCON_BOARD_SFN4112F,
 742                .ref_model      = "SFN4112F",
 743                .gen_type       = "SFP+ adapter",
 744                .init           = sfn4112f_init,
 745                .init_phy       = sfn4112f_init_phy,
 746                .fini           = efx_fini_lm87,
 747                .set_id_led     = sfn4112f_set_id_led,
 748                .monitor        = sfn4112f_check_hw,
 749        },
 750};
 751
 752int falcon_probe_board(struct efx_nic *efx, u16 revision_info)
 753{
 754        struct falcon_board *board = falcon_board(efx);
 755        u8 type_id = FALCON_BOARD_TYPE(revision_info);
 756        int i;
 757
 758        board->major = FALCON_BOARD_MAJOR(revision_info);
 759        board->minor = FALCON_BOARD_MINOR(revision_info);
 760
 761        for (i = 0; i < ARRAY_SIZE(board_types); i++)
 762                if (board_types[i].id == type_id)
 763                        board->type = &board_types[i];
 764
 765        if (board->type) {
 766                netif_info(efx, probe, efx->net_dev, "board is %s rev %c%d\n",
 767                         (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
 768                         ? board->type->ref_model : board->type->gen_type,
 769                         'A' + board->major, board->minor);
 770                return 0;
 771        } else {
 772                netif_err(efx, probe, efx->net_dev, "unknown board type %d\n",
 773                          type_id);
 774                return -ENODEV;
 775        }
 776}
 777