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 al_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 al_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 int (*signal_detect)(struct al_eth_lm_context *lm_context, uint32_t channel); 220 int (*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 = 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 = 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 = 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 = 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 = 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 = 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 555 } else if (lm_context->static_values != 0) { 556 lm_context->rx_param_dirty = 0; 557 558 if ((lm_context->serdes_obj->rx_advanced_params_set) == 0) { 559 al_err("rx_advanced_params_set is not supported for this serdes group\n"); 560 return; 561 } 562 563 if ((lm_context->retimer_exist == 0) && 564 (lm_context->mode == AL_ETH_LM_MODE_10G_DA)) 565 lm_context->serdes_obj->rx_advanced_params_set( 566 lm_context->serdes_obj, 567 lm_context->lane, 568 &da_rx_params); 569 else 570 lm_context->serdes_obj->rx_advanced_params_set( 571 lm_context->serdes_obj, 572 lm_context->lane, 573 &optic_rx_params); 574 } 575 } 576 577 static int 578 al_eth_rx_equal_run(struct al_eth_lm_context *lm_context) 579 { 580 struct al_serdes_adv_rx_params rx_params; 581 int dcgain; 582 int best_dcgain = -1; 583 int i; 584 int best_score = -1; 585 int test_score = -1; 586 587 rx_params.override = FALSE; 588 lm_context->serdes_obj->rx_advanced_params_set(lm_context->serdes_obj, 589 lm_context->lane, &rx_params); 590 591 lm_debug("score | dcgain | dfe3db | dfegain | tap1 | tap2 | tap3 | " 592 "tap4 | low freq | high freq\n"); 593 594 for (dcgain = 0; dcgain < AL_ETH_LM_MAX_DCGAIN; dcgain++) { 595 lm_context->serdes_obj->dcgain_set( 596 lm_context->serdes_obj, 597 dcgain); 598 599 test_score = lm_context->serdes_obj->rx_equalization( 600 lm_context->serdes_obj, 601 lm_context->lane); 602 603 if (test_score < 0) { 604 al_warn("serdes rx equalization failed on error\n"); 605 return (test_score); 606 } 607 608 if (test_score > best_score) { 609 best_score = test_score; 610 best_dcgain = dcgain; 611 } 612 613 lm_context->serdes_obj->rx_advanced_params_get( 614 lm_context->serdes_obj, 615 lm_context->lane, 616 &rx_params); 617 618 lm_debug("%6d|%8x|%8x|%9x|%6x|%6x|%6x|%6x|%10x|%10x|\n", 619 test_score, rx_params.dcgain, rx_params.dfe_3db_freq, 620 rx_params.dfe_gain, rx_params.dfe_first_tap_ctrl, 621 rx_params.dfe_secound_tap_ctrl, rx_params.dfe_third_tap_ctrl, 622 rx_params.dfe_fourth_tap_ctrl, rx_params.low_freq_agc_gain, 623 rx_params.high_freq_agc_boost); 624 } 625 626 lm_context->serdes_obj->dcgain_set( 627 lm_context->serdes_obj, 628 best_dcgain); 629 630 best_score = -1; 631 for(i = 0; i < AL_ETH_LM_EQ_ITERATIONS; i++) { 632 test_score = lm_context->serdes_obj->rx_equalization( 633 lm_context->serdes_obj, 634 lm_context->lane); 635 636 if (test_score < 0) { 637 al_warn("serdes rx equalization failed on error\n"); 638 return (test_score); 639 } 640 641 if (test_score > best_score) { 642 best_score = test_score; 643 lm_context->serdes_obj->rx_advanced_params_get( 644 lm_context->serdes_obj, 645 lm_context->lane, 646 &rx_params); 647 } 648 } 649 650 rx_params.precal_code_sel = 0; 651 rx_params.override = TRUE; 652 lm_context->serdes_obj->rx_advanced_params_set( 653 lm_context->serdes_obj, 654 lm_context->lane, 655 &rx_params); 656 657 lm_debug("-------------------- best dcgain %d ------------------------------------\n", best_dcgain); 658 lm_debug("%6d|%8x|%8x|%9x|%6x|%6x|%6x|%6x|%10x|%10x|\n", 659 best_score, rx_params.dcgain, rx_params.dfe_3db_freq, 660 rx_params.dfe_gain, rx_params.dfe_first_tap_ctrl, 661 rx_params.dfe_secound_tap_ctrl, rx_params.dfe_third_tap_ctrl, 662 rx_params.dfe_fourth_tap_ctrl, rx_params.low_freq_agc_gain, 663 rx_params.high_freq_agc_boost); 664 665 return (0); 666 } 667 668 static int al_eth_lm_retimer_boost_config(struct al_eth_lm_context *lm_context) 669 { 670 int i; 671 int rc = 0; 672 uint8_t boost = 0; 673 uint32_t boost_addr = 674 al_eth_retimer_boost_addr[lm_context->retimer_channel][lm_context->retimer_type]; 675 676 if (lm_context->mode != AL_ETH_LM_MODE_10G_DA) { 677 boost = al_eth_retimer_boost_value[0][lm_context->retimer_type]; 678 } else { 679 for (i = 0; i < RETIMER_LENS_MAX; i++) { 680 if (lm_context->da_len <= al_eth_retimer_boost_lens[i]) { 681 boost = al_eth_retimer_boost_value[i][lm_context->retimer_type]; 682 break; 683 } 684 } 685 686 if (i == RETIMER_LENS_MAX) 687 boost = al_eth_retimer_boost_value[RETIMER_LENS_MAX][lm_context->retimer_type]; 688 } 689 690 lm_debug("config retimer boost in channel %d (addr %x) to 0x%x\n", 691 lm_context->retimer_channel, boost_addr, boost); 692 693 rc = lm_context->i2c_write(lm_context->i2c_context, 694 lm_context->retimer_bus_id, lm_context->retimer_i2c_addr, 695 boost_addr, boost); 696 697 if (rc != 0) { 698 al_err("%s: Error occurred (%d) while writing retimer " 699 "configuration (bus-id %x i2c-addr %x)\n", 700 __func__, rc, lm_context->retimer_bus_id, 701 lm_context->retimer_i2c_addr); 702 return (rc); 703 } 704 705 return (0); 706 } 707 708 /******************************************************************************* 709 ************************** retimer DS25 *************************************** 710 ******************************************************************************/ 711 #define LM_DS25_CHANNEL_EN_REG 0xff 712 #define LM_DS25_CHANNEL_EN_MASK 0x03 713 #define LM_DS25_CHANNEL_EN_VAL 0x01 714 715 #define LM_DS25_CHANNEL_SEL_REG 0xfc 716 #define LM_DS25_CHANNEL_SEL_MASK 0xff 717 718 #define LM_DS25_CDR_RESET_REG 0x0a 719 #define LM_DS25_CDR_RESET_MASK 0x0c 720 #define LM_DS25_CDR_RESET_ASSERT 0x0c 721 #define LM_DS25_CDR_RESET_RELEASE 0x00 722 723 #define LM_DS25_SIGNAL_DETECT_REG 0x78 724 #define LM_DS25_SIGNAL_DETECT_MASK 0x20 725 726 #define LM_DS25_CDR_LOCK_REG 0x78 727 #define LM_DS25_CDR_LOCK_MASK 0x10 728 729 #define LM_DS25_DRV_PD_REG 0x15 730 #define LM_DS25_DRV_PD_MASK 0x08 731 732 static int al_eth_lm_retimer_ds25_write_reg(struct al_eth_lm_context *lm_context, 733 uint8_t reg_addr, 734 uint8_t reg_mask, 735 uint8_t reg_value) 736 { 737 uint8_t reg; 738 int rc; 739 740 rc = lm_context->i2c_read(lm_context->i2c_context, 741 lm_context->retimer_bus_id, 742 lm_context->retimer_i2c_addr, 743 reg_addr, 744 ®); 745 746 if (rc != 0) 747 return (EIO); 748 749 reg &= ~(reg_mask); 750 reg |= reg_value; 751 752 rc = lm_context->i2c_write(lm_context->i2c_context, 753 lm_context->retimer_bus_id, 754 lm_context->retimer_i2c_addr, 755 reg_addr, 756 reg); 757 758 if (rc != 0) 759 return (EIO); 760 761 return (0); 762 } 763 764 static int al_eth_lm_retimer_ds25_channel_select(struct al_eth_lm_context *lm_context, 765 uint8_t channel) 766 { 767 int rc = 0; 768 769 /* Write to specific channel */ 770 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 771 LM_DS25_CHANNEL_EN_REG, 772 LM_DS25_CHANNEL_EN_MASK, 773 LM_DS25_CHANNEL_EN_VAL); 774 775 if (rc != 0) 776 return (rc); 777 778 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 779 LM_DS25_CHANNEL_SEL_REG, 780 LM_DS25_CHANNEL_SEL_MASK, 781 (1 << channel)); 782 783 return (rc); 784 } 785 786 static int al_eth_lm_retimer_ds25_channel_config(struct al_eth_lm_context *lm_context, 787 uint8_t channel, 788 struct retimer_config_reg *config, 789 uint8_t config_size) 790 { 791 uint8_t i; 792 int rc; 793 794 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 795 if (rc != 0) 796 goto config_error; 797 798 for (i = 0; i < config_size; i++) { 799 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 800 config[i].addr, 801 config[i].mask, 802 config[i].value); 803 804 if (rc != 0) 805 goto config_error; 806 } 807 808 lm_debug("%s: retimer channel config done for channel %d\n", __func__, channel); 809 810 return (0); 811 812 config_error: 813 al_err("%s: failed to access to the retimer\n", __func__); 814 815 return (rc); 816 } 817 818 static int al_eth_lm_retimer_ds25_cdr_reset(struct al_eth_lm_context *lm_context, uint32_t channel) 819 { 820 int rc; 821 822 lm_debug("Perform CDR reset to channel %d\n", channel); 823 824 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 825 if (rc) 826 goto config_error; 827 828 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 829 LM_DS25_CDR_RESET_REG, 830 LM_DS25_CDR_RESET_MASK, 831 LM_DS25_CDR_RESET_ASSERT); 832 833 if (rc) 834 goto config_error; 835 836 rc = al_eth_lm_retimer_ds25_write_reg(lm_context, 837 LM_DS25_CDR_RESET_REG, 838 LM_DS25_CDR_RESET_MASK, 839 LM_DS25_CDR_RESET_RELEASE); 840 841 if (rc) 842 goto config_error; 843 844 return 0; 845 846 config_error: 847 al_err("%s: failed to access to the retimer\n", __func__); 848 849 return rc; 850 } 851 852 static boolean_t al_eth_lm_retimer_ds25_signal_detect(struct al_eth_lm_context *lm_context, 853 uint32_t channel) 854 { 855 int rc = 0; 856 uint8_t reg; 857 858 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 859 if (rc) 860 goto config_error; 861 862 rc = lm_context->i2c_read(lm_context->i2c_context, 863 lm_context->retimer_bus_id, 864 lm_context->retimer_i2c_addr, 865 LM_DS25_SIGNAL_DETECT_REG, 866 ®); 867 868 if (rc) 869 goto config_error; 870 871 if (reg & LM_DS25_SIGNAL_DETECT_MASK) 872 return TRUE; 873 874 return FALSE; 875 876 config_error: 877 al_err("%s: failed to access to the retimer\n", __func__); 878 879 return FALSE; 880 } 881 882 static boolean_t al_eth_lm_retimer_ds25_cdr_lock(struct al_eth_lm_context *lm_context, 883 uint32_t channel) 884 { 885 int rc = 0; 886 uint8_t reg; 887 888 rc = al_eth_lm_retimer_ds25_channel_select(lm_context, channel); 889 if (rc) 890 goto config_error; 891 892 rc = lm_context->i2c_read(lm_context->i2c_context, 893 lm_context->retimer_bus_id, 894 lm_context->retimer_i2c_addr, 895 LM_DS25_CDR_LOCK_REG, 896 ®); 897 898 if (rc) 899 goto config_error; 900 901 if (reg & LM_DS25_CDR_LOCK_MASK) 902 return TRUE; 903 904 return FALSE; 905 906 config_error: 907 al_err("%s: failed to access to the retimer\n", __func__); 908 909 return FALSE; 910 } 911 912 static boolean_t al_eth_lm_wait_for_lock(struct al_eth_lm_context *lm_context, 913 uint32_t channel) 914 { 915 uint32_t timeout = AL_ETH_LM_RETIMER_WAIT_FOR_LOCK; 916 al_bool lock = AL_FALSE; 917 918 while ((timeout > 0) && (lock == FALSE)) { 919 al_msleep(10); 920 timeout -= 10; 921 922 lock = retimer[lm_context->retimer_type].cdr_lock(lm_context, channel); 923 } 924 925 lm_debug("%s: %s to achieve CDR lock in %d msec\n", 926 __func__, (lock) ? "succeed" : "FAILED", 927 (AL_ETH_LM_RETIMER_WAIT_FOR_LOCK - timeout)); 928 929 return lock; 930 } 931 932 static void al_eth_lm_retimer_signal_lock_check(struct al_eth_lm_context *lm_context, 933 uint32_t channel, 934 boolean_t *ready) 935 { 936 al_bool signal_detect = TRUE; 937 al_bool cdr_lock = TRUE; 938 939 if (retimer[lm_context->retimer_type].signal_detect) { 940 if (!retimer[lm_context->retimer_type].signal_detect(lm_context, channel)) { 941 lm_debug("no signal detected on retimer channel %d\n", channel); 942 943 signal_detect = AL_FALSE; 944 } else { 945 if (retimer[lm_context->retimer_type].cdr_lock) { 946 cdr_lock = retimer[lm_context->retimer_type].cdr_lock( 947 lm_context, 948 channel); 949 if (!cdr_lock) { 950 if (retimer[lm_context->retimer_type].reset) { 951 retimer[lm_context->retimer_type].reset(lm_context, 952 channel); 953 954 cdr_lock = al_eth_lm_wait_for_lock(lm_context, 955 channel); 956 } 957 } 958 } 959 } 960 } 961 962 al_info("%s: (channel %d) signal %d cdr lock %d\n", 963 __func__, channel, signal_detect, (signal_detect) ? cdr_lock : 0); 964 965 *ready = ((cdr_lock == TRUE) && (signal_detect == TRUE)); 966 } 967 968 static int al_eth_lm_retimer_ds25_full_config(struct al_eth_lm_context *lm_context) 969 { 970 int rc = 0; 971 al_bool ready; 972 struct retimer_config_reg *config_tx; 973 uint32_t config_tx_size; 974 struct retimer_config_reg *config_rx; 975 uint32_t config_rx_size; 976 977 if (lm_context->mode == AL_ETH_LM_MODE_25G) { 978 config_tx = retimer_ds25_25g_mode_tx_ch; 979 config_tx_size = AL_ARR_SIZE(retimer_ds25_25g_mode_tx_ch); 980 981 config_rx = retimer_ds25_25g_mode_rx_ch; 982 config_rx_size = AL_ARR_SIZE(retimer_ds25_25g_mode_rx_ch); 983 984 } else { 985 config_tx = retimer_ds25_10g_mode; 986 config_tx_size = AL_ARR_SIZE(retimer_ds25_10g_mode); 987 988 config_rx = retimer_ds25_10g_mode; 989 config_rx_size = AL_ARR_SIZE(retimer_ds25_10g_mode); 990 } 991 992 993 rc = al_eth_lm_retimer_ds25_channel_config(lm_context, 994 lm_context->retimer_channel, 995 config_rx, 996 config_rx_size); 997 998 if (rc) 999 return rc; 1000 1001 rc = al_eth_lm_retimer_ds25_channel_config(lm_context, 1002 lm_context->retimer_tx_channel, 1003 config_tx, 1004 config_tx_size); 1005 1006 if (rc) 1007 return rc; 1008 1009 if (lm_context->serdes_obj->type_get() == AL_SRDS_TYPE_25G) { 1010 lm_debug("%s: serdes 25G - perform tx and rx gearbox reset\n", __func__); 1011 al_eth_gearbox_reset(lm_context->adapter, TRUE, TRUE); 1012 DELAY(AL_ETH_LM_GEARBOX_RESET_DELAY); 1013 } 1014 1015 al_eth_lm_retimer_signal_lock_check(lm_context, lm_context->retimer_tx_channel, &ready); 1016 1017 if (!ready) { 1018 lm_debug("%s: Failed to lock tx channel!\n", __func__); 1019 return (1); 1020 } 1021 1022 lm_debug("%s: retimer full configuration done\n", __func__); 1023 1024 return rc; 1025 } 1026 1027 static int al_eth_lm_retimer_25g_rx_adaptation(struct al_eth_lm_context *lm_context) 1028 { 1029 int rc = 0; 1030 al_bool ready; 1031 1032 al_eth_lm_retimer_signal_lock_check(lm_context, lm_context->retimer_channel, &ready); 1033 1034 if (!ready) { 1035 lm_debug("%s: no signal detected on retimer Rx channel (%d)\n", 1036 __func__, lm_context->retimer_channel); 1037 1038 return rc; 1039 } 1040 1041 al_msleep(AL_ETH_LM_SERDES_WAIT_FOR_LOCK); 1042 1043 return 0; 1044 } 1045 1046 static int al_eth_lm_check_for_link(struct al_eth_lm_context *lm_context, boolean_t *link_up) 1047 { 1048 struct al_eth_link_status status; 1049 int ret = 0; 1050 1051 al_eth_link_status_clear(lm_context->adapter); 1052 al_eth_link_status_get(lm_context->adapter, &status); 1053 1054 if (status.link_up == AL_TRUE) { 1055 lm_debug("%s: >>>> Link state DOWN ==> UP\n", __func__); 1056 al_eth_led_set(lm_context->adapter, AL_TRUE); 1057 lm_context->link_state = AL_ETH_LM_LINK_UP; 1058 *link_up = AL_TRUE; 1059 1060 return 0; 1061 } else if (status.local_fault) { 1062 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1063 al_eth_led_set(lm_context->adapter, AL_FALSE); 1064 1065 al_err("%s: Failed to establish link\n", __func__); 1066 ret = 1; 1067 } else { 1068 lm_debug("%s: >>>> Link state DOWN ==> DOWN_RF\n", __func__); 1069 lm_context->link_state = AL_ETH_LM_LINK_DOWN_RF; 1070 al_eth_led_set(lm_context->adapter, AL_FALSE); 1071 1072 ret = 0; 1073 } 1074 1075 *link_up = AL_FALSE; 1076 return ret; 1077 } 1078 1079 /*****************************************************************************/ 1080 /***************************** API functions *********************************/ 1081 /*****************************************************************************/ 1082 int 1083 al_eth_lm_init(struct al_eth_lm_context *lm_context, 1084 struct al_eth_lm_init_params *params) 1085 { 1086 1087 lm_context->adapter = params->adapter; 1088 lm_context->serdes_obj = params->serdes_obj; 1089 lm_context->lane = params->lane; 1090 lm_context->sfp_detection = params->sfp_detection; 1091 lm_context->sfp_bus_id = params->sfp_bus_id; 1092 lm_context->sfp_i2c_addr = params->sfp_i2c_addr; 1093 1094 lm_context->retimer_exist = params->retimer_exist; 1095 lm_context->retimer_type = params->retimer_type; 1096 lm_context->retimer_bus_id = params->retimer_bus_id; 1097 lm_context->retimer_i2c_addr = params->retimer_i2c_addr; 1098 lm_context->retimer_channel = params->retimer_channel; 1099 lm_context->retimer_tx_channel = params->retimer_tx_channel; 1100 1101 lm_context->default_mode = params->default_mode; 1102 lm_context->default_dac_len = params->default_dac_len; 1103 lm_context->link_training = params->link_training; 1104 lm_context->rx_equal = params->rx_equal; 1105 lm_context->static_values = params->static_values; 1106 lm_context->i2c_read = params->i2c_read; 1107 lm_context->i2c_write = params->i2c_write; 1108 lm_context->i2c_context = params->i2c_context; 1109 lm_context->get_random_byte = params->get_random_byte; 1110 1111 /* eeprom_read must be provided if sfp_detection is true */ 1112 al_assert((lm_context->sfp_detection == FALSE) || 1113 (lm_context->i2c_read != NULL)); 1114 1115 al_assert((lm_context->retimer_exist == FALSE) || 1116 (lm_context->i2c_write != NULL)); 1117 1118 lm_context->local_adv.selector_field = 1; 1119 lm_context->local_adv.capability = 0; 1120 lm_context->local_adv.remote_fault = 0; 1121 lm_context->local_adv.acknowledge = 0; 1122 lm_context->local_adv.next_page = 0; 1123 lm_context->local_adv.technology = AL_ETH_AN_TECH_10GBASE_KR; 1124 lm_context->local_adv.fec_capability = params->kr_fec_enable; 1125 1126 lm_context->mode = AL_ETH_LM_MODE_DISCONNECTED; 1127 lm_context->serdes_tx_params_valid = FALSE; 1128 lm_context->serdes_rx_params_valid = FALSE; 1129 1130 lm_context->rx_param_dirty = 1; 1131 lm_context->tx_param_dirty = 1; 1132 1133 lm_context->gpio_get = params->gpio_get; 1134 lm_context->gpio_present = params->gpio_present; 1135 1136 lm_context->max_speed = params->max_speed; 1137 lm_context->sfp_detect_force_mode = params->sfp_detect_force_mode; 1138 1139 lm_context->lm_pause = params->lm_pause; 1140 1141 lm_context->led_config = params->led_config; 1142 1143 lm_context->retimer_configured = FALSE; 1144 1145 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1146 1147 return (0); 1148 } 1149 1150 int 1151 al_eth_lm_link_detection(struct al_eth_lm_context *lm_context, 1152 boolean_t *link_fault, enum al_eth_lm_link_mode *old_mode, 1153 enum al_eth_lm_link_mode *new_mode) 1154 { 1155 int err; 1156 struct al_eth_link_status status; 1157 1158 al_assert(lm_context != NULL); 1159 al_assert(old_mode != NULL); 1160 al_assert(new_mode != NULL); 1161 1162 /** 1163 * if Link management is disabled, report no link fault in case the link was up 1164 * before and set new mode to disconnected to avoid calling to link establish 1165 * if the link wasn't up. 1166 */ 1167 if (lm_context->lm_pause != NULL) { 1168 boolean_t lm_pause = lm_context->lm_pause(lm_context->i2c_context); 1169 if (lm_pause == TRUE) { 1170 *new_mode = AL_ETH_LM_MODE_DISCONNECTED; 1171 if (link_fault != NULL) { 1172 if (lm_context->link_state == AL_ETH_LM_LINK_UP) 1173 *link_fault = FALSE; 1174 else 1175 *link_fault = TRUE; 1176 } 1177 1178 return 0; 1179 } 1180 } 1181 1182 *old_mode = lm_context->mode; 1183 *new_mode = lm_context->mode; 1184 1185 if (link_fault != NULL) 1186 *link_fault = TRUE; 1187 1188 switch (lm_context->link_state) { 1189 case AL_ETH_LM_LINK_UP: 1190 al_eth_link_status_get(lm_context->adapter, &status); 1191 1192 if (status.link_up) { 1193 if (link_fault != NULL) 1194 *link_fault = FALSE; 1195 1196 al_eth_led_set(lm_context->adapter, TRUE); 1197 1198 return (0); 1199 } else if (status.local_fault) { 1200 lm_debug("%s: >>>> Link state UP ==> DOWN\n", __func__); 1201 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1202 } else { 1203 lm_debug("%s: >>>> Link state UP ==> DOWN_RF\n", __func__); 1204 lm_context->link_state = AL_ETH_LM_LINK_DOWN_RF; 1205 } 1206 1207 break; 1208 case AL_ETH_LM_LINK_DOWN_RF: 1209 al_eth_link_status_get(lm_context->adapter, &status); 1210 1211 if (status.local_fault) { 1212 lm_debug("%s: >>>> Link state DOWN_RF ==> DOWN\n", __func__); 1213 lm_context->link_state = AL_ETH_LM_LINK_DOWN; 1214 1215 break; 1216 } else if (status.remote_fault == FALSE) { 1217 lm_debug("%s: >>>> Link state DOWN_RF ==> UP\n", __func__); 1218 lm_context->link_state = AL_ETH_LM_LINK_UP; 1219 } 1220 /* in case of remote fault only no need to check SFP again */ 1221 return (0); 1222 case AL_ETH_LM_LINK_DOWN: 1223 break; 1224 }; 1225 1226 al_eth_led_set(lm_context->adapter, FALSE); 1227 1228 if (lm_context->sfp_detection) { 1229 err = al_eth_module_detect(lm_context, new_mode); 1230 if (err != 0) { 1231 al_err("module_detection failed!\n"); 1232 return (err); 1233 } 1234 1235 lm_context->mode = *new_mode; 1236 } else { 1237 lm_context->mode = lm_context->default_mode; 1238 *new_mode = lm_context->mode; 1239 } 1240 1241 if (*old_mode != *new_mode) { 1242 al_info("%s: New SFP mode detected %s -> %s\n", 1243 __func__, al_eth_lm_mode_convert_to_str(*old_mode), 1244 al_eth_lm_mode_convert_to_str(*new_mode)); 1245 1246 lm_context->rx_param_dirty = 1; 1247 lm_context->tx_param_dirty = 1; 1248 1249 lm_context->new_port = TRUE; 1250 1251 if ((*new_mode != AL_ETH_LM_MODE_DISCONNECTED) && (lm_context->led_config)) { 1252 struct al_eth_lm_led_config_data data = {0}; 1253 1254 switch (*new_mode) { 1255 case AL_ETH_LM_MODE_10G_OPTIC: 1256 case AL_ETH_LM_MODE_10G_DA: 1257 data.speed = AL_ETH_LM_LED_CONFIG_10G; 1258 break; 1259 case AL_ETH_LM_MODE_1G: 1260 data.speed = AL_ETH_LM_LED_CONFIG_1G; 1261 break; 1262 case AL_ETH_LM_MODE_25G: 1263 data.speed = AL_ETH_LM_LED_CONFIG_25G; 1264 break; 1265 default: 1266 al_err("%s: unknown LM mode!\n", __func__); 1267 }; 1268 1269 lm_context->led_config(lm_context->i2c_context, &data); 1270 } 1271 } 1272 1273 return (0); 1274 } 1275 1276 int 1277 al_eth_lm_link_establish(struct al_eth_lm_context *lm_context, boolean_t *link_up) 1278 { 1279 boolean_t signal_detected; 1280 int ret = 0; 1281 1282 switch (lm_context->link_state) { 1283 case AL_ETH_LM_LINK_UP: 1284 *link_up = TRUE; 1285 lm_debug("%s: return link up\n", __func__); 1286 1287 return (0); 1288 case AL_ETH_LM_LINK_DOWN_RF: 1289 *link_up = FALSE; 1290 lm_debug("%s: return link down (DOWN_RF)\n", __func__); 1291 1292 return (0); 1293 case AL_ETH_LM_LINK_DOWN: 1294 break; 1295 }; 1296 1297 /** 1298 * At this point we will get LM disable only if changed to disable after link detection 1299 * finished. in this case link will not be established until LM will be enable again. 1300 */ 1301 if (lm_context->lm_pause) { 1302 boolean_t lm_pause = lm_context->lm_pause(lm_context->i2c_context); 1303 if (lm_pause == TRUE) { 1304 *link_up = FALSE; 1305 1306 return (0); 1307 } 1308 } 1309 1310 if ((lm_context->new_port) && (lm_context->retimer_exist)) { 1311 al_eth_serdes_static_rx_params_set(lm_context); 1312 al_eth_serdes_static_tx_params_set(lm_context); 1313 #if 0 1314 al_eth_lm_retimer_config(lm_context); 1315 DELAY(AL_ETH_LM_RETIMER_LINK_STATUS_DELAY); 1316 #endif 1317 1318 if (retimer[lm_context->retimer_type].config(lm_context)) { 1319 al_info("%s: failed to configure the retimer\n", __func__); 1320 1321 *link_up = FALSE; 1322 return (1); 1323 } 1324 1325 lm_context->new_port = FALSE; 1326 1327 DELAY(1000); 1328 } 1329 1330 if (lm_context->retimer_exist) { 1331 if (retimer[lm_context->retimer_type].rx_adaptation) { 1332 ret = retimer[lm_context->retimer_type].rx_adaptation(lm_context); 1333 1334 if (ret != 0) { 1335 lm_debug("retimer rx is not ready\n"); 1336 *link_up = FALSE; 1337 1338 return (0); 1339 } 1340 } 1341 } 1342 1343 signal_detected = lm_context->serdes_obj->signal_is_detected( 1344 lm_context->serdes_obj, 1345 lm_context->lane); 1346 1347 if (signal_detected == FALSE) { 1348 /* if no signal detected there is nothing to do */ 1349 lm_debug("serdes signal is down\n"); 1350 *link_up = AL_FALSE; 1351 return 0; 1352 } 1353 1354 if (lm_context->serdes_obj->type_get() == AL_SRDS_TYPE_25G) { 1355 lm_debug("%s: serdes 25G - perform rx gearbox reset\n", __func__); 1356 al_eth_gearbox_reset(lm_context->adapter, FALSE, TRUE); 1357 DELAY(AL_ETH_LM_GEARBOX_RESET_DELAY); 1358 } 1359 1360 1361 if (lm_context->retimer_exist) { 1362 DELAY(AL_ETH_LM_RETIMER_LINK_STATUS_DELAY); 1363 1364 ret = al_eth_lm_check_for_link(lm_context, link_up); 1365 1366 if (ret == 0) { 1367 lm_debug("%s: link is up with retimer\n", __func__); 1368 return 0; 1369 } 1370 1371 return ret; 1372 } 1373 1374 if ((lm_context->mode == AL_ETH_LM_MODE_10G_DA) && (lm_context->link_training)) { 1375 lm_context->local_adv.transmitted_nonce = lm_context->get_random_byte(); 1376 lm_context->local_adv.transmitted_nonce &= 0x1f; 1377 1378 ret = al_eth_an_lt_execute(lm_context->adapter, 1379 lm_context->serdes_obj, 1380 lm_context->lane, 1381 &lm_context->local_adv, 1382 &lm_context->partner_adv); 1383 1384 lm_context->rx_param_dirty = 1; 1385 lm_context->tx_param_dirty = 1; 1386 1387 if (ret == 0) { 1388 al_info("%s: link training finished successfully\n", __func__); 1389 lm_context->link_training_failures = 0; 1390 ret = al_eth_lm_check_for_link(lm_context, link_up); 1391 1392 if (ret == 0) { 1393 lm_debug("%s: link is up with LT\n", __func__); 1394 return (0); 1395 } 1396 1397 } 1398 1399 lm_context->link_training_failures++; 1400 if (lm_context->link_training_failures > AL_ETH_LT_FAILURES_TO_RESET) { 1401 lm_debug("%s: failed to establish LT %d times. reset serdes\n", 1402 __func__, AL_ETH_LT_FAILURES_TO_RESET); 1403 1404 lm_context->serdes_obj->pma_hard_reset_lane( 1405 lm_context->serdes_obj, 1406 lm_context->lane, 1407 TRUE); 1408 lm_context->serdes_obj->pma_hard_reset_lane( 1409 lm_context->serdes_obj, 1410 lm_context->lane, 1411 FALSE); 1412 lm_context->link_training_failures = 0; 1413 } 1414 } 1415 1416 al_eth_serdes_static_tx_params_set(lm_context); 1417 1418 if ((lm_context->mode == AL_ETH_LM_MODE_10G_DA) && 1419 (lm_context->rx_equal)) { 1420 ret = al_eth_rx_equal_run(lm_context); 1421 1422 if (ret == 0) { 1423 DELAY(AL_ETH_LM_LINK_STATUS_DELAY); 1424 ret = al_eth_lm_check_for_link(lm_context, link_up); 1425 1426 if (ret == 0) { 1427 lm_debug("%s: link is up with Rx Equalization\n", __func__); 1428 return (0); 1429 } 1430 } 1431 } 1432 1433 al_eth_serdes_static_rx_params_set(lm_context); 1434 1435 DELAY(AL_ETH_LM_LINK_STATUS_DELAY); 1436 1437 ret = al_eth_lm_check_for_link(lm_context, link_up); 1438 1439 if (ret == 0) { 1440 lm_debug("%s: link is up with static parameters\n", __func__); 1441 return (0); 1442 } 1443 1444 *link_up = FALSE; 1445 return (1); 1446 } 1447 1448 int 1449 al_eth_lm_static_parameters_override(struct al_eth_lm_context *lm_context, 1450 struct al_serdes_adv_tx_params *tx_params, 1451 struct al_serdes_adv_rx_params *rx_params) 1452 { 1453 1454 if (tx_params != NULL) { 1455 lm_context->tx_params_override = *tx_params; 1456 lm_context->tx_param_dirty = 1; 1457 lm_context->serdes_tx_params_valid = TRUE; 1458 } 1459 1460 if (rx_params != NULL) { 1461 lm_context->rx_params_override = *rx_params; 1462 lm_context->rx_param_dirty = 1; 1463 lm_context->serdes_rx_params_valid = TRUE; 1464 } 1465 1466 return (0); 1467 } 1468 1469 int 1470 al_eth_lm_static_parameters_override_disable(struct al_eth_lm_context *lm_context, 1471 boolean_t tx_params, boolean_t rx_params) 1472 { 1473 1474 if (tx_params != 0) 1475 lm_context->serdes_tx_params_valid = FALSE; 1476 if (rx_params != 0) 1477 lm_context->serdes_tx_params_valid = FALSE; 1478 1479 return (0); 1480 } 1481 1482 int 1483 al_eth_lm_static_parameters_get(struct al_eth_lm_context *lm_context, 1484 struct al_serdes_adv_tx_params *tx_params, 1485 struct al_serdes_adv_rx_params *rx_params) 1486 { 1487 1488 if (tx_params != NULL) { 1489 if (lm_context->serdes_tx_params_valid) 1490 *tx_params = lm_context->tx_params_override; 1491 else 1492 lm_context->serdes_obj->tx_advanced_params_get( 1493 lm_context->serdes_obj, 1494 lm_context->lane, 1495 tx_params); 1496 } 1497 1498 if (rx_params != NULL) { 1499 if (lm_context->serdes_rx_params_valid) 1500 *rx_params = lm_context->rx_params_override; 1501 else 1502 lm_context->serdes_obj->rx_advanced_params_get( 1503 lm_context->serdes_obj, 1504 lm_context->lane, 1505 rx_params); 1506 } 1507 1508 return (0); 1509 } 1510 1511 const char * 1512 al_eth_lm_mode_convert_to_str(enum al_eth_lm_link_mode val) 1513 { 1514 1515 switch (val) { 1516 case AL_ETH_LM_MODE_DISCONNECTED: 1517 return ("AL_ETH_LM_MODE_DISCONNECTED"); 1518 case AL_ETH_LM_MODE_10G_OPTIC: 1519 return ("AL_ETH_LM_MODE_10G_OPTIC"); 1520 case AL_ETH_LM_MODE_10G_DA: 1521 return ("AL_ETH_LM_MODE_10G_DA"); 1522 case AL_ETH_LM_MODE_1G: 1523 return ("AL_ETH_LM_MODE_1G"); 1524 case AL_ETH_LM_MODE_25G: 1525 return ("AL_ETH_LM_MODE_25G"); 1526 } 1527 1528 return ("N/A"); 1529 } 1530 1531 void 1532 al_eth_lm_debug_mode_set(struct al_eth_lm_context *lm_context, 1533 boolean_t enable) 1534 { 1535 1536 lm_context->debug = enable; 1537 } 1538