aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/hfi1/platform.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/hfi1/platform.c b/drivers/infiniband/hw/hfi1/platform.c
index 0e7043801bb1..838fe84e285a 100644
--- a/drivers/infiniband/hw/hfi1/platform.c
+++ b/drivers/infiniband/hw/hfi1/platform.c
@@ -637,6 +637,38 @@ static void apply_tx_lanes(struct hfi1_pportdata *ppd, u8 field_id,
637 } 637 }
638} 638}
639 639
640/*
641 * Return a special SerDes setting for low power AOC cables. The power class
642 * threshold and setting being used were all found by empirical testing.
643 *
644 * Summary of the logic:
645 *
646 * if (QSFP and QSFP_TYPE == AOC and QSFP_POWER_CLASS < 4)
647 * return 0xe
648 * return 0; // leave at default
649 */
650static u8 aoc_low_power_setting(struct hfi1_pportdata *ppd)
651{
652 u8 *cache = ppd->qsfp_info.cache;
653 int power_class;
654
655 /* QSFP only */
656 if (ppd->port_type != PORT_TYPE_QSFP)
657 return 0; /* leave at default */
658
659 /* active optical cables only */
660 switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {
661 case 0x0 ... 0x9: /* fallthrough */
662 case 0xC: /* fallthrough */
663 case 0xE:
664 /* active AOC */
665 power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);
666 if (power_class < QSFP_POWER_CLASS_4)
667 return 0xe;
668 }
669 return 0; /* leave at default */
670}
671
640static void apply_tunings( 672static void apply_tunings(
641 struct hfi1_pportdata *ppd, u32 tx_preset_index, 673 struct hfi1_pportdata *ppd, u32 tx_preset_index,
642 u8 tuning_method, u32 total_atten, u8 limiting_active) 674 u8 tuning_method, u32 total_atten, u8 limiting_active)
@@ -705,7 +737,17 @@ static void apply_tunings(
705 tx_preset_index, TX_PRESET_TABLE_POSTCUR, &tx_preset, 4); 737 tx_preset_index, TX_PRESET_TABLE_POSTCUR, &tx_preset, 4);
706 postcur = tx_preset; 738 postcur = tx_preset;
707 739
708 config_data = precur | (attn << 8) | (postcur << 16); 740 /*
741 * NOTES:
742 * o The aoc_low_power_setting is applied to all lanes even
743 * though only lane 0's value is examined by the firmware.
744 * o A lingering low power setting after a cable swap does
745 * not occur. On cable unplug the 8051 is reset and
746 * restarted on cable insert. This resets all settings to
747 * their default, erasing any previous low power setting.
748 */
749 config_data = precur | (attn << 8) | (postcur << 16) |
750 (aoc_low_power_setting(ppd) << 24);
709 751
710 apply_tx_lanes(ppd, TX_EQ_SETTINGS, config_data, 752 apply_tx_lanes(ppd, TX_EQ_SETTINGS, config_data,
711 "Applying TX settings"); 753 "Applying TX settings");