aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon_boards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/falcon_boards.c')
-rw-r--r--drivers/net/sfc/falcon_boards.c325
1 files changed, 170 insertions, 155 deletions
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index 3d950c2cf205..b9cc846811d6 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -1,6 +1,6 @@
1/**************************************************************************** 1/****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards 2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2007-2009 Solarflare Communications Inc. 3 * Copyright 2007-2010 Solarflare Communications Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 as published
@@ -13,8 +13,6 @@
13#include "phy.h" 13#include "phy.h"
14#include "efx.h" 14#include "efx.h"
15#include "nic.h" 15#include "nic.h"
16#include "regs.h"
17#include "io.h"
18#include "workarounds.h" 16#include "workarounds.h"
19 17
20/* Macros for unpacking the board revision */ 18/* Macros for unpacking the board revision */
@@ -26,21 +24,32 @@
26/* Board types */ 24/* Board types */
27#define FALCON_BOARD_SFE4001 0x01 25#define FALCON_BOARD_SFE4001 0x01
28#define FALCON_BOARD_SFE4002 0x02 26#define FALCON_BOARD_SFE4002 0x02
29#define FALCON_BOARD_SFN4111T 0x51 27#define FALCON_BOARD_SFE4003 0x03
30#define FALCON_BOARD_SFN4112F 0x52 28#define FALCON_BOARD_SFN4112F 0x52
31 29
32/* Board temperature is about 15°C above ambient when air flow is 30/* Board temperature is about 15°C above ambient when air flow is
33 * limited. */ 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 34#define FALCON_BOARD_TEMP_BIAS 15
35#define FALCON_BOARD_TEMP_CRIT (80 + FALCON_BOARD_TEMP_BIAS)
35 36
36/* SFC4000 datasheet says: 'The maximum permitted junction temperature 37/* SFC4000 datasheet says: 'The maximum permitted junction temperature
37 * is 125°C; the thermal design of the environment for the SFC4000 38 * is 125°C; the thermal design of the environment for the SFC4000
38 * should aim to keep this well below 100°C.' */ 39 * should aim to keep this well below 100°C.' */
40#define FALCON_JUNC_TEMP_MIN 0
39#define FALCON_JUNC_TEMP_MAX 90 41#define FALCON_JUNC_TEMP_MAX 90
42#define FALCON_JUNC_TEMP_CRIT 125
40 43
41/***************************************************************************** 44/*****************************************************************************
42 * Support for LM87 sensor chip used on several boards 45 * Support for LM87 sensor chip used on several boards
43 */ 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
44#define LM87_REG_ALARMS1 0x41 53#define LM87_REG_ALARMS1 0x41
45#define LM87_REG_ALARMS2 0x42 54#define LM87_REG_ALARMS2 0x42
46#define LM87_IN_LIMITS(nr, _min, _max) \ 55#define LM87_IN_LIMITS(nr, _min, _max) \
@@ -57,6 +66,27 @@
57 66
58#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE) 67#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
59 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
60static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, 90static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
61 const u8 *reg_values) 91 const u8 *reg_values)
62{ 92{
@@ -67,13 +97,16 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
67 if (!client) 97 if (!client)
68 return -EIO; 98 return -EIO;
69 99
70 while (*reg_values) { 100 /* Read-to-clear alarm/interrupt status */
71 u8 reg = *reg_values++; 101 i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
72 u8 value = *reg_values++; 102 i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
73 rc = i2c_smbus_write_byte_data(client, reg, value); 103
74 if (rc) 104 rc = efx_poke_lm87(client, reg_values);
75 goto err; 105 if (rc)
76 } 106 goto err;
107 rc = efx_poke_lm87(client, falcon_lm87_common_regs);
108 if (rc)
109 goto err;
77 110
78 board->hwmon_client = client; 111 board->hwmon_client = client;
79 return 0; 112 return 0;
@@ -91,36 +124,56 @@ static void efx_fini_lm87(struct efx_nic *efx)
91static int efx_check_lm87(struct efx_nic *efx, unsigned mask) 124static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
92{ 125{
93 struct i2c_client *client = falcon_board(efx)->hwmon_client; 126 struct i2c_client *client = falcon_board(efx)->hwmon_client;
94 s32 alarms1, alarms2; 127 bool temp_crit, elec_fault, is_failure;
128 u16 alarms;
129 s32 reg;
95 130
96 /* If link is up then do not monitor temperature */ 131 /* If link is up then do not monitor temperature */
97 if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) 132 if (EFX_WORKAROUND_7884(efx) && efx->link_state.up)
98 return 0; 133 return 0;
99 134
100 alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); 135 reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
101 alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); 136 if (reg < 0)
102 if (alarms1 < 0) 137 return reg;
103 return alarms1; 138 alarms = reg;
104 if (alarms2 < 0) 139 reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
105 return alarms2; 140 if (reg < 0)
106 alarms1 &= mask; 141 return reg;
107 alarms2 &= mask >> 8; 142 alarms |= reg << 8;
108 if (alarms1 || alarms2) { 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)
109 netif_err(efx, hw, efx->net_dev, 164 netif_err(efx, hw, efx->net_dev,
110 "LM87 detected a hardware failure (status %02x:%02x)" 165 "LM87 detected a hardware %s (status %02x:%02x)"
111 "%s%s%s\n", 166 "%s%s%s%s\n",
112 alarms1, alarms2, 167 is_failure ? "failure" : "problem",
113 (alarms1 & LM87_ALARM_TEMP_INT) ? 168 alarms & 0xff, alarms >> 8,
169 (alarms & LM87_ALARM_TEMP_INT) ?
114 "; board is overheating" : "", 170 "; board is overheating" : "",
115 (alarms1 & LM87_ALARM_TEMP_EXT1) ? 171 (alarms & LM87_ALARM_TEMP_EXT1) ?
116 "; controller is overheating" : "", 172 "; controller is overheating" : "",
117 (alarms1 & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1) 173 temp_crit ? "; reached critical temperature" : "",
118 || alarms2) ? 174 elec_fault ? "; electrical fault" : "");
119 "; electrical fault" : "");
120 return -ERANGE;
121 }
122 175
123 return 0; 176 return is_failure ? -ERANGE : 0;
124} 177}
125 178
126#else /* !CONFIG_SENSORS_LM87 */ 179#else /* !CONFIG_SENSORS_LM87 */
@@ -142,17 +195,17 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
142#endif /* CONFIG_SENSORS_LM87 */ 195#endif /* CONFIG_SENSORS_LM87 */
143 196
144/***************************************************************************** 197/*****************************************************************************
145 * Support for the SFE4001 and SFN4111T NICs. 198 * Support for the SFE4001 NIC.
146 * 199 *
147 * The SFE4001 does not power-up fully at reset due to its high power 200 * The SFE4001 does not power-up fully at reset due to its high power
148 * consumption. We control its power via a PCA9539 I/O expander. 201 * consumption. We control its power via a PCA9539 I/O expander.
149 * Both boards have a MAX6647 temperature monitor which we expose to 202 * It also has a MAX6647 temperature monitor which we expose to
150 * the lm90 driver. 203 * the lm90 driver.
151 * 204 *
152 * This also provides minimal support for reflashing the PHY, which is 205 * This also provides minimal support for reflashing the PHY, which is
153 * initiated by resetting it with the FLASH_CFG_1 pin pulled down. 206 * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
154 * On SFE4001 rev A2 and later this is connected to the 3V3X output of 207 * On SFE4001 rev A2 and later this is connected to the 3V3X output of
155 * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3. 208 * the IO-expander.
156 * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually 209 * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
157 * exclusive with the network device being open. 210 * exclusive with the network device being open.
158 */ 211 */
@@ -304,34 +357,6 @@ fail_on:
304 return rc; 357 return rc;
305} 358}
306 359
307static int sfn4111t_reset(struct efx_nic *efx)
308{
309 struct falcon_board *board = falcon_board(efx);
310 efx_oword_t reg;
311
312 /* GPIO 3 and the GPIO register are shared with I2C, so block that */
313 i2c_lock_adapter(&board->i2c_adap);
314
315 /* Pull RST_N (GPIO 2) low then let it up again, setting the
316 * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
317 * output enables; the output levels should always be 0 (low)
318 * and we rely on external pull-ups. */
319 efx_reado(efx, &reg, FR_AB_GPIO_CTL);
320 EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true);
321 efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
322 msleep(1000);
323 EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false);
324 EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN,
325 !!(efx->phy_mode & PHY_MODE_SPECIAL));
326 efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
327 msleep(1);
328
329 i2c_unlock_adapter(&board->i2c_adap);
330
331 ssleep(1);
332 return 0;
333}
334
335static ssize_t show_phy_flash_cfg(struct device *dev, 360static ssize_t show_phy_flash_cfg(struct device *dev,
336 struct device_attribute *attr, char *buf) 361 struct device_attribute *attr, char *buf)
337{ 362{
@@ -353,7 +378,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
353 new_mode = old_mode & ~PHY_MODE_SPECIAL; 378 new_mode = old_mode & ~PHY_MODE_SPECIAL;
354 else 379 else
355 new_mode = PHY_MODE_SPECIAL; 380 new_mode = PHY_MODE_SPECIAL;
356 if (old_mode == new_mode) { 381 if (!((old_mode ^ new_mode) & PHY_MODE_SPECIAL)) {
357 err = 0; 382 err = 0;
358 } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { 383 } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
359 err = -EBUSY; 384 err = -EBUSY;
@@ -363,10 +388,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
363 efx->phy_mode = new_mode; 388 efx->phy_mode = new_mode;
364 if (new_mode & PHY_MODE_SPECIAL) 389 if (new_mode & PHY_MODE_SPECIAL)
365 falcon_stop_nic_stats(efx); 390 falcon_stop_nic_stats(efx);
366 if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) 391 err = sfe4001_poweron(efx);
367 err = sfe4001_poweron(efx);
368 else
369 err = sfn4111t_reset(efx);
370 if (!err) 392 if (!err)
371 err = efx_reconfigure_port(efx); 393 err = efx_reconfigure_port(efx);
372 if (!(new_mode & PHY_MODE_SPECIAL)) 394 if (!(new_mode & PHY_MODE_SPECIAL))
@@ -393,10 +415,11 @@ static void sfe4001_fini(struct efx_nic *efx)
393 415
394static int sfe4001_check_hw(struct efx_nic *efx) 416static int sfe4001_check_hw(struct efx_nic *efx)
395{ 417{
418 struct falcon_nic_data *nic_data = efx->nic_data;
396 s32 status; 419 s32 status;
397 420
398 /* If XAUI link is up then do not monitor */ 421 /* If XAUI link is up then do not monitor */
399 if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) 422 if (EFX_WORKAROUND_7884(efx) && !nic_data->xmac_poll_required)
400 return 0; 423 return 0;
401 424
402 /* Check the powered status of the PHY. Lack of power implies that 425 /* Check the powered status of the PHY. Lack of power implies that
@@ -479,83 +502,6 @@ fail_hwmon:
479 return rc; 502 return rc;
480} 503}
481 504
482static int sfn4111t_check_hw(struct efx_nic *efx)
483{
484 s32 status;
485
486 /* If XAUI link is up then do not monitor */
487 if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
488 return 0;
489
490 /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
491 status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client,
492 MAX664X_REG_RSL);
493 if (status < 0)
494 return -EIO;
495 if (status & 0x57)
496 return -ERANGE;
497 return 0;
498}
499
500static void sfn4111t_fini(struct efx_nic *efx)
501{
502 netif_info(efx, drv, efx->net_dev, "%s\n", __func__);
503
504 device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
505 i2c_unregister_device(falcon_board(efx)->hwmon_client);
506}
507
508static struct i2c_board_info sfn4111t_a0_hwmon_info = {
509 I2C_BOARD_INFO("max6647", 0x4e),
510};
511
512static struct i2c_board_info sfn4111t_r5_hwmon_info = {
513 I2C_BOARD_INFO("max6646", 0x4d),
514};
515
516static void sfn4111t_init_phy(struct efx_nic *efx)
517{
518 if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
519 if (sft9001_wait_boot(efx) != -EINVAL)
520 return;
521
522 efx->phy_mode = PHY_MODE_SPECIAL;
523 falcon_stop_nic_stats(efx);
524 }
525
526 sfn4111t_reset(efx);
527 sft9001_wait_boot(efx);
528}
529
530static int sfn4111t_init(struct efx_nic *efx)
531{
532 struct falcon_board *board = falcon_board(efx);
533 int rc;
534
535 board->hwmon_client =
536 i2c_new_device(&board->i2c_adap,
537 (board->minor < 5) ?
538 &sfn4111t_a0_hwmon_info :
539 &sfn4111t_r5_hwmon_info);
540 if (!board->hwmon_client)
541 return -EIO;
542
543 rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
544 if (rc)
545 goto fail_hwmon;
546
547 if (efx->phy_mode & PHY_MODE_SPECIAL)
548 /* PHY may not generate a 156.25 MHz clock and MAC
549 * stats fetch will fail. */
550 falcon_stop_nic_stats(efx);
551
552 return 0;
553
554fail_hwmon:
555 i2c_unregister_device(board->hwmon_client);
556 return rc;
557}
558
559/***************************************************************************** 505/*****************************************************************************
560 * Support for the SFE4002 506 * Support for the SFE4002
561 * 507 *
@@ -691,6 +637,75 @@ static int sfn4112f_init(struct efx_nic *efx)
691 return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); 637 return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
692} 638}
693 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
694static const struct falcon_board_type board_types[] = { 709static const struct falcon_board_type board_types[] = {
695 { 710 {
696 .id = FALCON_BOARD_SFE4001, 711 .id = FALCON_BOARD_SFE4001,
@@ -713,14 +728,14 @@ static const struct falcon_board_type board_types[] = {
713 .monitor = sfe4002_check_hw, 728 .monitor = sfe4002_check_hw,
714 }, 729 },
715 { 730 {
716 .id = FALCON_BOARD_SFN4111T, 731 .id = FALCON_BOARD_SFE4003,
717 .ref_model = "SFN4111T", 732 .ref_model = "SFE4003",
718 .gen_type = "100/1000/10GBASE-T adapter", 733 .gen_type = "10GBASE-CX4 adapter",
719 .init = sfn4111t_init, 734 .init = sfe4003_init,
720 .init_phy = sfn4111t_init_phy, 735 .init_phy = sfe4003_init_phy,
721 .fini = sfn4111t_fini, 736 .fini = efx_fini_lm87,
722 .set_id_led = tenxpress_set_id_led, 737 .set_id_led = sfe4003_set_id_led,
723 .monitor = sfn4111t_check_hw, 738 .monitor = sfe4003_check_hw,
724 }, 739 },
725 { 740 {
726 .id = FALCON_BOARD_SFN4112F, 741 .id = FALCON_BOARD_SFN4112F,