1 /*- 2 * Copyright (c) 2015,2016 Annapurna Labs Ltd. and affiliates 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include "al_init_eth_lm.h" 33 #include "al_serdes.h" 34 #include "al_hal_eth.h" 35 #include "al_init_eth_kr.h" 36 37 /** 38 * @{ 39 * @file al_init_eth_lm.c 40 * 41 * @brief ethernet link management common utilities 42 * 43 */ 44 45 /* delay before checking link status with new serdes parameters (uSec) */ 46 #define AL_ETH_LM_LINK_STATUS_DELAY 1000 47 /* delay before checking link status after reconfiguring the retimer (uSec) */ 48 #define AL_ETH_LM_RETIMER_LINK_STATUS_DELAY 50000 49 50 #define AL_ETH_LM_EQ_ITERATIONS 15 51 #define AL_ETH_LM_MAX_DCGAIN 8 52 53 /* num of link training failures till serdes reset */ 54 #define AL_ETH_LT_FAILURES_TO_RESET 10 55 56 #define MODULE_IDENTIFIER_IDX 0 57 #define MODULE_IDENTIFIER_SFP 0x3 58 #define MODULE_IDENTIFIER_QSFP 0xd 59 60 #define SFP_PRESENT 0 61 #define SFP_NOT_PRESENT 1 62 63 /* SFP+ module */ 64 #define SFP_I2C_HEADER_10G_IDX 3 65 #define SFP_I2C_HEADER_10G_DA_IDX 8 66 #define SFP_I2C_HEADER_10G_DA_LEN_IDX 18 67 #define SFP_I2C_HEADER_1G_IDX 6 68 #define SFP_I2C_HEADER_SIGNAL_RATE 12 /* Nominal signaling rate, units of 100MBd. */ 69 70 #define SFP_MIN_SIGNAL_RATE_25G 250 71 #define SFP_MIN_SIGNAL_RATE_10G 100 72 73 /* QSFP+ module */ 74 #define QSFP_COMPLIANCE_CODE_IDX 131 75 /* 40GBASE-LR4 and 40GBASE-SR4 are optic modules */ 76 #define QSFP_COMPLIANCE_CODE_OPTIC ((1 << 1) | (1 << 2)) 77 #define QSFP_COMPLIANCE_CODE_DAC (1 << 3) 78 #define QSFP_CABLE_LEN_IDX 146 79 80 /* TODO: need to check the necessary delay */ 81 #define AL_ETH_LM_RETIMER_WAIT_FOR_LOCK 500 /* delay after retimer reset to lock (mSec) */ 82 #define AL_ETH_LM_SERDES_WAIT_FOR_LOCK 50 /* delay after signal detect to lock (mSec) */ 83 84 #define AL_ETH_LM_GEARBOX_RESET_DELAY 1000 /* (uSec) */ 85 86 static const uint32_t 87 al_eth_retimer_boost_addr[AL_ETH_RETIMER_CHANNEL_MAX][AL_ETH_RETIMER_TYPE_MAX] = { 88 /* BR_210 | BR_410 */ 89 /* AL_ETH_RETIMER_CHANNEL_A */ {0xf, 0x1a}, 90 /* AL_ETH_RETIMER_CHANNEL_B */ {0x16, 0x18}, 91 /* AL_ETH_RETIMER_CHANNEL_C */ {0x0, 0x16}, 92 /* AL_ETH_RETIMER_CHANNEL_D */ {0x0, 0x14}, 93 }; 94 95 #define RETIMER_LENS_MAX 5 96 static const uint32_t 97 al_eth_retimer_boost_lens[RETIMER_LENS_MAX] = {0, 1, 2, 3, 5}; 98 99 static const uint32_t 100 al_eth_retimer_boost_value[RETIMER_LENS_MAX + 1][AL_ETH_RETIMER_TYPE_MAX] = { 101 /* BR_210 | BR_410 */ 102 /* 0 */ {0x0, 0x0}, 103 /* 1 */ {0x1, 0x1}, 104 /* 2 */ {0x2, 0x1}, 105 /* 3 */ {0x3, 0x3}, 106 /* 5 */ {0x7, 0x3}, 107 /* 5+ */{0xb, 0x7}, 108 }; 109 110 struct retimer_config_reg { 111 uint8_t addr; 112 uint8_t value; 113 uint8_t mask; 114 }; 115 116 static struct retimer_config_reg retimer_ds25_25g_mode_tx_ch[] = { 117 {.addr = 0x0A, .value = 0x0C, .mask = 0xff }, 118 {.addr = 0x2F, .value = 0x54, .mask = 0xff }, 119 {.addr = 0x31, .value = 0x20, .mask = 0xff }, 120 {.addr = 0x1E, .value = 0xE9, .mask = 0xff }, 121 {.addr = 0x1F, .value = 0x0B, .mask = 0xff }, 122 {.addr = 0xA6, .value = 0x43, .mask = 0xff }, 123 {.addr = 0x2A, .value = 0x5A, .mask = 0xff }, 124 {.addr = 0x2B, .value = 0x0A, .mask = 0xff }, 125 {.addr = 0x2C, .value = 0xF6, .mask = 0xff }, 126 {.addr = 0x70, .value = 0x05, .mask = 0xff }, 127 {.addr = 0x6A, .value = 0x21, .mask = 0xff }, 128 {.addr = 0x35, .value = 0x0F, .mask = 0xff }, 129 {.addr = 0x12, .value = 0x83, .mask = 0xff }, 130 {.addr = 0x9C, .value = 0x24, .mask = 0xff }, 131 {.addr = 0x98, .value = 0x00, .mask = 0xff }, 132 {.addr = 0x42, .value = 0x50, .mask = 0xff }, 133 {.addr = 0x44, .value = 0x90, .mask = 0xff }, 134 {.addr = 0x45, .value = 0xC0, .mask = 0xff }, 135 {.addr = 0x46, .value = 0xD0, .mask = 0xff }, 136 {.addr = 0x47, .value = 0xD1, .mask = 0xff }, 137 {.addr = 0x48, .value = 0xD5, .mask = 0xff }, 138 {.addr = 0x49, .value = 0xD8, .mask = 0xff }, 139 {.addr = 0x4A, .value = 0xEA, .mask = 0xff }, 140 {.addr = 0x4B, .value = 0xF7, .mask = 0xff }, 141 {.addr = 0x4C, .value = 0xFD, .mask = 0xff }, 142 {.addr = 0x8E, .value = 0x00, .mask = 0xff }, 143 {.addr = 0x3D, .value = 0x94, .mask = 0xff }, 144 {.addr = 0x3F, .value = 0x40, .mask = 0xff }, 145 {.addr = 0x3E, .value = 0x43, .mask = 0xff }, 146 {.addr = 0x0A, .value = 0x00, .mask = 0xff }, 147 }; 148 149 static struct retimer_config_reg retimer_ds25_25g_mode_rx_ch[] = { 150 {.addr = 0x0A, .value = 0x0C, .mask = 0xff}, 151 {.addr = 0x2F, .value = 0x54, .mask = 0xff}, 152 {.addr = 0x31, .value = 0x40, .mask = 0xff}, 153 {.addr = 0x1E, .value = 0xE3, .mask = 0xff}, 154 {.addr = 0x1F, .value = 0x0B, .mask = 0xff}, 155 {.addr = 0xA6, .value = 0x43, .mask = 0xff}, 156 {.addr = 0x2A, .value = 0x5A, .mask = 0xff}, 157 {.addr = 0x2B, .value = 0x0A, .mask = 0xff}, 158 {.addr = 0x2C, .value = 0xF6, .mask = 0xff}, 159 {.addr = 0x70, .value = 0x05, .mask = 0xff}, 160 {.addr = 0x6A, .value = 0x21, .mask = 0xff}, 161 {.addr = 0x35, .value = 0x0F, .mask = 0xff}, 162 {.addr = 0x12, .value = 0x83, .mask = 0xff}, 163 {.addr = 0x9C, .value = 0x24, .mask = 0xff}, 164 {.addr = 0x98, .value = 0x00, .mask = 0xff}, 165 {.addr = 0x42, .value = 0x50, .mask = 0xff}, 166 {.addr = 0x44, .value = 0x90, .mask = 0xff}, 167 {.addr = 0x45, .value = 0xC0, .mask = 0xff}, 168 {.addr = 0x46, .value = 0xD0, .mask = 0xff}, 169 {.addr = 0x47, .value = 0xD1, .mask = 0xff}, 170 {.addr = 0x48, .value = 0xD5, .mask = 0xff}, 171 {.addr = 0x49, .value = 0xD8, .mask = 0xff}, 172 {.addr = 0x4A, .value = 0xEA, .mask = 0xff}, 173 {.addr = 0x4B, .value = 0xF7, .mask = 0xff}, 174 {.addr = 0x4C, .value = 0xFD, .mask = 0xff}, 175 {.addr = 0x8E, .value = 0x00, .mask = 0xff}, 176 {.addr = 0x3D, .value = 0x94, .mask = 0xff}, 177 {.addr = 0x3F, .value = 0x40, .mask = 0xff}, 178 {.addr = 0x3E, .value = 0x43, .mask = 0xff}, 179 {.addr = 0x0A, .value = 0x00, .mask = 0xff}, 180 }; 181 182 static struct retimer_config_reg retimer_ds25_10g_mode[] = { 183 /* Assert CDR reset (6.3) */ 184 {.addr = 0x0A, .value = 0x0C, .mask = 0x0C}, 185 /* Select 10.3125Gbps standard rate mode (6.6) */ 186 {.addr = 0x2F, .value = 0x00, .mask = 0xF0}, 187 /* Enable loop filter auto-adjust */ 188 {.addr = 0x1F, .value = 0x08, .mask = 0x08}, 189 /* Set Adapt Mode 1 (6.13) */ 190 {.addr = 0x31, .value = 0x20, .mask = 0x60}, 191 /* Disable the DFE since most applications do not need it (6.18) */ 192 {.addr = 0x1E, .value = 0x08, .mask = 0x08}, 193 /* Release CDR reset (6.4) */ 194 {.addr = 0x0A, .value = 0x00, .mask = 0x0C}, 195 /* Enable FIR (6.12) */ 196 {.addr = 0x3D, .value = 0x80, .mask = 0x80}, 197 /* Set Main-cursor tap sign to positive (6.12) */ 198 {.addr = 0x3D, .value = 0x00, .mask = 0x40}, 199 /* Set Post-cursor tap sign to negative (6.12) */ 200 {.addr = 0x3F, .value = 0x40, .mask = 0x40}, 201 /* Set Pre-cursor tap sign to negative (6.12) */ 202 {.addr = 0x3E, .value = 0x40, .mask = 0x40}, 203 /* Set Main-cursor tap magnitude to 13 (6.12) */ 204 {.addr = 0x3D, .value = 0x0D, .mask = 0x1F}, 205 }; 206 207 static int al_eth_lm_retimer_boost_config(struct al_eth_lm_context *lm_context); 208 static int al_eth_lm_retimer_ds25_full_config(struct al_eth_lm_context *lm_context); 209 static bool al_eth_lm_retimer_ds25_signal_detect( 210 struct al_eth_lm_context *lm_context, uint32_t channel); 211 static int al_eth_lm_retimer_ds25_cdr_reset(struct al_eth_lm_context *lm_context, uint32_t channel); 212 static bool al_eth_lm_retimer_ds25_cdr_lock( 213 struct al_eth_lm_context *lm_context, uint32_t channel); 214 static int al_eth_lm_retimer_25g_rx_adaptation(struct al_eth_lm_context *lm_context); 215 216 struct al_eth_lm_retimer { 217 int (*config)(struct al_eth_lm_context *lm_context); 218 int (*reset)(struct al_eth_lm_context *lm_context, uint32_t channel); 219 bool (*signal_detect)(struct al_eth_lm_context *lm_context, uint32_t channel); 220 bool (*cdr_lock)(struct al_eth_lm_context *lm_context, uint32_t channel); 221 int (*rx_adaptation)(struct al_eth_lm_context *lm_context); 222 }; 223 224 static struct al_eth_lm_retimer retimer[] = { 225 {.config = al_eth_lm_retimer_boost_config, .signal_detect = NULL, 226 .reset = NULL, .cdr_lock = NULL, .rx_adaptation = NULL}, 227 {.config = al_eth_lm_retimer_boost_config, .signal_detect = NULL, 228 .reset = NULL, .cdr_lock = NULL, .rx_adaptation = NULL}, 229 {.config = al_eth_lm_retimer_ds25_full_config, 230 .signal_detect = al_eth_lm_retimer_ds25_signal_detect, 231 .reset = al_eth_lm_retimer_ds25_cdr_reset, 232 .cdr_lock = al_eth_lm_retimer_ds25_cdr_lock, 233 .rx_adaptation = al_eth_lm_retimer_25g_rx_adaptation}, 234 }; 235 236 #define SFP_10G_DA_ACTIVE 0x8 237 #define SFP_10G_DA_PASSIVE 0x4 238 239 #define lm_debug(...) \ 240 do { \ 241 if (lm_context->debug) \ 242 al_warn(__VA_ARGS__); \ 243 else \ 244 al_dbg(__VA_ARGS__); \ 245 } while (0) 246 247 static int 248 al_eth_sfp_detect(struct al_eth_lm_context *lm_context, 249 enum al_eth_lm_link_mode *new_mode) 250 { 251 int rc = 0; 252 uint8_t sfp_10g; 253 uint8_t sfp_1g; 254 uint8_t sfp_cable_tech; 255 uint8_t sfp_da_len; 256 uint8_t signal_rate; 257 258 do { 259 rc = lm_context->i2c_read(lm_context->i2c_context, 260 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 261 SFP_I2C_HEADER_10G_IDX, &sfp_10g); 262 if (rc != 0) 263 break; 264 265 rc = lm_context->i2c_read(lm_context->i2c_context, 266 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 267 SFP_I2C_HEADER_1G_IDX, &sfp_1g); 268 if (rc != 0) 269 break; 270 271 rc = lm_context->i2c_read(lm_context->i2c_context, 272 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 273 SFP_I2C_HEADER_10G_DA_IDX, &sfp_cable_tech); 274 if (rc != 0) 275 break; 276 277 rc = lm_context->i2c_read(lm_context->i2c_context, 278 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 279 SFP_I2C_HEADER_10G_DA_LEN_IDX, &sfp_da_len); 280 if (rc != 0) 281 break; 282 283 rc = lm_context->i2c_read(lm_context->i2c_context, 284 lm_context->sfp_bus_id, 285 lm_context->sfp_i2c_addr, 286 SFP_I2C_HEADER_SIGNAL_RATE, 287 &signal_rate); 288 } while (0); 289 290 if (rc != 0) { 291 if (rc == ETIMEDOUT) { 292 /* ETIMEDOUT is returned when no SFP is connected */ 293 if (lm_context->mode != AL_ETH_LM_MODE_DISCONNECTED) 294 lm_debug("%s: SFP Disconnected\n", __func__); 295 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 296 } else { 297 return (rc); 298 } 299 } else if ((sfp_cable_tech & (SFP_10G_DA_PASSIVE | SFP_10G_DA_ACTIVE)) != 0) { 300 if ((signal_rate >= SFP_MIN_SIGNAL_RATE_25G) && 301 ((lm_context->max_speed == AL_ETH_LM_MAX_SPEED_25G) || 302 (lm_context->max_speed == AL_ETH_LM_MAX_SPEED_MAX))) 303 *new_mode = AL_ETH_LM_MODE_25G; 304 else if ((signal_rate >= SFP_MIN_SIGNAL_RATE_10G) && 305 ((lm_context->max_speed == AL_ETH_LM_MAX_SPEED_10G) || 306 (lm_context->max_speed == AL_ETH_LM_MAX_SPEED_MAX))) 307 *new_mode = AL_ETH_LM_MODE_10G_DA; 308 else 309 *new_mode = AL_ETH_LM_MODE_1G; 310 311 lm_debug("%s: %s DAC (%d M) detected (max signal rate %d)\n", 312 __func__, 313 (sfp_cable_tech & SFP_10G_DA_PASSIVE) ? "Passive" : "Active", 314 sfp_da_len, 315 signal_rate); 316 317 /* for active direct attached need to use len 0 in the retimer configuration */ 318 lm_context->da_len = (sfp_cable_tech & SFP_10G_DA_PASSIVE) ? sfp_da_len : 0; 319 } else if (sfp_10g != 0) { 320 lm_debug("%s: 10 SFP detected\n", __func__); 321 *new_mode = AL_ETH_LM_MODE_10G_OPTIC; 322 } else if (sfp_1g != 0) { 323 lm_debug("%s: 1G SFP detected\n", __func__); 324 *new_mode = AL_ETH_LM_MODE_1G; 325 } else { 326 al_warn("%s: unknown SFP inserted. eeprom content: 10G compliance 0x%x," 327 " 1G compliance 0x%x, sfp+cable 0x%x. default to %s\n", 328 __func__, sfp_10g, sfp_1g, sfp_cable_tech, 329 al_eth_lm_mode_convert_to_str(lm_context->default_mode)); 330 *new_mode = lm_context->default_mode; 331 lm_context->da_len = lm_context->default_dac_len; 332 } 333 334 if ((lm_context->sfp_detect_force_mode) && (*new_mode != AL_ETH_LM_MODE_DISCONNECTED) && 335 (*new_mode != lm_context->default_mode)) { 336 al_warn("%s: Force mode to default (%s). mode based of the SFP EEPROM %s\n", 337 __func__, al_eth_lm_mode_convert_to_str(lm_context->default_mode), 338 al_eth_lm_mode_convert_to_str(*new_mode)); 339 340 *new_mode = lm_context->default_mode; 341 } 342 343 lm_context->mode = *new_mode; 344 345 return (0); 346 } 347 348 static int 349 al_eth_qsfp_detect(struct al_eth_lm_context *lm_context, 350 enum al_eth_lm_link_mode *new_mode) 351 { 352 int rc = 0; 353 uint8_t qsfp_comp_code; 354 uint8_t qsfp_da_len; 355 356 do { 357 rc = lm_context->i2c_read(lm_context->i2c_context, 358 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 359 QSFP_COMPLIANCE_CODE_IDX, &qsfp_comp_code); 360 if (rc != 0) 361 break; 362 363 rc = lm_context->i2c_read(lm_context->i2c_context, 364 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 365 QSFP_CABLE_LEN_IDX, &qsfp_da_len); 366 if (rc != 0) 367 break; 368 } while (0); 369 370 if (rc != 0) { 371 if (rc == ETIMEDOUT) { 372 /* ETIMEDOUT is returned when no SFP is connected */ 373 lm_debug("%s: SFP Disconnected\n", __func__); 374 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 375 } else { 376 return (rc); 377 } 378 } else if ((qsfp_comp_code & QSFP_COMPLIANCE_CODE_DAC) != 0) { 379 lm_debug("%s: 10G passive DAC (%d M) detected\n", 380 __func__, qsfp_da_len); 381 *new_mode = AL_ETH_LM_MODE_10G_DA; 382 lm_context->da_len = qsfp_da_len; 383 } else if ((qsfp_comp_code & QSFP_COMPLIANCE_CODE_OPTIC) != 0) { 384 lm_debug("%s: 10G optic module detected\n", __func__); 385 *new_mode = AL_ETH_LM_MODE_10G_OPTIC; 386 } else { 387 al_warn("%s: unknown QSFP inserted. eeprom content: 10G " 388 "compliance 0x%x default to %s\n", __func__, qsfp_comp_code, 389 al_eth_lm_mode_convert_to_str(lm_context->default_mode)); 390 *new_mode = lm_context->default_mode; 391 lm_context->da_len = lm_context->default_dac_len; 392 } 393 394 lm_context->mode = *new_mode; 395 396 return (0); 397 } 398 399 static int 400 al_eth_module_detect(struct al_eth_lm_context *lm_context, 401 enum al_eth_lm_link_mode *new_mode) 402 { 403 int rc = 0; 404 uint8_t module_idx; 405 int sfp_present = SFP_PRESENT; 406 407 if ((lm_context->gpio_get) && (lm_context->gpio_present != 0)) 408 sfp_present = lm_context->gpio_get(lm_context->gpio_present); 409 410 if (sfp_present == SFP_NOT_PRESENT) { 411 lm_debug("%s: SFP not exist\n", __func__); 412 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 413 414 return 0; 415 } 416 417 rc = lm_context->i2c_read(lm_context->i2c_context, 418 lm_context->sfp_bus_id, lm_context->sfp_i2c_addr, 419 MODULE_IDENTIFIER_IDX, &module_idx); 420 if (rc != 0) { 421 if (rc == ETIMEDOUT) { 422 /* ETIMEDOUT is returned when no SFP is connected */ 423 if (lm_context->mode != AL_ETH_LM_MODE_DISCONNECTED) 424 lm_debug("%s: SFP Disconnected\n", __func__); 425 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 426 return (0); 427 } else { 428 return (rc); 429 } 430 } 431 432 if (module_idx == MODULE_IDENTIFIER_QSFP) 433 return (al_eth_qsfp_detect(lm_context, new_mode)); 434 else 435 return (al_eth_sfp_detect(lm_context, new_mode)); 436 437 return (0); 438 } 439 440 static struct al_serdes_adv_tx_params da_tx_params = { 441 .override = AL_TRUE, 442 .amp = 0x1, 443 .total_driver_units = 0x13, 444 .c_plus_1 = 0x2, 445 .c_plus_2 = 0, 446 .c_minus_1 = 0x2, 447 .slew_rate = 0, 448 }; 449 450 static struct al_serdes_adv_rx_params da_rx_params = { 451 .override = AL_TRUE, 452 .dcgain = 0x4, 453 .dfe_3db_freq = 0x4, 454 .dfe_gain = 0x3, 455 .dfe_first_tap_ctrl = 0x5, 456 .dfe_secound_tap_ctrl = 0x1, 457 .dfe_third_tap_ctrl = 0x8, 458 .dfe_fourth_tap_ctrl = 0x1, 459 .low_freq_agc_gain = 0x7, 460 .precal_code_sel = 0, 461 .high_freq_agc_boost = 0x1d, 462 }; 463 464 static struct al_serdes_adv_tx_params optic_tx_params = { 465 .override = AL_TRUE, 466 .amp = 0x1, 467 .total_driver_units = 0x13, 468 .c_plus_1 = 0x2, 469 .c_plus_2 = 0, 470 .c_minus_1 = 0, 471 .slew_rate = 0, 472 }; 473 474 static struct al_serdes_adv_rx_params optic_rx_params = { 475 .override = AL_TRUE, 476 .dcgain = 0x0, 477 .dfe_3db_freq = 0x7, 478 .dfe_gain = 0x0, 479 .dfe_first_tap_ctrl = 0x0, 480 .dfe_secound_tap_ctrl = 0x8, 481 .dfe_third_tap_ctrl = 0x0, 482 .dfe_fourth_tap_ctrl = 0x8, 483 .low_freq_agc_gain = 0x7, 484 .precal_code_sel = 0, 485 .high_freq_agc_boost = 0x4, 486 }; 487 488 static void 489 al_eth_serdes_static_tx_params_set(struct al_eth_lm_context *lm_context) 490 { 491 492 if (lm_context->tx_param_dirty == 0) 493 return; 494 495 if (lm_context->serdes_tx_params_valid != 0) { 496 lm_context->tx_param_dirty = 0; 497 498 lm_context->tx_params_override.override = AL_TRUE; 499 500 if ((lm_context->serdes_obj->tx_advanced_params_set) == 0) { 501 al_err("tx_advanced_params_set is not supported for this serdes group\n"); 502 return; 503 } 504 505 lm_context->serdes_obj->tx_advanced_params_set( 506 lm_context->serdes_obj, 507 lm_context->lane, 508 &lm_context->tx_params_override); 509 510 } else if (lm_context->static_values != 0) { 511 lm_context->tx_param_dirty = 0; 512 513 if ((lm_context->serdes_obj->tx_advanced_params_set) == 0) { 514 al_err("tx_advanced_params_set is not supported for this serdes group\n"); 515 return; 516 } 517 518 if ((lm_context->retimer_exist == 0) && 519 (lm_context->mode == AL_ETH_LM_MODE_10G_DA)) 520 lm_context->serdes_obj->tx_advanced_params_set( 521 lm_context->serdes_obj, 522 lm_context->lane, 523 &da_tx_params); 524 else 525 lm_context->serdes_obj->tx_advanced_params_set( 526 lm_context->serdes_obj, 527 lm_context->lane, 528 &optic_tx_params); 529 } 530 } 531 532 static void 533 al_eth_serdes_static_rx_params_set(struct al_eth_lm_context *lm_context) 534 { 535 536 if (lm_context->rx_param_dirty == 0) 537 return; 538 539 if (lm_context->serdes_rx_params_valid != 0) { 540 lm_context->rx_param_dirty = 0; 541 542 lm_context->rx_params_override.override = AL_TRUE; 543 544 if ((lm_context->serdes_obj->rx_advanced_params_set) == 0) { 545 al_err("rx_advanced_params_set is not supported for this serdes group\n"); 546 return; 547 } 548 549 lm_context->serdes_obj->rx_advanced_params_set( 550 lm_context->serdes_obj, 551 lm_context->lane, 552 &lm_context->rx_params_override); 553 554 } else if (lm_context->static_values != 0) { 555 lm_context->rx_param_dirty = 0; 556 557 if ((lm_context->serdes_obj->rx_advanced_params_set) == 0) { 558 al_err("rx_advanced_params_set is not supported for this serdes group\n"); 559 return; 560 } 561 562 if ((lm_context->retimer_exist == 0) && 563 (lm_context->mode == AL_ETH_LM_MODE_10G_DA)) 564 lm_context->serdes_obj->rx_advanced_params_set( 565 lm_context->serdes_obj, 566 lm_context->lane, 567 &da_rx_params); 568 else 569 lm_context->serdes_obj->rx_advanced_params_set( 570 lm_context->serdes_obj, 571 lm_context->lane, 572 &optic_rx_params); 573 } 574 } 575 576 static int 577 al_eth_rx_equal_run(struct al_eth_lm_context *lm_context) 578 { 579 struct al_serdes_adv_rx_params rx_params; 580 int dcgain; 581 int best_dcgain = -1; 582 int i; 583 int best_score = -1; 584 int test_score = -1; 585 586 rx_params.override = AL_FALSE; 587 lm_context->serdes_obj->rx_advanced_params_set(lm_context->serdes_obj, 588 lm_context->lane, &rx_params); 589 590 lm_debug("score | dcgain | dfe3db | dfegain | tap1 | tap2 | tap3 | " 591 "tap4 | low freq | high freq\n"); 592 593 for (dcgain = 0; dcgain < AL_ETH_LM_MAX_DCGAIN; dcgain++) { 594 lm_context->serdes_obj->dcgain_set( 595 lm_context->serdes_obj, 596 dcgain); 597 598 test_score = lm_context->serdes_obj->rx_equalization( 599 lm_context->serdes_obj, 600 lm_context->lane); 601 602 if (test_score < 0) { 603 al_warn("serdes rx equalization failed on error\n"); 604 return (test_score); 605 } 606 607 if (test_score > best_score) { 608 best_score = test_score; 609 best_dcgain = dcgain; 610 } 611 612 lm_context->serdes_obj->rx_advanced_params_get( 613 lm_context->serdes_obj, 614 lm_context->lane, 615 &rx_params); 616 617 lm_debug("%6d|%8x|%8x|%9x|%6x|%6x|%6x|%6x|%10x|%10x|\n", 618 test_score, rx_params.dcgain, rx_params.dfe_3db_freq, 619 rx_params.dfe_gain, rx_params.dfe_first_tap_ctrl, 620 rx_params.dfe_secound_tap_ctrl, rx_params.dfe_third_tap_ctrl, 621 rx_params.dfe_fourth_tap_ctrl, rx_params.low_freq_agc_gain, 622 rx_params.high_freq_agc_boost); 623 } 624 625 lm_context->serdes_obj->dcgain_set( 626 lm_context->serdes_obj, 627 best_dcgain); 628 629 best_score = -1; 630 for(i = 0; i < AL_ETH_LM_EQ_ITERATIONS; i++) { 631 test_score = lm_context->serdes_obj->rx_equalization( 632 lm_context->serdes_obj, 633 lm_context->lane); 634 635 if (test_score < 0) { 636 al_warn("serdes rx equalization failed on error\n"); 637 return (test_score); 638 } 639 640 if (test_score > best_score) { 641 best_score = test_score; 642 lm_context->serdes_obj->rx_advanced_params_get( 643 lm_context->serdes_obj, 644 lm_context->lane, 645 &rx_params); 646 } 647 } 648 649 rx_params.precal_code_sel = 0; 650 rx_params.override = AL_TRUE; 651 lm_context->serdes_obj->rx_advanced_params_set( 652 lm_context->serdes_obj, 653 lm_context->lane, 654 &rx_params); 655 656 lm_debug("-------------------- best dcgain %d ------------------------------------\n", best_dcgain); 657 lm_debug("%6d|%8x|%8x|%9x|%6x|%6x|%6x|%6x|%10x|%10x|\n", 658 best_score, rx_params.dcgain, rx_params.dfe_3db_freq, 659 rx_params.dfe_gain, rx_params.dfe_first_tap_ctrl, 660 rx_params.dfe_secound_tap_ctrl, rx_params.dfe_third_tap_ctrl, 661 rx_params.dfe_fourth_tap_ctrl, rx_params.low_freq_agc_gain, 662 rx_params.high_freq_agc_boost); 663 664 return (0); 665 } 666 667 static int al_eth_lm_retimer_boost_config(struct al_eth_lm_context *lm_context) 668 { 669 int i; 670 int rc = 0; 671 uint8_t boost = 0; 672 uint32_t boost_addr = 673 al_eth_retimer_boost_addr[lm_context->retimer_channel][lm_context->retimer_type]; 674 675 if (lm_context->mode != AL_ETH_LM_MODE_10G_DA) { 676 boost = al_eth_retimer_boost_value[0][lm_context->retimer_type]; 677 } else { 678 for (i = 0; i < RETIMER_LENS_MAX; i++) { 679 if (lm_context->da_len <= al_eth_retimer_boost_lens[i]) { 680 boost = al_eth_retimer_boost_value[i][lm_context->retimer_type]; 681 break; 682 } 683 } 684 685 if (i == RETIMER_LENS_MAX) 686 boost = al_eth_retimer_boost_value[RETIMER_LENS_MAX][lm_context->retimer_type]; 687 } 688 689 lm_debug("config retimer boost in channel %d (addr %x) to 0x%x\n", 690 lm_context->retimer_channel, boost_addr, boost); 691 692 rc = lm_context->i2c_write(lm_context->i2c_context, 693 lm_context->retimer_bus_id, lm_context->retimer_i2c_addr, 694 boost_addr, boost); 695 696 if (rc != 0) { 697 al_err("%s: Error occurred (%d) while writing retimer " 698 "configuration (bus-id %x i2c-addr %x)\n", 699 __func__, rc, lm_context->retimer_bus_id, 700 lm_context->retimer_i2c_addr); 701 return (rc); 702 } 703 704 return (0); 705 } 706 707 /******************************************************************************* 708 ************************** retimer DS25 *************************************** 709 ******************************************************************************/ 710 #define LM_DS25_CHANNEL_EN_REG 0xff 711 #define LM_DS25_CHANNEL_EN_MASK 0x03 712 #define LM_DS25_CHANNEL_EN_VAL 0x01 713 714 #define LM_DS25_CHANNEL_SEL_REG 0xfc 715 #define LM_DS25_CHANNEL_SEL_MASK 0xff 716 717 #define LM_DS25_CDR_RESET_REG 0x0a 718 #define LM_DS25_CDR_RESET_MASK 0x0c 719 #define LM_DS25_CDR_RESET_ASSERT 0x0c 720 #define LM_DS25_CDR_RESET_RELEASE 0x00 721 722 #define LM_DS25_SIGNAL_DETECT_REG 0x78 723 #define LM_DS25_SIGNAL_DETECT_MASK 0x20 724 725 #define LM_DS25_CDR_LOCK_REG 0x78 726 #define LM_DS25_CDR_LOCK_MASK 0x10 727 728 #define LM_DS25_DRV_PD_REG 0x15 729 #define LM_DS25_DRV_PD_MASK 0x08 730 731 static int al_eth_lm_retimer_ds25_write_reg(struct al_eth_lm_context *lm_context, 732 uint8_t reg_addr, 733 uint8_t reg_mask, 734 uint8_t reg_value) 735 { 736 uint8_t reg; 737 int rc; 738 739 rc = lm_context->i2c_read(lm_context->i2c_context, 740 lm_context->retimer_bus_id, 741 lm_context->retimer_i2c_addr, 742 reg_addr, 743 ®); 744 745 if (rc != 0) 746 return (EIO); 747 748 reg &= ~(reg_mask); 749 reg |= reg_value; 750 751 rc = lm_context->i2c_write(lm_context->i2c_context, 752 lm_context->retimer_bus_id, 753 lm_context->retimer_i2c_addr, 754 reg_addr, 755 reg); 756 757 if (rc != 0) 758 return (EIO); 759 760 return (0); 761 } 762 763 static int al_eth_lm_retimer_ds25_channel_select(struct al_eth_lm_context *lm_context, 764 uint8_t channel) 765 { 766 int rc = 0; 767 768 /* Write to specific channel */ 769 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 770 LM_DS25_CHANNEL_EN_REG, 771 LM_DS25_CHANNEL_EN_MASK, 772 LM_DS25_CHANNEL_EN_VAL); 773 774 if (rc != 0) 775 return (rc); 776 777 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 778 LM_DS25_CHANNEL_SEL_REG, 779 LM_DS25_CHANNEL_SEL_MASK, 780 (1 << channel)); 781 782 return (rc); 783 } 784 785 static int al_eth_lm_retimer_ds25_channel_config(struct al_eth_lm_context *lm_context, 786 uint8_t channel, 787 struct retimer_config_reg *config, 788 uint8_t config_size) 789 { 790 uint8_t i; 791 int rc; 792 793 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 794 if (rc != 0) 795 goto config_error; 796 797 for (i = 0; i < config_size; i++) { 798 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 799 config[i].addr, 800 config[i].mask, 801 config[i].value); 802 803 if (rc != 0) 804 goto config_error; 805 } 806 807 lm_debug("%s: retimer channel config done for channel %d\n", __func__, channel); 808 809 return (0); 810 811 config_error: 812 al_err("%s: failed to access to the retimer\n", __func__); 813 814 return (rc); 815 } 816 817 static int al_eth_lm_retimer_ds25_cdr_reset(struct al_eth_lm_context *lm_context, uint32_t channel) 818 { 819 int rc; 820 821 lm_debug("Perform CDR reset to channel %d\n", channel); 822 823 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 824 if (rc) 825 goto config_error; 826 827 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 828 LM_DS25_CDR_RESET_REG, 829 LM_DS25_CDR_RESET_MASK, 830 LM_DS25_CDR_RESET_ASSERT); 831 832 if (rc) 833 goto config_error; 834 835 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 836 LM_DS25_CDR_RESET_REG, 837 LM_DS25_CDR_RESET_MASK, 838 LM_DS25_CDR_RESET_RELEASE); 839 840 if (rc) 841 goto config_error; 842 843 return 0; 844 845 config_error: 846 al_err("%s: failed to access to the retimer\n", __func__); 847 848 return rc; 849 } 850 851 static bool al_eth_lm_retimer_ds25_signal_detect(struct al_eth_lm_context *lm_context, 852 uint32_t channel) 853 { 854 int rc = 0; 855 uint8_t reg; 856 857 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 858 if (rc) 859 goto config_error; 860 861 rc = lm_context->i2c_read(lm_context->i2c_context, 862 lm_context->retimer_bus_id, 863 lm_context->retimer_i2c_addr, 864 LM_DS25_SIGNAL_DETECT_REG, 865 ®); 866 867 if (rc) 868 goto config_error; 869 870 if (reg & LM_DS25_SIGNAL_DETECT_MASK) 871 return true; 872 873 return false; 874 875 config_error: 876 al_err("%s: failed to access to the retimer\n", __func__); 877 878 return false; 879 } 880 881 static bool al_eth_lm_retimer_ds25_cdr_lock(struct al_eth_lm_context *lm_context, 882 uint32_t channel) 883 { 884 int rc = 0; 885 uint8_t reg; 886 887 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 888 if (rc) 889 goto config_error; 890 891 rc = lm_context->i2c_read(lm_context->i2c_context, 892 lm_context->retimer_bus_id, 893 lm_context->retimer_i2c_addr, 894 LM_DS25_CDR_LOCK_REG, 895 ®); 896 897 if (rc) 898 goto config_error; 899 900 if (reg & LM_DS25_CDR_LOCK_MASK) 901 return true; 902 903 return false; 904 905 config_error: 906 al_err("%s: failed to access to the retimer\n", __func__); 907 908 return false; 909 } 910 911 static bool al_eth_lm_wait_for_lock(struct al_eth_lm_context *lm_context, 912 uint32_t channel) 913 { 914 uint32_t timeout = AL_ETH_LM_RETIMER_WAIT_FOR_LOCK; 915 bool lock = false; 916 917 while ((timeout > 0) && (!lock)) { 918 al_msleep(10); 919 timeout -= 10; 920 921 lock = retimer[lm_context->retimer_type].cdr_lock(lm_context, channel); 922 } 923 924 lm_debug("%s: %s to achieve CDR lock in %d msec\n", 925 __func__, (lock) ? "succeed" : "FAILED", 926 (AL_ETH_LM_RETIMER_WAIT_FOR_LOCK - timeout)); 927 928 return lock; 929 } 930 931 static void al_eth_lm_retimer_signal_lock_check(struct al_eth_lm_context *lm_context, 932 uint32_t channel, 933 bool *ready) 934 { 935 bool signal_detect = true; 936 bool cdr_lock = true; 937 938 if (retimer[lm_context->retimer_type].signal_detect) { 939 if (!retimer[lm_context->retimer_type].signal_detect(lm_context, channel)) { 940 lm_debug("no signal detected on retimer channel %d\n", channel); 941 942 signal_detect = false; 943 } else { 944 if (retimer[lm_context->retimer_type].cdr_lock) { 945 cdr_lock = retimer[lm_context->retimer_type].cdr_lock( 946 lm_context, 947 channel); 948 if (!cdr_lock) { 949 if (retimer[lm_context->retimer_type].reset) { 950 retimer[lm_context->retimer_type].reset(lm_context, 951 channel); 952 953 cdr_lock = al_eth_lm_wait_for_lock(lm_context, 954 channel); 955 } 956 } 957 } 958 } 959 } 960 961 al_info("%s: (channel %d) signal %d cdr lock %d\n", 962 __func__, channel, signal_detect, (signal_detect) ? cdr_lock : 0); 963 964 *ready = (cdr_lock && signal_detect); 965 } 966 967 static int al_eth_lm_retimer_ds25_full_config(struct al_eth_lm_context *lm_context) 968 { 969 int rc = 0; 970 bool ready; 971 struct retimer_config_reg *config_tx; 972 uint32_t config_tx_size; 973 struct retimer_config_reg *config_rx; 974 uint32_t config_rx_size; 975 976 if (lm_context->mode == AL_ETH_LM_MODE_25G) { 977 config_tx = retimer_ds25_25g_mode_tx_ch; 978 config_tx_size = AL_ARR_SIZE(retimer_ds25_25g_mode_tx_ch); 979 980 config_rx = retimer_ds25_25g_mode_rx_ch; 981 config_rx_size = AL_ARR_SIZE(retimer_ds25_25g_mode_rx_ch); 982 983 } else { 984 config_tx = retimer_ds25_10g_mode; 985 config_tx_size = AL_ARR_SIZE(retimer_ds25_10g_mode); 986 987 config_rx = retimer_ds25_10g_mode; 988 config_rx_size = AL_ARR_SIZE(retimer_ds25_10g_mode); 989 } 990 991 rc = al_eth_lm_retimer_ds25_channel_config(lm_context, 992 lm_context->retimer_channel, 993 config_rx, 994 config_rx_size); 995 996 if (rc) 997 return rc; 998 999 rc = al_eth_lm_retimer_ds25_channel_config(lm_context, 1000 lm_context->retimer_tx_channel, 1001 config_tx, 1002 config_tx_size); 1003 1004 if (rc) 1005 return rc; 1006 1007 if (lm_context->serdes_obj->type_get() == AL_SRDS_TYPE_25G) { 1008 lm_debug("%s: serdes 25G - perform tx and rx gearbox reset\n", __func__); 1009 al_eth_gearbox_reset(lm_context->adapter, AL_TRUE, AL_TRUE); 1010 DELAY(AL_ETH_LM_GEARBOX_RESET_DELAY); 1011 } 1012 1013 al_eth_lm_retimer_signal_lock_check(lm_context, lm_context->retimer_tx_channel, &ready); 1014 1015 if (!ready) { 1016 lm_debug("%s: Failed to lock tx channel!\n", __func__); 1017 return (1); 1018 } 1019 1020 lm_debug("%s: retimer full configuration done\n", __func__); 1021 1022 return rc; 1023 } 1024 1025 static int al_eth_lm_retimer_25g_rx_adaptation(struct al_eth_lm_context *lm_context) 1026 { 1027 int rc = 0; 1028 bool ready; 1029 1030 al_eth_lm_retimer_signal_lock_check(lm_context, lm_context->retimer_channel, &ready); 1031 1032 if (!ready) { 1033 lm_debug("%s: no signal detected on retimer Rx channel (%d)\n", 1034 __func__, lm_context->retimer_channel); 1035 1036 return rc; 1037 } 1038 1039 al_msleep(AL_ETH_LM_SERDES_WAIT_FOR_LOCK); 1040 1041 return 0; 1042 } 1043 1044 static int al_eth_lm_check_for_link(struct al_eth_lm_context *lm_context, bool *link_up) 1045 { 1046 struct al_eth_link_status status; 1047 int ret = 0; 1048 1049 al_eth_link_status_clear(lm_context->adapter); 1050 al_eth_link_status_get(lm_context->adapter, &status); 1051 1052 if (status.link_up == AL_TRUE) { 1053 lm_debug("%s: >>>> Link state DOWN ==> UP\n", __func__); 1054 al_eth_led_set(lm_context->adapter, AL_TRUE); 1055 lm_context->link_state = AL_ETH_LM_LINK_UP; 1056 *link_up = true; 1057 1058 return 0; 1059 } else if (status.local_fault) { 1060 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1061 al_eth_led_set(lm_context->adapter, AL_FALSE); 1062 1063 al_err("%s: Failed to establish link\n", __func__); 1064 ret = 1; 1065 } else { 1066 lm_debug("%s: >>>> Link state DOWN ==> DOWN_RF\n", __func__); 1067 lm_context->link_state = AL_ETH_LM_LINK_DOWN_RF; 1068 al_eth_led_set(lm_context->adapter, AL_FALSE); 1069 1070 ret = 0; 1071 } 1072 1073 *link_up = false; 1074 return ret; 1075 } 1076 1077 /*****************************************************************************/ 1078 /***************************** API functions *********************************/ 1079 /*****************************************************************************/ 1080 int 1081 al_eth_lm_init(struct al_eth_lm_context *lm_context, 1082 struct al_eth_lm_init_params *params) 1083 { 1084 1085 lm_context->adapter = params->adapter; 1086 lm_context->serdes_obj = params->serdes_obj; 1087 lm_context->lane = params->lane; 1088 lm_context->sfp_detection = params->sfp_detection; 1089 lm_context->sfp_bus_id = params->sfp_bus_id; 1090 lm_context->sfp_i2c_addr = params->sfp_i2c_addr; 1091 1092 lm_context->retimer_exist = params->retimer_exist; 1093 lm_context->retimer_type = params->retimer_type; 1094 lm_context->retimer_bus_id = params->retimer_bus_id; 1095 lm_context->retimer_i2c_addr = params->retimer_i2c_addr; 1096 lm_context->retimer_channel = params->retimer_channel; 1097 lm_context->retimer_tx_channel = params->retimer_tx_channel; 1098 1099 lm_context->default_mode = params->default_mode; 1100 lm_context->default_dac_len = params->default_dac_len; 1101 lm_context->link_training = params->link_training; 1102 lm_context->rx_equal = params->rx_equal; 1103 lm_context->static_values = params->static_values; 1104 lm_context->i2c_read = params->i2c_read; 1105 lm_context->i2c_write = params->i2c_write; 1106 lm_context->i2c_context = params->i2c_context; 1107 lm_context->get_random_byte = params->get_random_byte; 1108 1109 /* eeprom_read must be provided if sfp_detection is true */ 1110 al_assert((lm_context->sfp_detection == false) || 1111 (lm_context->i2c_read != NULL)); 1112 1113 al_assert((lm_context->retimer_exist == false) || 1114 (lm_context->i2c_write != NULL)); 1115 1116 lm_context->local_adv.selector_field = 1; 1117 lm_context->local_adv.capability = 0; 1118 lm_context->local_adv.remote_fault = 0; 1119 lm_context->local_adv.acknowledge = 0; 1120 lm_context->local_adv.next_page = 0; 1121 lm_context->local_adv.technology = AL_ETH_AN_TECH_10GBASE_KR; 1122 lm_context->local_adv.fec_capability = params->kr_fec_enable; 1123 1124 lm_context->mode = AL_ETH_LM_MODE_DISCONNECTED; 1125 lm_context->serdes_tx_params_valid = false; 1126 lm_context->serdes_rx_params_valid = false; 1127 1128 lm_context->rx_param_dirty = 1; 1129 lm_context->tx_param_dirty = 1; 1130 1131 lm_context->gpio_get = params->gpio_get; 1132 lm_context->gpio_present = params->gpio_present; 1133 1134 lm_context->max_speed = params->max_speed; 1135 lm_context->sfp_detect_force_mode = params->sfp_detect_force_mode; 1136 1137 lm_context->lm_pause = params->lm_pause; 1138 1139 lm_context->led_config = params->led_config; 1140 1141 lm_context->retimer_configured = false; 1142 1143 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1144 1145 return (0); 1146 } 1147 1148 int 1149 al_eth_lm_link_detection(struct al_eth_lm_context *lm_context, 1150 bool *link_fault, enum al_eth_lm_link_mode *old_mode, 1151 enum al_eth_lm_link_mode *new_mode) 1152 { 1153 int err; 1154 struct al_eth_link_status status; 1155 1156 al_assert(lm_context != NULL); 1157 al_assert(old_mode != NULL); 1158 al_assert(new_mode != NULL); 1159 1160 /** 1161 * if Link management is disabled, report no link fault in case the link was up 1162 * before and set new mode to disconnected to avoid calling to link establish 1163 * if the link wasn't up. 1164 */ 1165 if (lm_context->lm_pause != NULL) { 1166 bool lm_pause = lm_context->lm_pause(lm_context->i2c_context); 1167 if (lm_pause == true) { 1168 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 1169 if (link_fault != NULL) { 1170 if (lm_context->link_state == AL_ETH_LM_LINK_UP) 1171 *link_fault = false; 1172 else 1173 *link_fault = true; 1174 } 1175 1176 return 0; 1177 } 1178 } 1179 1180 *old_mode = lm_context->mode; 1181 *new_mode = lm_context->mode; 1182 1183 if (link_fault != NULL) 1184 *link_fault = true; 1185 1186 switch (lm_context->link_state) { 1187 case AL_ETH_LM_LINK_UP: 1188 al_eth_link_status_get(lm_context->adapter, &status); 1189 1190 if (status.link_up) { 1191 if (link_fault != NULL) 1192 *link_fault = false; 1193 1194 al_eth_led_set(lm_context->adapter, AL_TRUE); 1195 1196 return (0); 1197 } else if (status.local_fault) { 1198 lm_debug("%s: >>>> Link state UP ==> DOWN\n", __func__); 1199 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1200 } else { 1201 lm_debug("%s: >>>> Link state UP ==> DOWN_RF\n", __func__); 1202 lm_context->link_state = AL_ETH_LM_LINK_DOWN_RF; 1203 } 1204 1205 break; 1206 case AL_ETH_LM_LINK_DOWN_RF: 1207 al_eth_link_status_get(lm_context->adapter, &status); 1208 1209 if (status.local_fault) { 1210 lm_debug("%s: >>>> Link state DOWN_RF ==> DOWN\n", __func__); 1211 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1212 1213 break; 1214 } else if (status.remote_fault == AL_FALSE) { 1215 lm_debug("%s: >>>> Link state DOWN_RF ==> UP\n", __func__); 1216 lm_context->link_state = AL_ETH_LM_LINK_UP; 1217 } 1218 /* in case of remote fault only no need to check SFP again */ 1219 return (0); 1220 case AL_ETH_LM_LINK_DOWN: 1221 break; 1222 }; 1223 1224 al_eth_led_set(lm_context->adapter, AL_FALSE); 1225 1226 if (lm_context->sfp_detection) { 1227 err = al_eth_module_detect(lm_context, new_mode); 1228 if (err != 0) { 1229 al_err("module_detection failed!\n"); 1230 return (err); 1231 } 1232 1233 lm_context->mode = *new_mode; 1234 } else { 1235 lm_context->mode = lm_context->default_mode; 1236 *new_mode = lm_context->mode; 1237 } 1238 1239 if (*old_mode != *new_mode) { 1240 al_info("%s: New SFP mode detected %s -> %s\n", 1241 __func__, al_eth_lm_mode_convert_to_str(*old_mode), 1242 al_eth_lm_mode_convert_to_str(*new_mode)); 1243 1244 lm_context->rx_param_dirty = 1; 1245 lm_context->tx_param_dirty = 1; 1246 1247 lm_context->new_port = true; 1248 1249 if ((*new_mode != AL_ETH_LM_MODE_DISCONNECTED) && (lm_context->led_config)) { 1250 struct al_eth_lm_led_config_data data = {0}; 1251 1252 switch (*new_mode) { 1253 case AL_ETH_LM_MODE_10G_OPTIC: 1254 case AL_ETH_LM_MODE_10G_DA: 1255 data.speed = AL_ETH_LM_LED_CONFIG_10G; 1256 break; 1257 case AL_ETH_LM_MODE_1G: 1258 data.speed = AL_ETH_LM_LED_CONFIG_1G; 1259 break; 1260 case AL_ETH_LM_MODE_25G: 1261 data.speed = AL_ETH_LM_LED_CONFIG_25G; 1262 break; 1263 default: 1264 al_err("%s: unknown LM mode!\n", __func__); 1265 }; 1266 1267 lm_context->led_config(lm_context->i2c_context, &data); 1268 } 1269 } 1270 1271 return (0); 1272 } 1273 1274 int 1275 al_eth_lm_link_establish(struct al_eth_lm_context *lm_context, bool *link_up) 1276 { 1277 bool signal_detected; 1278 int ret = 0; 1279 1280 switch (lm_context->link_state) { 1281 case AL_ETH_LM_LINK_UP: 1282 *link_up = true; 1283 lm_debug("%s: return link up\n", __func__); 1284 1285 return (0); 1286 case AL_ETH_LM_LINK_DOWN_RF: 1287 *link_up = false; 1288 lm_debug("%s: return link down (DOWN_RF)\n", __func__); 1289 1290 return (0); 1291 case AL_ETH_LM_LINK_DOWN: 1292 break; 1293 }; 1294 1295 /** 1296 * At this point we will get LM disable only if changed to disable after link detection 1297 * finished. in this case link will not be established until LM will be enable again. 1298 */ 1299 if (lm_context->lm_pause) { 1300 bool lm_pause = lm_context->lm_pause(lm_context->i2c_context); 1301 if (lm_pause == true) { 1302 *link_up = false; 1303 1304 return (0); 1305 } 1306 } 1307 1308 if ((lm_context->new_port) && (lm_context->retimer_exist)) { 1309 al_eth_serdes_static_rx_params_set(lm_context); 1310 al_eth_serdes_static_tx_params_set(lm_context); 1311 #if 0 1312 al_eth_lm_retimer_config(lm_context); 1313 DELAY(AL_ETH_LM_RETIMER_LINK_STATUS_DELAY); 1314 #endif 1315 1316 if (retimer[lm_context->retimer_type].config(lm_context)) { 1317 al_info("%s: failed to configure the retimer\n", __func__); 1318 1319 *link_up = false; 1320 return (1); 1321 } 1322 1323 lm_context->new_port = false; 1324 1325 DELAY(1000); 1326 } 1327 1328 if (lm_context->retimer_exist) { 1329 if (retimer[lm_context->retimer_type].rx_adaptation) { 1330 ret = retimer[lm_context->retimer_type].rx_adaptation(lm_context); 1331 1332 if (ret != 0) { 1333 lm_debug("retimer rx is not ready\n"); 1334 *link_up = false; 1335 1336 return (0); 1337 } 1338 } 1339 } 1340 1341 signal_detected = lm_context->serdes_obj->signal_is_detected( 1342 lm_context->serdes_obj, 1343 lm_context->lane); 1344 1345 if (signal_detected == false) { 1346 /* if no signal detected there is nothing to do */ 1347 lm_debug("serdes signal is down\n"); 1348 *link_up = false; 1349 return 0; 1350 } 1351 1352 if (lm_context->serdes_obj->type_get() == AL_SRDS_TYPE_25G) { 1353 lm_debug("%s: serdes 25G - perform rx gearbox reset\n", __func__); 1354 al_eth_gearbox_reset(lm_context->adapter, AL_FALSE, AL_TRUE); 1355 DELAY(AL_ETH_LM_GEARBOX_RESET_DELAY); 1356 } 1357 1358 if (lm_context->retimer_exist) { 1359 DELAY(AL_ETH_LM_RETIMER_LINK_STATUS_DELAY); 1360 1361 ret = al_eth_lm_check_for_link(lm_context, link_up); 1362 1363 if (ret == 0) { 1364 lm_debug("%s: link is up with retimer\n", __func__); 1365 return 0; 1366 } 1367 1368 return ret; 1369 } 1370 1371 if ((lm_context->mode == AL_ETH_LM_MODE_10G_DA) && (lm_context->link_training)) { 1372 lm_context->local_adv.transmitted_nonce = lm_context->get_random_byte(); 1373 lm_context->local_adv.transmitted_nonce &= 0x1f; 1374 1375 ret = al_eth_an_lt_execute(lm_context->adapter, 1376 lm_context->serdes_obj, 1377 lm_context->lane, 1378 &lm_context->local_adv, 1379 &lm_context->partner_adv); 1380 1381 lm_context->rx_param_dirty = 1; 1382 lm_context->tx_param_dirty = 1; 1383 1384 if (ret == 0) { 1385 al_info("%s: link training finished successfully\n", __func__); 1386 lm_context->link_training_failures = 0; 1387 ret = al_eth_lm_check_for_link(lm_context, link_up); 1388 1389 if (ret == 0) { 1390 lm_debug("%s: link is up with LT\n", __func__); 1391 return (0); 1392 } 1393 } 1394 1395 lm_context->link_training_failures++; 1396 if (lm_context->link_training_failures > AL_ETH_LT_FAILURES_TO_RESET) { 1397 lm_debug("%s: failed to establish LT %d times. reset serdes\n", 1398 __func__, AL_ETH_LT_FAILURES_TO_RESET); 1399 1400 lm_context->serdes_obj->pma_hard_reset_lane( 1401 lm_context->serdes_obj, 1402 lm_context->lane, 1403 AL_TRUE); 1404 lm_context->serdes_obj->pma_hard_reset_lane( 1405 lm_context->serdes_obj, 1406 lm_context->lane, 1407 AL_FALSE); 1408 lm_context->link_training_failures = 0; 1409 } 1410 } 1411 1412 al_eth_serdes_static_tx_params_set(lm_context); 1413 1414 if ((lm_context->mode == AL_ETH_LM_MODE_10G_DA) && 1415 (lm_context->rx_equal)) { 1416 ret = al_eth_rx_equal_run(lm_context); 1417 1418 if (ret == 0) { 1419 DELAY(AL_ETH_LM_LINK_STATUS_DELAY); 1420 ret = al_eth_lm_check_for_link(lm_context, link_up); 1421 1422 if (ret == 0) { 1423 lm_debug("%s: link is up with Rx Equalization\n", __func__); 1424 return (0); 1425 } 1426 } 1427 } 1428 1429 al_eth_serdes_static_rx_params_set(lm_context); 1430 1431 DELAY(AL_ETH_LM_LINK_STATUS_DELAY); 1432 1433 ret = al_eth_lm_check_for_link(lm_context, link_up); 1434 1435 if (ret == 0) { 1436 lm_debug("%s: link is up with static parameters\n", __func__); 1437 return (0); 1438 } 1439 1440 *link_up = false; 1441 return (1); 1442 } 1443 1444 int 1445 al_eth_lm_static_parameters_override(struct al_eth_lm_context *lm_context, 1446 struct al_serdes_adv_tx_params *tx_params, 1447 struct al_serdes_adv_rx_params *rx_params) 1448 { 1449 1450 if (tx_params != NULL) { 1451 lm_context->tx_params_override = *tx_params; 1452 lm_context->tx_param_dirty = 1; 1453 lm_context->serdes_tx_params_valid = true; 1454 } 1455 1456 if (rx_params != NULL) { 1457 lm_context->rx_params_override = *rx_params; 1458 lm_context->rx_param_dirty = 1; 1459 lm_context->serdes_rx_params_valid = true; 1460 } 1461 1462 return (0); 1463 } 1464 1465 int 1466 al_eth_lm_static_parameters_override_disable(struct al_eth_lm_context *lm_context, 1467 bool tx_params, bool rx_params) 1468 { 1469 1470 if (tx_params) 1471 lm_context->serdes_tx_params_valid = false; 1472 if (rx_params) 1473 lm_context->serdes_tx_params_valid = false; 1474 1475 return (0); 1476 } 1477 1478 int 1479 al_eth_lm_static_parameters_get(struct al_eth_lm_context *lm_context, 1480 struct al_serdes_adv_tx_params *tx_params, 1481 struct al_serdes_adv_rx_params *rx_params) 1482 { 1483 1484 if (tx_params != NULL) { 1485 if (lm_context->serdes_tx_params_valid) 1486 *tx_params = lm_context->tx_params_override; 1487 else 1488 lm_context->serdes_obj->tx_advanced_params_get( 1489 lm_context->serdes_obj, 1490 lm_context->lane, 1491 tx_params); 1492 } 1493 1494 if (rx_params != NULL) { 1495 if (lm_context->serdes_rx_params_valid) 1496 *rx_params = lm_context->rx_params_override; 1497 else 1498 lm_context->serdes_obj->rx_advanced_params_get( 1499 lm_context->serdes_obj, 1500 lm_context->lane, 1501 rx_params); 1502 } 1503 1504 return (0); 1505 } 1506 1507 const char * 1508 al_eth_lm_mode_convert_to_str(enum al_eth_lm_link_mode val) 1509 { 1510 1511 switch (val) { 1512 case AL_ETH_LM_MODE_DISCONNECTED: 1513 return ("AL_ETH_LM_MODE_DISCONNECTED"); 1514 case AL_ETH_LM_MODE_10G_OPTIC: 1515 return ("AL_ETH_LM_MODE_10G_OPTIC"); 1516 case AL_ETH_LM_MODE_10G_DA: 1517 return ("AL_ETH_LM_MODE_10G_DA"); 1518 case AL_ETH_LM_MODE_1G: 1519 return ("AL_ETH_LM_MODE_1G"); 1520 case AL_ETH_LM_MODE_25G: 1521 return ("AL_ETH_LM_MODE_25G"); 1522 } 1523 1524 return ("N/A"); 1525 } 1526 1527 void 1528 al_eth_lm_debug_mode_set(struct al_eth_lm_context *lm_context, 1529 bool enable) 1530 { 1531 1532 lm_context->debug = enable; 1533 } 1534