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 int set_qsfp_tx(struct hfi1_pportdata
*ppd
, int on
)
92 u8 tx_ctrl_byte
= on
? 0x0 : 0xF;
95 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
, QSFP_TX_CTRL_BYTE_OFFS
,
97 /* we expected 1, so consider 0 an error */
105 static int qual_power(struct hfi1_pportdata
*ppd
)
107 u32 cable_power_class
= 0, power_class_max
= 0;
108 u8
*cache
= ppd
->qsfp_info
.cache
;
111 ret
= get_platform_config_field(
112 ppd
->dd
, PLATFORM_CONFIG_SYSTEM_TABLE
, 0,
113 SYSTEM_TABLE_QSFP_POWER_CLASS_MAX
, &power_class_max
, 4);
117 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
119 if (cable_power_class
> power_class_max
)
120 ppd
->offline_disabled_reason
=
121 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY
);
123 if (ppd
->offline_disabled_reason
==
124 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY
)) {
127 "%s: Port disabled due to system power restrictions\n",
134 static int qual_bitrate(struct hfi1_pportdata
*ppd
)
136 u16 lss
= ppd
->link_speed_supported
, lse
= ppd
->link_speed_enabled
;
137 u8
*cache
= ppd
->qsfp_info
.cache
;
139 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
) &&
140 cache
[QSFP_NOM_BIT_RATE_250_OFFS
] < 0x64)
141 ppd
->offline_disabled_reason
=
142 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
);
144 if ((lss
& OPA_LINK_SPEED_12_5G
) && (lse
& OPA_LINK_SPEED_12_5G
) &&
145 cache
[QSFP_NOM_BIT_RATE_100_OFFS
] < 0x7D)
146 ppd
->offline_disabled_reason
=
147 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
);
149 if (ppd
->offline_disabled_reason
==
150 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY
)) {
153 "%s: Cable failed bitrate check, disabling port\n",
160 static int set_qsfp_high_power(struct hfi1_pportdata
*ppd
)
162 u8 cable_power_class
= 0, power_ctrl_byte
= 0;
163 u8
*cache
= ppd
->qsfp_info
.cache
;
166 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
168 if (cable_power_class
> QSFP_POWER_CLASS_1
) {
169 power_ctrl_byte
= cache
[QSFP_PWR_CTRL_BYTE_OFFS
];
171 power_ctrl_byte
|= 1;
172 power_ctrl_byte
&= ~(0x2);
174 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
,
175 QSFP_PWR_CTRL_BYTE_OFFS
,
176 &power_ctrl_byte
, 1);
180 if (cable_power_class
> QSFP_POWER_CLASS_4
) {
181 power_ctrl_byte
|= (1 << 2);
182 ret
= qsfp_write(ppd
, ppd
->dd
->hfi1_id
,
183 QSFP_PWR_CTRL_BYTE_OFFS
,
184 &power_ctrl_byte
, 1);
189 /* SFF 8679 rev 1.7 LPMode Deassert time */
195 static void apply_rx_cdr(struct hfi1_pportdata
*ppd
,
200 u8
*cache
= ppd
->qsfp_info
.cache
;
201 int cable_power_class
;
203 if (!((cache
[QSFP_MOD_PWR_OFFS
] & 0x4) &&
204 (cache
[QSFP_CDR_INFO_OFFS
] & 0x40)))
207 /* RX CDR present, bypass supported */
208 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
210 if (cable_power_class
<= QSFP_POWER_CLASS_3
) {
211 /* Power class <= 3, ignore config & turn RX CDR on */
212 *cdr_ctrl_byte
|= 0xF;
216 get_platform_config_field(
217 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
218 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_CDR_APPLY
,
224 "%s: RX_CDR_APPLY is set to disabled\n",
228 get_platform_config_field(
229 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
230 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_CDR
,
233 /* Expand cdr setting to all 4 lanes */
234 rx_preset
= (rx_preset
| (rx_preset
<< 1) |
235 (rx_preset
<< 2) | (rx_preset
<< 3));
238 *cdr_ctrl_byte
|= rx_preset
;
240 *cdr_ctrl_byte
&= rx_preset
;
241 /* Preserve current TX CDR status */
242 *cdr_ctrl_byte
|= (cache
[QSFP_CDR_CTRL_BYTE_OFFS
] & 0xF0);
246 static void apply_tx_cdr(struct hfi1_pportdata
*ppd
,
251 u8
*cache
= ppd
->qsfp_info
.cache
;
252 int cable_power_class
;
254 if (!((cache
[QSFP_MOD_PWR_OFFS
] & 0x8) &&
255 (cache
[QSFP_CDR_INFO_OFFS
] & 0x80)))
258 /* TX CDR present, bypass supported */
259 cable_power_class
= get_qsfp_power_class(cache
[QSFP_MOD_PWR_OFFS
]);
261 if (cable_power_class
<= QSFP_POWER_CLASS_3
) {
262 /* Power class <= 3, ignore config & turn TX CDR on */
263 *cdr_ctrl_byte
|= 0xF0;
267 get_platform_config_field(
269 PLATFORM_CONFIG_TX_PRESET_TABLE
, tx_preset_index
,
270 TX_PRESET_TABLE_QSFP_TX_CDR_APPLY
, &tx_preset
, 4);
275 "%s: TX_CDR_APPLY is set to disabled\n",
279 get_platform_config_field(
281 PLATFORM_CONFIG_TX_PRESET_TABLE
,
283 TX_PRESET_TABLE_QSFP_TX_CDR
, &tx_preset
, 4);
285 /* Expand cdr setting to all 4 lanes */
286 tx_preset
= (tx_preset
| (tx_preset
<< 1) |
287 (tx_preset
<< 2) | (tx_preset
<< 3));
290 *cdr_ctrl_byte
|= (tx_preset
<< 4);
292 /* Preserve current/determined RX CDR status */
293 *cdr_ctrl_byte
&= ((tx_preset
<< 4) | 0xF);
296 static void apply_cdr_settings(
297 struct hfi1_pportdata
*ppd
, u32 rx_preset_index
,
300 u8
*cache
= ppd
->qsfp_info
.cache
;
301 u8 cdr_ctrl_byte
= cache
[QSFP_CDR_CTRL_BYTE_OFFS
];
303 apply_rx_cdr(ppd
, rx_preset_index
, &cdr_ctrl_byte
);
305 apply_tx_cdr(ppd
, tx_preset_index
, &cdr_ctrl_byte
);
307 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, QSFP_CDR_CTRL_BYTE_OFFS
,
311 static void apply_tx_eq_auto(struct hfi1_pportdata
*ppd
)
313 u8
*cache
= ppd
->qsfp_info
.cache
;
316 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x8))
318 /* Disable adaptive TX EQ if present */
319 tx_eq
= cache
[(128 * 3) + 241];
321 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 241, &tx_eq
, 1);
324 static void apply_tx_eq_prog(struct hfi1_pportdata
*ppd
, u32 tx_preset_index
)
326 u8
*cache
= ppd
->qsfp_info
.cache
;
330 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x4))
333 get_platform_config_field(
334 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
335 tx_preset_index
, TX_PRESET_TABLE_QSFP_TX_EQ_APPLY
,
340 "%s: TX_EQ_APPLY is set to disabled\n",
344 get_platform_config_field(
345 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
346 tx_preset_index
, TX_PRESET_TABLE_QSFP_TX_EQ
,
349 if (((cache
[(128 * 3) + 224] & 0xF0) >> 4) < tx_preset
) {
352 "%s: TX EQ %x unsupported\n",
353 __func__
, tx_preset
);
357 "%s: Applying EQ %x\n",
358 __func__
, cache
[608] & 0xF0);
360 tx_preset
= (cache
[608] & 0xF0) >> 4;
363 tx_eq
= tx_preset
| (tx_preset
<< 4);
364 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 234, &tx_eq
, 1);
365 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 235, &tx_eq
, 1);
368 static void apply_rx_eq_emp(struct hfi1_pportdata
*ppd
, u32 rx_preset_index
)
371 u8 rx_eq
, *cache
= ppd
->qsfp_info
.cache
;
373 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x2))
375 get_platform_config_field(
376 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
377 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_EMP_APPLY
,
383 "%s: RX_EMP_APPLY is set to disabled\n",
387 get_platform_config_field(
388 ppd
->dd
, PLATFORM_CONFIG_RX_PRESET_TABLE
,
389 rx_preset_index
, RX_PRESET_TABLE_QSFP_RX_EMP
,
392 if ((cache
[(128 * 3) + 224] & 0xF) < rx_preset
) {
395 "%s: Requested RX EMP %x\n",
396 __func__
, rx_preset
);
400 "%s: Applying supported EMP %x\n",
401 __func__
, cache
[608] & 0xF);
403 rx_preset
= cache
[608] & 0xF;
406 rx_eq
= rx_preset
| (rx_preset
<< 4);
408 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 236, &rx_eq
, 1);
409 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 237, &rx_eq
, 1);
412 static void apply_eq_settings(struct hfi1_pportdata
*ppd
,
413 u32 rx_preset_index
, u32 tx_preset_index
)
415 u8
*cache
= ppd
->qsfp_info
.cache
;
417 /* no point going on w/o a page 3 */
420 "%s: Upper page 03 not present\n",
425 apply_tx_eq_auto(ppd
);
427 apply_tx_eq_prog(ppd
, tx_preset_index
);
429 apply_rx_eq_emp(ppd
, rx_preset_index
);
432 static void apply_rx_amplitude_settings(
433 struct hfi1_pportdata
*ppd
, u32 rx_preset_index
,
437 u8 rx_amp
= 0, i
= 0, preferred
= 0, *cache
= ppd
->qsfp_info
.cache
;
439 /* no point going on w/o a page 3 */
442 "%s: Upper page 03 not present\n",
446 if (!(cache
[QSFP_EQ_INFO_OFFS
] & 0x1)) {
448 "%s: RX_AMP_APPLY is set to disabled\n",
453 get_platform_config_field(ppd
->dd
,
454 PLATFORM_CONFIG_RX_PRESET_TABLE
,
456 RX_PRESET_TABLE_QSFP_RX_AMP_APPLY
,
461 "%s: RX_AMP_APPLY is set to disabled\n",
465 get_platform_config_field(ppd
->dd
,
466 PLATFORM_CONFIG_RX_PRESET_TABLE
,
468 RX_PRESET_TABLE_QSFP_RX_AMP
,
472 "%s: Requested RX AMP %x\n",
476 for (i
= 0; i
< 4; i
++) {
477 if (cache
[(128 * 3) + 225] & (1 << i
)) {
479 if (preferred
== rx_preset
)
485 * Verify that preferred RX amplitude is not just a
486 * fall through of the default
488 if (!preferred
&& !(cache
[(128 * 3) + 225] & 0x1)) {
489 dd_dev_info(ppd
->dd
, "No supported RX AMP, not applying\n");
494 "%s: Applying RX AMP %x\n", __func__
, preferred
);
496 rx_amp
= preferred
| (preferred
<< 4);
497 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 238, &rx_amp
, 1);
498 qsfp_write(ppd
, ppd
->dd
->hfi1_id
, (256 * 3) + 239, &rx_amp
, 1);
501 #define OPA_INVALID_INDEX 0xFFF
503 static void apply_tx_lanes(struct hfi1_pportdata
*ppd
, u8 field_id
,
504 u32 config_data
, const char *message
)
507 int ret
= HCMD_SUCCESS
;
509 for (i
= 0; i
< 4; i
++) {
510 ret
= load_8051_config(ppd
->dd
, field_id
, i
, config_data
);
511 if (ret
!= HCMD_SUCCESS
) {
514 "%s: %s for lane %u failed\n",
515 message
, __func__
, i
);
520 static void apply_tunings(
521 struct hfi1_pportdata
*ppd
, u32 tx_preset_index
,
522 u8 tuning_method
, u32 total_atten
, u8 limiting_active
)
525 u32 config_data
= 0, tx_preset
= 0;
526 u8 precur
= 0, attn
= 0, postcur
= 0, external_device_config
= 0;
527 u8
*cache
= ppd
->qsfp_info
.cache
;
529 /* Enable external device config if channel is limiting active */
530 read_8051_config(ppd
->dd
, LINK_OPTIMIZATION_SETTINGS
,
531 GENERAL_CONFIG
, &config_data
);
532 config_data
|= limiting_active
;
533 ret
= load_8051_config(ppd
->dd
, LINK_OPTIMIZATION_SETTINGS
,
534 GENERAL_CONFIG
, config_data
);
535 if (ret
!= HCMD_SUCCESS
)
538 "%s: Failed to set enable external device config\n",
541 config_data
= 0; /* re-init */
542 /* Pass tuning method to 8051 */
543 read_8051_config(ppd
->dd
, LINK_TUNING_PARAMETERS
, GENERAL_CONFIG
,
545 config_data
|= tuning_method
;
546 ret
= load_8051_config(ppd
->dd
, LINK_TUNING_PARAMETERS
, GENERAL_CONFIG
,
548 if (ret
!= HCMD_SUCCESS
)
549 dd_dev_err(ppd
->dd
, "%s: Failed to set tuning method\n",
552 /* Set same channel loss for both TX and RX */
553 config_data
= 0 | (total_atten
<< 16) | (total_atten
<< 24);
554 apply_tx_lanes(ppd
, CHANNEL_LOSS_SETTINGS
, config_data
,
555 "Setting channel loss");
557 /* Inform 8051 of cable capabilities */
558 if (ppd
->qsfp_info
.cache_valid
) {
559 external_device_config
=
560 ((cache
[QSFP_MOD_PWR_OFFS
] & 0x4) << 3) |
561 ((cache
[QSFP_MOD_PWR_OFFS
] & 0x8) << 2) |
562 ((cache
[QSFP_EQ_INFO_OFFS
] & 0x2) << 1) |
563 (cache
[QSFP_EQ_INFO_OFFS
] & 0x4);
564 ret
= read_8051_config(ppd
->dd
, DC_HOST_COMM_SETTINGS
,
565 GENERAL_CONFIG
, &config_data
);
566 /* Clear, then set the external device config field */
567 config_data
&= ~(0xFF << 24);
568 config_data
|= (external_device_config
<< 24);
569 ret
= load_8051_config(ppd
->dd
, DC_HOST_COMM_SETTINGS
,
570 GENERAL_CONFIG
, config_data
);
571 if (ret
!= HCMD_SUCCESS
)
573 "%s: Failed set ext device config params\n",
577 if (tx_preset_index
== OPA_INVALID_INDEX
) {
578 if (ppd
->port_type
== PORT_TYPE_QSFP
&& limiting_active
)
579 dd_dev_info(ppd
->dd
, "%s: Invalid Tx preset index\n",
584 /* Following for limiting active channels only */
585 get_platform_config_field(
586 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
, tx_preset_index
,
587 TX_PRESET_TABLE_PRECUR
, &tx_preset
, 4);
590 get_platform_config_field(
591 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
592 tx_preset_index
, TX_PRESET_TABLE_ATTN
, &tx_preset
, 4);
595 get_platform_config_field(
596 ppd
->dd
, PLATFORM_CONFIG_TX_PRESET_TABLE
,
597 tx_preset_index
, TX_PRESET_TABLE_POSTCUR
, &tx_preset
, 4);
600 config_data
= precur
| (attn
<< 8) | (postcur
<< 16);
602 apply_tx_lanes(ppd
, TX_EQ_SETTINGS
, config_data
,
603 "Applying TX settings");
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 ret
= acquire_chip_resource(ppd
->dd
, qsfp_resource(ppd
->dd
), QSFP_WAIT
);
615 dd_dev_err(ppd
->dd
, "%s: hfi%d: cannot lock i2c chain\n",
616 __func__
, (int)ppd
->dd
->hfi1_id
);
620 ppd
->qsfp_info
.limiting_active
= 1;
622 ret
= set_qsfp_tx(ppd
, 0);
626 ret
= qual_power(ppd
);
630 ret
= qual_bitrate(ppd
);
634 if (ppd
->qsfp_info
.reset_needed
) {
636 ppd
->qsfp_info
.reset_needed
= 0;
637 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
639 ppd
->qsfp_info
.reset_needed
= 1;
642 ret
= set_qsfp_high_power(ppd
);
646 if (cache
[QSFP_EQ_INFO_OFFS
] & 0x4) {
647 ret
= get_platform_config_field(
649 PLATFORM_CONFIG_PORT_TABLE
, 0,
650 PORT_TABLE_TX_PRESET_IDX_ACTIVE_EQ
,
653 *ptr_tx_preset
= OPA_INVALID_INDEX
;
657 ret
= get_platform_config_field(
659 PLATFORM_CONFIG_PORT_TABLE
, 0,
660 PORT_TABLE_TX_PRESET_IDX_ACTIVE_NO_EQ
,
663 *ptr_tx_preset
= OPA_INVALID_INDEX
;
668 ret
= get_platform_config_field(
669 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
670 PORT_TABLE_RX_PRESET_IDX
, ptr_rx_preset
, 4);
672 *ptr_rx_preset
= OPA_INVALID_INDEX
;
676 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
))
677 get_platform_config_field(
678 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
679 PORT_TABLE_LOCAL_ATTEN_25G
, ptr_total_atten
, 4);
680 else if ((lss
& OPA_LINK_SPEED_12_5G
) && (lse
& OPA_LINK_SPEED_12_5G
))
681 get_platform_config_field(
682 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
683 PORT_TABLE_LOCAL_ATTEN_12G
, ptr_total_atten
, 4);
685 apply_cdr_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
687 apply_eq_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
689 apply_rx_amplitude_settings(ppd
, *ptr_rx_preset
, *ptr_tx_preset
);
691 ret
= set_qsfp_tx(ppd
, 1);
694 release_chip_resource(ppd
->dd
, qsfp_resource(ppd
->dd
));
698 static int tune_qsfp(struct hfi1_pportdata
*ppd
,
699 u32
*ptr_tx_preset
, u32
*ptr_rx_preset
,
700 u8
*ptr_tuning_method
, u32
*ptr_total_atten
)
702 u32 cable_atten
= 0, remote_atten
= 0, platform_atten
= 0;
703 u16 lss
= ppd
->link_speed_supported
, lse
= ppd
->link_speed_enabled
;
705 u8
*cache
= ppd
->qsfp_info
.cache
;
707 switch ((cache
[QSFP_MOD_TECH_OFFS
] & 0xF0) >> 4) {
709 ret
= get_platform_config_field(
711 PLATFORM_CONFIG_PORT_TABLE
, 0,
712 PORT_TABLE_LOCAL_ATTEN_25G
,
717 if ((lss
& OPA_LINK_SPEED_25G
) && (lse
& OPA_LINK_SPEED_25G
))
718 cable_atten
= cache
[QSFP_CU_ATTEN_12G_OFFS
];
719 else if ((lss
& OPA_LINK_SPEED_12_5G
) &&
720 (lse
& OPA_LINK_SPEED_12_5G
))
721 cable_atten
= cache
[QSFP_CU_ATTEN_7G_OFFS
];
723 /* Fallback to configured attenuation if cable memory is bad */
724 if (cable_atten
== 0 || cable_atten
> 36) {
725 ret
= get_platform_config_field(
727 PLATFORM_CONFIG_SYSTEM_TABLE
, 0,
728 SYSTEM_TABLE_QSFP_ATTENUATION_DEFAULT_25G
,
734 ret
= get_platform_config_field(
735 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
736 PORT_TABLE_REMOTE_ATTEN_25G
, &remote_atten
, 4);
740 *ptr_total_atten
= platform_atten
+ cable_atten
+ remote_atten
;
742 *ptr_tuning_method
= OPA_PASSIVE_TUNING
;
744 case 0x0 ... 0x9: /* fallthrough */
745 case 0xC: /* fallthrough */
747 ret
= tune_active_qsfp(ppd
, ptr_tx_preset
, ptr_rx_preset
,
752 *ptr_tuning_method
= OPA_ACTIVE_TUNING
;
754 case 0xD: /* fallthrough */
757 dd_dev_info(ppd
->dd
, "%s: Unknown/unsupported cable\n",
765 * This function communicates its success or failure via ppd->driver_link_ready
766 * Thus, it depends on its association with start_link(...) which checks
767 * driver_link_ready before proceeding with the link negotiation and
768 * initialization process.
770 void tune_serdes(struct hfi1_pportdata
*ppd
)
774 u32 remote_atten
= 0, platform_atten
= 0;
775 u32 rx_preset_index
, tx_preset_index
;
776 u8 tuning_method
= 0, limiting_active
= 0;
777 struct hfi1_devdata
*dd
= ppd
->dd
;
779 rx_preset_index
= OPA_INVALID_INDEX
;
780 tx_preset_index
= OPA_INVALID_INDEX
;
782 /* the link defaults to enabled */
783 ppd
->link_enabled
= 1;
784 /* the driver link ready state defaults to not ready */
785 ppd
->driver_link_ready
= 0;
786 ppd
->offline_disabled_reason
= HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE
);
788 /* Skip the tuning for testing (loopback != none) and simulations */
789 if (loopback
!= LOOPBACK_NONE
||
790 ppd
->dd
->icode
== ICODE_FUNCTIONAL_SIMULATOR
) {
791 ppd
->driver_link_ready
= 1;
795 ret
= get_platform_config_field(ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
796 PORT_TABLE_PORT_TYPE
, &ppd
->port_type
,
799 ppd
->port_type
= PORT_TYPE_UNKNOWN
;
801 switch (ppd
->port_type
) {
802 case PORT_TYPE_DISCONNECTED
:
803 ppd
->offline_disabled_reason
=
804 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_DISCONNECTED
);
805 dd_dev_info(dd
, "%s: Port disconnected, disabling port\n",
808 case PORT_TYPE_FIXED
:
809 /* platform_atten, remote_atten pre-zeroed to catch error */
810 get_platform_config_field(
811 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
812 PORT_TABLE_LOCAL_ATTEN_25G
, &platform_atten
, 4);
814 get_platform_config_field(
815 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
816 PORT_TABLE_REMOTE_ATTEN_25G
, &remote_atten
, 4);
818 total_atten
= platform_atten
+ remote_atten
;
820 tuning_method
= OPA_PASSIVE_TUNING
;
822 case PORT_TYPE_VARIABLE
:
823 if (qsfp_mod_present(ppd
)) {
825 * platform_atten, remote_atten pre-zeroed to
828 get_platform_config_field(
829 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
830 PORT_TABLE_LOCAL_ATTEN_25G
,
833 get_platform_config_field(
834 ppd
->dd
, PLATFORM_CONFIG_PORT_TABLE
, 0,
835 PORT_TABLE_REMOTE_ATTEN_25G
,
838 total_atten
= platform_atten
+ remote_atten
;
840 tuning_method
= OPA_PASSIVE_TUNING
;
842 ppd
->offline_disabled_reason
=
843 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_CHASSIS_CONFIG
);
846 if (qsfp_mod_present(ppd
)) {
847 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
849 if (ppd
->qsfp_info
.cache_valid
) {
857 * We may have modified the QSFP memory, so
858 * update the cache to reflect the changes
860 refresh_qsfp_cache(ppd
, &ppd
->qsfp_info
);
865 ppd
->qsfp_info
.limiting_active
;
868 "%s: Reading QSFP memory failed\n",
873 ppd
->offline_disabled_reason
=
875 OPA_LINKDOWN_REASON_LOCAL_MEDIA_NOT_INSTALLED
);
878 dd_dev_info(ppd
->dd
, "%s: Unknown port type\n", __func__
);
879 ppd
->port_type
= PORT_TYPE_UNKNOWN
;
880 tuning_method
= OPA_UNKNOWN_TUNING
;
883 tx_preset_index
= OPA_INVALID_INDEX
;
887 if (ppd
->offline_disabled_reason
==
888 HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE
))
889 apply_tunings(ppd
, tx_preset_index
, tuning_method
,
890 total_atten
, limiting_active
);
893 ppd
->driver_link_ready
= 1;
897 ppd
->driver_link_ready
= 0;