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