diff options
Diffstat (limited to 'drivers/net/sfc/falcon_boards.c')
-rw-r--r-- | drivers/net/sfc/falcon_boards.c | 203 |
1 files changed, 82 insertions, 121 deletions
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 3d950c2cf205..cfc6a5b5a477 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c | |||
@@ -26,7 +26,7 @@ | |||
26 | /* Board types */ | 26 | /* Board types */ |
27 | #define FALCON_BOARD_SFE4001 0x01 | 27 | #define FALCON_BOARD_SFE4001 0x01 |
28 | #define FALCON_BOARD_SFE4002 0x02 | 28 | #define FALCON_BOARD_SFE4002 0x02 |
29 | #define FALCON_BOARD_SFN4111T 0x51 | 29 | #define FALCON_BOARD_SFE4003 0x03 |
30 | #define FALCON_BOARD_SFN4112F 0x52 | 30 | #define FALCON_BOARD_SFN4112F 0x52 |
31 | 31 | ||
32 | /* Board temperature is about 15°C above ambient when air flow is | 32 | /* Board temperature is about 15°C above ambient when air flow is |
@@ -142,17 +142,17 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask) | |||
142 | #endif /* CONFIG_SENSORS_LM87 */ | 142 | #endif /* CONFIG_SENSORS_LM87 */ |
143 | 143 | ||
144 | /***************************************************************************** | 144 | /***************************************************************************** |
145 | * Support for the SFE4001 and SFN4111T NICs. | 145 | * Support for the SFE4001 NIC. |
146 | * | 146 | * |
147 | * The SFE4001 does not power-up fully at reset due to its high power | 147 | * 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. | 148 | * consumption. We control its power via a PCA9539 I/O expander. |
149 | * Both boards have a MAX6647 temperature monitor which we expose to | 149 | * It also has a MAX6647 temperature monitor which we expose to |
150 | * the lm90 driver. | 150 | * the lm90 driver. |
151 | * | 151 | * |
152 | * This also provides minimal support for reflashing the PHY, which is | 152 | * This also provides minimal support for reflashing the PHY, which is |
153 | * initiated by resetting it with the FLASH_CFG_1 pin pulled down. | 153 | * 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 | 154 | * 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. | 155 | * the IO-expander. |
156 | * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually | 156 | * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually |
157 | * exclusive with the network device being open. | 157 | * exclusive with the network device being open. |
158 | */ | 158 | */ |
@@ -304,34 +304,6 @@ fail_on: | |||
304 | return rc; | 304 | return rc; |
305 | } | 305 | } |
306 | 306 | ||
307 | static 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, ®, FR_AB_GPIO_CTL); | ||
320 | EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true); | ||
321 | efx_writeo(efx, ®, 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, ®, FR_AB_GPIO_CTL); | ||
327 | msleep(1); | ||
328 | |||
329 | i2c_unlock_adapter(&board->i2c_adap); | ||
330 | |||
331 | ssleep(1); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static ssize_t show_phy_flash_cfg(struct device *dev, | 307 | static ssize_t show_phy_flash_cfg(struct device *dev, |
336 | struct device_attribute *attr, char *buf) | 308 | struct device_attribute *attr, char *buf) |
337 | { | 309 | { |
@@ -363,10 +335,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev, | |||
363 | efx->phy_mode = new_mode; | 335 | efx->phy_mode = new_mode; |
364 | if (new_mode & PHY_MODE_SPECIAL) | 336 | if (new_mode & PHY_MODE_SPECIAL) |
365 | falcon_stop_nic_stats(efx); | 337 | falcon_stop_nic_stats(efx); |
366 | if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) | 338 | err = sfe4001_poweron(efx); |
367 | err = sfe4001_poweron(efx); | ||
368 | else | ||
369 | err = sfn4111t_reset(efx); | ||
370 | if (!err) | 339 | if (!err) |
371 | err = efx_reconfigure_port(efx); | 340 | err = efx_reconfigure_port(efx); |
372 | if (!(new_mode & PHY_MODE_SPECIAL)) | 341 | if (!(new_mode & PHY_MODE_SPECIAL)) |
@@ -479,83 +448,6 @@ fail_hwmon: | |||
479 | return rc; | 448 | return rc; |
480 | } | 449 | } |
481 | 450 | ||
482 | static 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 | |||
500 | static 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 | |||
508 | static struct i2c_board_info sfn4111t_a0_hwmon_info = { | ||
509 | I2C_BOARD_INFO("max6647", 0x4e), | ||
510 | }; | ||
511 | |||
512 | static struct i2c_board_info sfn4111t_r5_hwmon_info = { | ||
513 | I2C_BOARD_INFO("max6646", 0x4d), | ||
514 | }; | ||
515 | |||
516 | static 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 | |||
530 | static 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 | |||
554 | fail_hwmon: | ||
555 | i2c_unregister_device(board->hwmon_client); | ||
556 | return rc; | ||
557 | } | ||
558 | |||
559 | /***************************************************************************** | 451 | /***************************************************************************** |
560 | * Support for the SFE4002 | 452 | * Support for the SFE4002 |
561 | * | 453 | * |
@@ -691,6 +583,75 @@ static int sfn4112f_init(struct efx_nic *efx) | |||
691 | return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); | 583 | return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); |
692 | } | 584 | } |
693 | 585 | ||
586 | /***************************************************************************** | ||
587 | * Support for the SFE4003 | ||
588 | * | ||
589 | */ | ||
590 | static u8 sfe4003_lm87_channel = 0x03; /* use AIN not FAN inputs */ | ||
591 | |||
592 | static const u8 sfe4003_lm87_regs[] = { | ||
593 | LM87_IN_LIMITS(0, 0x67, 0x7f), /* 2.5V: 1.5V +/- 10% */ | ||
594 | LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */ | ||
595 | LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */ | ||
596 | LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */ | ||
597 | LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */ | ||
598 | LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS), | ||
599 | 0 | ||
600 | }; | ||
601 | |||
602 | static struct i2c_board_info sfe4003_hwmon_info = { | ||
603 | I2C_BOARD_INFO("lm87", 0x2e), | ||
604 | .platform_data = &sfe4003_lm87_channel, | ||
605 | }; | ||
606 | |||
607 | /* Board-specific LED info. */ | ||
608 | #define SFE4003_RED_LED_GPIO 11 | ||
609 | #define SFE4003_LED_ON 1 | ||
610 | #define SFE4003_LED_OFF 0 | ||
611 | |||
612 | static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) | ||
613 | { | ||
614 | struct falcon_board *board = falcon_board(efx); | ||
615 | |||
616 | /* The LEDs were not wired to GPIOs before A3 */ | ||
617 | if (board->minor < 3 && board->major == 0) | ||
618 | return; | ||
619 | |||
620 | falcon_txc_set_gpio_val( | ||
621 | efx, SFE4003_RED_LED_GPIO, | ||
622 | (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF); | ||
623 | } | ||
624 | |||
625 | static void sfe4003_init_phy(struct efx_nic *efx) | ||
626 | { | ||
627 | struct falcon_board *board = falcon_board(efx); | ||
628 | |||
629 | /* The LEDs were not wired to GPIOs before A3 */ | ||
630 | if (board->minor < 3 && board->major == 0) | ||
631 | return; | ||
632 | |||
633 | falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT); | ||
634 | falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF); | ||
635 | } | ||
636 | |||
637 | static int sfe4003_check_hw(struct efx_nic *efx) | ||
638 | { | ||
639 | struct falcon_board *board = falcon_board(efx); | ||
640 | |||
641 | /* A0/A1/A2 board rev. 4003s report a temperature fault the whole time | ||
642 | * (bad sensor) so we mask it out. */ | ||
643 | unsigned alarm_mask = | ||
644 | (board->major == 0 && board->minor <= 2) ? | ||
645 | ~LM87_ALARM_TEMP_EXT1 : ~0; | ||
646 | |||
647 | return efx_check_lm87(efx, alarm_mask); | ||
648 | } | ||
649 | |||
650 | static int sfe4003_init(struct efx_nic *efx) | ||
651 | { | ||
652 | return efx_init_lm87(efx, &sfe4003_hwmon_info, sfe4003_lm87_regs); | ||
653 | } | ||
654 | |||
694 | static const struct falcon_board_type board_types[] = { | 655 | static const struct falcon_board_type board_types[] = { |
695 | { | 656 | { |
696 | .id = FALCON_BOARD_SFE4001, | 657 | .id = FALCON_BOARD_SFE4001, |
@@ -713,14 +674,14 @@ static const struct falcon_board_type board_types[] = { | |||
713 | .monitor = sfe4002_check_hw, | 674 | .monitor = sfe4002_check_hw, |
714 | }, | 675 | }, |
715 | { | 676 | { |
716 | .id = FALCON_BOARD_SFN4111T, | 677 | .id = FALCON_BOARD_SFE4003, |
717 | .ref_model = "SFN4111T", | 678 | .ref_model = "SFE4003", |
718 | .gen_type = "100/1000/10GBASE-T adapter", | 679 | .gen_type = "10GBASE-CX4 adapter", |
719 | .init = sfn4111t_init, | 680 | .init = sfe4003_init, |
720 | .init_phy = sfn4111t_init_phy, | 681 | .init_phy = sfe4003_init_phy, |
721 | .fini = sfn4111t_fini, | 682 | .fini = efx_fini_lm87, |
722 | .set_id_led = tenxpress_set_id_led, | 683 | .set_id_led = sfe4003_set_id_led, |
723 | .monitor = sfn4111t_check_hw, | 684 | .monitor = sfe4003_check_hw, |
724 | }, | 685 | }, |
725 | { | 686 | { |
726 | .id = FALCON_BOARD_SFN4112F, | 687 | .id = FALCON_BOARD_SFN4112F, |