2 * Copyright(c) 2015, 2016 Intel Corporation.
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
24 * - Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * - Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
30 * - Neither the name of Intel Corporation nor the names of its
31 * contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 void get_platform_config(struct hfi1_devdata
*dd
)
54 unsigned long size
= 0;
55 u8
*temp_platform_config
= NULL
;
57 ret
= read_hfi1_efi_var(dd
, "configuration", &size
,
58 (void **)&temp_platform_config
);
61 "%s: Failed to get platform config from UEFI, falling back to request firmware\n",
63 /* fall back to request firmware */
64 platform_config_load
= 1;
68 dd
->platform_config
.data
= temp_platform_config
;
69 dd
->platform_config
.size
= size
;
75 void free_platform_config(struct hfi1_devdata
*dd
)
77 if (!platform_config_load
) {
79 * was loaded from EFI, release memory
80 * allocated by read_efi_var
82 kfree(dd
->platform_config
.data
);
85 * else do nothing, dispose_firmware will release
86 * struct firmware platform_config on driver exit
90 void get_port_type(struct hfi1_pportdata
*ppd
)
94 ret
= get_platform_config_field(ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
95 PORT_TABLE_PORT_TYPE
, &ppd
->port_type
,
98 ppd
->port_type
= PORT_TYPE_UNKNOWN
;
101 int set_qsfp_tx(struct hfi1_pportdata
*ppd
, int on
)
103 u8 tx_ctrl_byte
= on
? 0x0 : 0xF;
106 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
, QSFP_TX_CTRL_BYTE_OFFS
,
108 /* we expected 1, so consider 0 an error */
116 static int qual_power(struct hfi1_pportdata
*ppd
)
118 u32 cable_power_class
= 0, power_class_max
= 0;
119 u8
*cache
= ppd
->qsfp_info
.cache
;
122 ret
= get_platform_config_field(
123 ppd
->dd
, PLATFORM_CONFIG_SYSTEM_TABLE
, 0,
124 SYSTEM_TABLE_QSFP_POWER_CLASS_MAX
, &power_class_max
, 4);
128 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
130 if (cable_power_class
> power_class_max
)
131 ppd
->offline_disabled_reason
=
132 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY
);
134 if (ppd
->offline_disabled_reason
==
135 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY
)) {
138 "%s: Port disabled due to system power restrictions\n",
145 static int qual_bitrate(struct hfi1_pportdata
*ppd
)
147 u16 lss
= ppd
->link_speed_supported
, lse
= ppd
->link_speed_enabled
;
148 u8
*cache
= ppd
->qsfp_info
.cache
;
150 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
) &&
151 cache
[QSFP_NOM_BIT_RATE_250_OFFS
] < 0x64)
152 ppd
->offline_disabled_reason
=
153 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
);
155 if ((lss
& OPA_LINK_SPEED_12_5G
) && (lse
& OPA_LINK_SPEED_12_5G
) &&
156 cache
[QSFP_NOM_BIT_RATE_100_OFFS
] < 0x7D)
157 ppd
->offline_disabled_reason
=
158 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
);
160 if (ppd
->offline_disabled_reason
==
161 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
)) {
164 "%s: Cable failed bitrate check, disabling port\n",
171 static int set_qsfp_high_power(struct hfi1_pportdata
*ppd
)
173 u8 cable_power_class
= 0, power_ctrl_byte
= 0;
174 u8
*cache
= ppd
->qsfp_info
.cache
;
177 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
179 if (cable_power_class
> QSFP_POWER_CLASS_1
) {
180 power_ctrl_byte
= cache
[QSFP_PWR_CTRL_BYTE_OFFS
];
182 power_ctrl_byte
|= 1;
183 power_ctrl_byte
&= ~(0x2);
185 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
,
186 QSFP_PWR_CTRL_BYTE_OFFS
,
187 &power_ctrl_byte
, 1);
191 if (cable_power_class
> QSFP_POWER_CLASS_4
) {
192 power_ctrl_byte
|= (1 << 2);
193 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
,
194 QSFP_PWR_CTRL_BYTE_OFFS
,
195 &power_ctrl_byte
, 1);
200 /* SFF 8679 rev 1.7 LPMode Deassert time */
206 static void apply_rx_cdr(struct hfi1_pportdata
*ppd
,
211 u8
*cache
= ppd
->qsfp_info
.cache
;
212 int cable_power_class
;
214 if (!((cache
[QSFP_MOD_PWR_OFFS
] & 0x4) &&
215 (cache
[QSFP_CDR_INFO_OFFS
] & 0x40)))
218 /* RX CDR present, bypass supported */
219 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
221 if (cable_power_class
<= QSFP_POWER_CLASS_3
) {
222 /* Power class <= 3, ignore config & turn RX CDR on */
223 *cdr_ctrl_byte
|= 0xF;
227 get_platform_config_field(
228 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
229 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_CDR_APPLY
,
235 "%s: RX_CDR_APPLY is set to disabled\n",
239 get_platform_config_field(
240 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
241 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_CDR
,
244 /* Expand cdr setting to all 4 lanes */
245 rx_preset
= (rx_preset
| (rx_preset
<< 1) |
246 (rx_preset
<< 2) | (rx_preset
<< 3));
249 *cdr_ctrl_byte
|= rx_preset
;
251 *cdr_ctrl_byte
&= rx_preset
;
252 /* Preserve current TX CDR status */
253 *cdr_ctrl_byte
|= (cache
[QSFP_CDR_CTRL_BYTE_OFFS
] & 0xF0);
257 static void apply_tx_cdr(struct hfi1_pportdata
*ppd
,
262 u8
*cache
= ppd
->qsfp_info
.cache
;
263 int cable_power_class
;
265 if (!((cache
[QSFP_MOD_PWR_OFFS
] & 0x8) &&
266 (cache
[QSFP_CDR_INFO_OFFS
] & 0x80)))
269 /* TX CDR present, bypass supported */
270 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
272 if (cable_power_class
<= QSFP_POWER_CLASS_3
) {
273 /* Power class <= 3, ignore config & turn TX CDR on */
274 *cdr_ctrl_byte
|= 0xF0;
278 get_platform_config_field(
280 PLATFORM_CONFIG_TX_PRESET_TABLE
, tx_preset_index
,
281 TX_PRESET_TABLE_QSFP_TX_CDR_APPLY
, &tx_preset
, 4);
286 "%s: TX_CDR_APPLY is set to disabled\n",
290 get_platform_config_field(
292 PLATFORM_CONFIG_TX_PRESET_TABLE
,
294 TX_PRESET_TABLE_QSFP_TX_CDR
, &tx_preset
, 4);
296 /* Expand cdr setting to all 4 lanes */
297 tx_preset
= (tx_preset
| (tx_preset
<< 1) |
298 (tx_preset
<< 2) | (tx_preset
<< 3));
301 *cdr_ctrl_byte
|= (tx_preset
<< 4);
303 /* Preserve current/determined RX CDR status */
304 *cdr_ctrl_byte
&= ((tx_preset
<< 4) | 0xF);
307 static void apply_cdr_settings(
308 struct hfi1_pportdata
*ppd
, u32 rx_preset_index
,
311 u8
*cache
= ppd
->qsfp_info
.cache
;
312 u8 cdr_ctrl_byte
= cache
[QSFP_CDR_CTRL_BYTE_OFFS
];
314 apply_rx_cdr(ppd
, rx_preset_index
, &cdr_ctrl_byte
);
316 apply_tx_cdr(ppd
, tx_preset_index
, &cdr_ctrl_byte
);
318 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, QSFP_CDR_CTRL_BYTE_OFFS
,
322 static void apply_tx_eq_auto(struct hfi1_pportdata
*ppd
)
324 u8
*cache
= ppd
->qsfp_info
.cache
;
327 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x8))
329 /* Disable adaptive TX EQ if present */
330 tx_eq
= cache
[(128 * 3) + 241];
332 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 241, &tx_eq
, 1);
335 static void apply_tx_eq_prog(struct hfi1_pportdata
*ppd
, u32 tx_preset_index
)
337 u8
*cache
= ppd
->qsfp_info
.cache
;
341 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x4))
344 get_platform_config_field(
345 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
346 tx_preset_index
, TX_PRESET_TABLE_QSFP_TX_EQ_APPLY
,
351 "%s: TX_EQ_APPLY is set to disabled\n",
355 get_platform_config_field(
356 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
357 tx_preset_index
, TX_PRESET_TABLE_QSFP_TX_EQ
,
360 if (((cache
[(128 * 3) + 224] & 0xF0) >> 4) < tx_preset
) {
363 "%s: TX EQ %x unsupported\n",
364 __func__
, tx_preset
);
368 "%s: Applying EQ %x\n",
369 __func__
, cache
[608] & 0xF0);
371 tx_preset
= (cache
[608] & 0xF0) >> 4;
374 tx_eq
= tx_preset
| (tx_preset
<< 4);
375 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 234, &tx_eq
, 1);
376 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 235, &tx_eq
, 1);
379 static void apply_rx_eq_emp(struct hfi1_pportdata
*ppd
, u32 rx_preset_index
)
382 u8 rx_eq
, *cache
= ppd
->qsfp_info
.cache
;
384 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x2))
386 get_platform_config_field(
387 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
388 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_EMP_APPLY
,
394 "%s: RX_EMP_APPLY is set to disabled\n",
398 get_platform_config_field(
399 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
400 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_EMP
,
403 if ((cache
[(128 * 3) + 224] & 0xF) < rx_preset
) {
406 "%s: Requested RX EMP %x\n",
407 __func__
, rx_preset
);
411 "%s: Applying supported EMP %x\n",
412 __func__
, cache
[608] & 0xF);
414 rx_preset
= cache
[608] & 0xF;
417 rx_eq
= rx_preset
| (rx_preset
<< 4);
419 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 236, &rx_eq
, 1);
420 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 237, &rx_eq
, 1);
423 static void apply_eq_settings(struct hfi1_pportdata
*ppd
,
424 u32 rx_preset_index
, u32 tx_preset_index
)
426 u8
*cache
= ppd
->qsfp_info
.cache
;
428 /* no point going on w/o a page 3 */
431 "%s: Upper page 03 not present\n",
436 apply_tx_eq_auto(ppd
);
438 apply_tx_eq_prog(ppd
, tx_preset_index
);
440 apply_rx_eq_emp(ppd
, rx_preset_index
);
443 static void apply_rx_amplitude_settings(
444 struct hfi1_pportdata
*ppd
, u32 rx_preset_index
,
448 u8 rx_amp
= 0, i
= 0, preferred
= 0, *cache
= ppd
->qsfp_info
.cache
;
450 /* no point going on w/o a page 3 */
453 "%s: Upper page 03 not present\n",
457 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x1)) {
459 "%s: RX_AMP_APPLY is set to disabled\n",
464 get_platform_config_field(ppd
->dd
,
465 PLATFORM_CONFIG_RX_PRESET_TABLE
,
467 RX_PRESET_TABLE_QSFP_RX_AMP_APPLY
,
472 "%s: RX_AMP_APPLY is set to disabled\n",
476 get_platform_config_field(ppd
->dd
,
477 PLATFORM_CONFIG_RX_PRESET_TABLE
,
479 RX_PRESET_TABLE_QSFP_RX_AMP
,
483 "%s: Requested RX AMP %x\n",
487 for (i
= 0; i
< 4; i
++) {
488 if (cache
[(128 * 3) + 225] & (1 << i
)) {
490 if (preferred
== rx_preset
)
496 * Verify that preferred RX amplitude is not just a
497 * fall through of the default
499 if (!preferred
&& !(cache
[(128 * 3) + 225] & 0x1)) {
500 dd_dev_info(ppd
->dd
, "No supported RX AMP, not applying\n");
505 "%s: Applying RX AMP %x\n", __func__
, preferred
);
507 rx_amp
= preferred
| (preferred
<< 4);
508 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 238, &rx_amp
, 1);
509 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 239, &rx_amp
, 1);
512 #define OPA_INVALID_INDEX 0xFFF
514 static void apply_tx_lanes(struct hfi1_pportdata
*ppd
, u8 field_id
,
515 u32 config_data
, const char *message
)
518 int ret
= HCMD_SUCCESS
;
520 for (i
= 0; i
< 4; i
++) {
521 ret
= load_8051_config(ppd
->dd
, field_id
, i
, config_data
);
522 if (ret
!= HCMD_SUCCESS
) {
525 "%s: %s for lane %u failed\n",
526 message
, __func__
, i
);
531 static void apply_tunings(
532 struct hfi1_pportdata
*ppd
, u32 tx_preset_index
,
533 u8 tuning_method
, u32 total_atten
, u8 limiting_active
)
536 u32 config_data
= 0, tx_preset
= 0;
537 u8 precur
= 0, attn
= 0, postcur
= 0, external_device_config
= 0;
538 u8
*cache
= ppd
->qsfp_info
.cache
;
540 /* Pass tuning method to 8051 */
541 read_8051_config(ppd
->dd
, LINK_TUNING_PARAMETERS
, GENERAL_CONFIG
,
543 config_data
&= ~(0xff << TUNING_METHOD_SHIFT
);
544 config_data
|= ((u32
)tuning_method
<< TUNING_METHOD_SHIFT
);
545 ret
= load_8051_config(ppd
->dd
, LINK_TUNING_PARAMETERS
, GENERAL_CONFIG
,
547 if (ret
!= HCMD_SUCCESS
)
548 dd_dev_err(ppd
->dd
, "%s: Failed to set tuning method\n",
551 /* Set same channel loss for both TX and RX */
552 config_data
= 0 | (total_atten
<< 16) | (total_atten
<< 24);
553 apply_tx_lanes(ppd
, CHANNEL_LOSS_SETTINGS
, config_data
,
554 "Setting channel loss");
556 /* Inform 8051 of cable capabilities */
557 if (ppd
->qsfp_info
.cache_valid
) {
558 external_device_config
=
559 ((cache
[QSFP_MOD_PWR_OFFS
] & 0x4) << 3) |
560 ((cache
[QSFP_MOD_PWR_OFFS
] & 0x8) << 2) |
561 ((cache
[QSFP_EQ_INFO_OFFS
] & 0x2) << 1) |
562 (cache
[QSFP_EQ_INFO_OFFS
] & 0x4);
563 ret
= read_8051_config(ppd
->dd
, DC_HOST_COMM_SETTINGS
,
564 GENERAL_CONFIG
, &config_data
);
565 /* Clear, then set the external device config field */
566 config_data
&= ~(u32
)0xFF;
567 config_data
|= external_device_config
;
568 ret
= load_8051_config(ppd
->dd
, DC_HOST_COMM_SETTINGS
,
569 GENERAL_CONFIG
, config_data
);
570 if (ret
!= HCMD_SUCCESS
)
572 "%s: Failed set ext device config params\n",
576 if (tx_preset_index
== OPA_INVALID_INDEX
) {
577 if (ppd
->port_type
== PORT_TYPE_QSFP
&& limiting_active
)
578 dd_dev_info(ppd
->dd
, "%s: Invalid Tx preset index\n",
583 /* Following for limiting active channels only */
584 get_platform_config_field(
585 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
, tx_preset_index
,
586 TX_PRESET_TABLE_PRECUR
, &tx_preset
, 4);
589 get_platform_config_field(
590 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
591 tx_preset_index
, TX_PRESET_TABLE_ATTN
, &tx_preset
, 4);
594 get_platform_config_field(
595 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
596 tx_preset_index
, TX_PRESET_TABLE_POSTCUR
, &tx_preset
, 4);
599 config_data
= precur
| (attn
<< 8) | (postcur
<< 16);
601 apply_tx_lanes(ppd
, TX_EQ_SETTINGS
, config_data
,
602 "Applying TX settings");
605 /* Must be holding the QSFP i2c resource */
606 static int tune_active_qsfp(struct hfi1_pportdata
*ppd
, u32
*ptr_tx_preset
,
607 u32
*ptr_rx_preset
, u32
*ptr_total_atten
)
610 u16 lss
= ppd
->link_speed_supported
, lse
= ppd
->link_speed_enabled
;
611 u8
*cache
= ppd
->qsfp_info
.cache
;
613 ppd
->qsfp_info
.limiting_active
= 1;
615 ret
= set_qsfp_tx(ppd
, 0);
619 ret
= qual_power(ppd
);
623 ret
= qual_bitrate(ppd
);
628 * We'll change the QSFP memory contents from here on out, thus we set a
629 * flag here to remind ourselves to reset the QSFP module. This prevents
630 * reuse of stale settings established in our previous pass through.
632 if (ppd
->qsfp_info
.reset_needed
) {
634 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
636 ppd
->qsfp_info
.reset_needed
= 1;
639 ret
= set_qsfp_high_power(ppd
);
643 if (cache
[QSFP_EQ_INFO_OFFS
] & 0x4) {
644 ret
= get_platform_config_field(
646 PLATFORM_CONFIG_PORT_TABLE
, 0,
647 PORT_TABLE_TX_PRESET_IDX_ACTIVE_EQ
,
650 *ptr_tx_preset
= OPA_INVALID_INDEX
;
654 ret
= get_platform_config_field(
656 PLATFORM_CONFIG_PORT_TABLE
, 0,
657 PORT_TABLE_TX_PRESET_IDX_ACTIVE_NO_EQ
,
660 *ptr_tx_preset
= OPA_INVALID_INDEX
;
665 ret
= get_platform_config_field(
666 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
667 PORT_TABLE_RX_PRESET_IDX
, ptr_rx_preset
, 4);
669 *ptr_rx_preset
= OPA_INVALID_INDEX
;
673 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
))
674 get_platform_config_field(
675 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
676 PORT_TABLE_LOCAL_ATTEN_25G
, ptr_total_atten
, 4);
677 else if ((lss
& OPA_LINK_SPEED_12_5G
) && (lse
& OPA_LINK_SPEED_12_5G
))
678 get_platform_config_field(
679 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
680 PORT_TABLE_LOCAL_ATTEN_12G
, ptr_total_atten
, 4);
682 apply_cdr_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
684 apply_eq_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
686 apply_rx_amplitude_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
688 ret
= set_qsfp_tx(ppd
, 1);
693 static int tune_qsfp(struct hfi1_pportdata
*ppd
,
694 u32
*ptr_tx_preset
, u32
*ptr_rx_preset
,
695 u8
*ptr_tuning_method
, u32
*ptr_total_atten
)
697 u32 cable_atten
= 0, remote_atten
= 0, platform_atten
= 0;
698 u16 lss
= ppd
->link_speed_supported
, lse
= ppd
->link_speed_enabled
;
700 u8
*cache
= ppd
->qsfp_info
.cache
;
702 switch ((cache
[QSFP_MOD_TECH_OFFS
] & 0xF0) >> 4) {
704 ret
= get_platform_config_field(
706 PLATFORM_CONFIG_PORT_TABLE
, 0,
707 PORT_TABLE_LOCAL_ATTEN_25G
,
712 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
))
713 cable_atten
= cache
[QSFP_CU_ATTEN_12G_OFFS
];
714 else if ((lss
& OPA_LINK_SPEED_12_5G
) &&
715 (lse
& OPA_LINK_SPEED_12_5G
))
716 cable_atten
= cache
[QSFP_CU_ATTEN_7G_OFFS
];
718 /* Fallback to configured attenuation if cable memory is bad */
719 if (cable_atten
== 0 || cable_atten
> 36) {
720 ret
= get_platform_config_field(
722 PLATFORM_CONFIG_SYSTEM_TABLE
, 0,
723 SYSTEM_TABLE_QSFP_ATTENUATION_DEFAULT_25G
,
729 ret
= get_platform_config_field(
730 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
731 PORT_TABLE_REMOTE_ATTEN_25G
, &remote_atten
, 4);
735 *ptr_total_atten
= platform_atten
+ cable_atten
+ remote_atten
;
737 *ptr_tuning_method
= OPA_PASSIVE_TUNING
;
739 case 0x0 ... 0x9: /* fallthrough */
740 case 0xC: /* fallthrough */
742 ret
= tune_active_qsfp(ppd
, ptr_tx_preset
, ptr_rx_preset
,
747 *ptr_tuning_method
= OPA_ACTIVE_TUNING
;
749 case 0xD: /* fallthrough */
752 dd_dev_info(ppd
->dd
, "%s: Unknown/unsupported cable\n",
760 * This function communicates its success or failure via ppd->driver_link_ready
761 * Thus, it depends on its association with start_link(...) which checks
762 * driver_link_ready before proceeding with the link negotiation and
763 * initialization process.
765 void tune_serdes(struct hfi1_pportdata
*ppd
)
769 u32 remote_atten
= 0, platform_atten
= 0;
770 u32 rx_preset_index
, tx_preset_index
;
771 u8 tuning_method
= 0, limiting_active
= 0;
772 struct hfi1_devdata
*dd
= ppd
->dd
;
774 rx_preset_index
= OPA_INVALID_INDEX
;
775 tx_preset_index
= OPA_INVALID_INDEX
;
777 /* the link defaults to enabled */
778 ppd
->link_enabled
= 1;
779 /* the driver link ready state defaults to not ready */
780 ppd
->driver_link_ready
= 0;
781 ppd
->offline_disabled_reason
= HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE
);
783 /* Skip the tuning for testing (loopback != none) and simulations */
784 if (loopback
!= LOOPBACK_NONE
||
785 ppd
->dd
->icode
== ICODE_FUNCTIONAL_SIMULATOR
) {
786 ppd
->driver_link_ready
= 1;
790 switch (ppd
->port_type
) {
791 case PORT_TYPE_DISCONNECTED
:
792 ppd
->offline_disabled_reason
=
793 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_DISCONNECTED
);
794 dd_dev_info(dd
, "%s: Port disconnected, disabling port\n",
797 case PORT_TYPE_FIXED
:
798 /* platform_atten, remote_atten pre-zeroed to catch error */
799 get_platform_config_field(
800 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
801 PORT_TABLE_LOCAL_ATTEN_25G
, &platform_atten
, 4);
803 get_platform_config_field(
804 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
805 PORT_TABLE_REMOTE_ATTEN_25G
, &remote_atten
, 4);
807 total_atten
= platform_atten
+ remote_atten
;
809 tuning_method
= OPA_PASSIVE_TUNING
;
811 case PORT_TYPE_VARIABLE
:
812 if (qsfp_mod_present(ppd
)) {
814 * platform_atten, remote_atten pre-zeroed to
817 get_platform_config_field(
818 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
819 PORT_TABLE_LOCAL_ATTEN_25G
,
822 get_platform_config_field(
823 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
824 PORT_TABLE_REMOTE_ATTEN_25G
,
827 total_atten
= platform_atten
+ remote_atten
;
829 tuning_method
= OPA_PASSIVE_TUNING
;
831 ppd
->offline_disabled_reason
=
832 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_CHASSIS_CONFIG
);
837 if (qsfp_mod_present(ppd
)) {
838 ret
= acquire_chip_resource(ppd
->dd
,
839 qsfp_resource(ppd
->dd
),
842 dd_dev_err(ppd
->dd
, "%s: hfi%d: cannot lock i2c chain\n",
843 __func__
, (int)ppd
->dd
->hfi1_id
);
846 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
848 if (ppd
->qsfp_info
.cache_valid
) {
856 * We may have modified the QSFP memory, so
857 * update the cache to reflect the changes
859 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
861 ppd
->qsfp_info
.limiting_active
;
864 "%s: Reading QSFP memory failed\n",
866 ret
= -EINVAL
; /* a fail indication */
868 release_chip_resource(ppd
->dd
, qsfp_resource(ppd
->dd
));
872 ppd
->offline_disabled_reason
=
874 OPA_LINKDOWN_REASON_LOCAL_MEDIA_NOT_INSTALLED
);
879 dd_dev_info(ppd
->dd
, "%s: Unknown port type\n", __func__
);
880 ppd
->port_type
= PORT_TYPE_UNKNOWN
;
881 tuning_method
= OPA_UNKNOWN_TUNING
;
884 tx_preset_index
= OPA_INVALID_INDEX
;
888 if (ppd
->offline_disabled_reason
==
889 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE
))
890 apply_tunings(ppd
, tx_preset_index
, tuning_method
,
891 total_atten
, limiting_active
);
894 ppd
->driver_link_ready
= 1;
898 ppd
->driver_link_ready
= 0;