madura_diag_seq.c (26972B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 * 6 */ 7 8 /* 9 * 10 * 11 * This program is the proprietary software of Broadcom Corporation 12 * and/or its licensors, and may only be used, duplicated, modified 13 * or distributed pursuant to the terms and conditions of a separate, 14 * written license agreement executed between you and Broadcom 15 * (an "Authorized License"). Except as set forth in an Authorized 16 * License, Broadcom grants no license (express or implied), right 17 * to use, or waiver of any kind with respect to the Software, and 18 * Broadcom expressly reserves all rights in and to the Software 19 * and all intellectual property rights therein. IF YOU HAVE 20 * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE 21 * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE 22 * ALL USE OF THE SOFTWARE. 23 * 24 * Except as expressly set forth in the Authorized License, 25 * 26 * 1. This program, including its structure, sequence and organization, 27 * constitutes the valuable trade secrets of Broadcom, and you shall use 28 * all reasonable efforts to protect the confidentiality thereof, 29 * and to use this information only in connection with your use of 30 * Broadcom integrated circuit products. 31 * 32 * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS 33 * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, 34 * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, 35 * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY 36 * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, 37 * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, 38 * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 39 * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING 40 * OUT OF USE OR PERFORMANCE OF THE SOFTWARE. 41 * 42 * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL 43 * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, 44 * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER 45 * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY 46 * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE 47 * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF 48 * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00, 49 * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING 50 * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$ 51 */ 52 53 #define MADURA_EXCLUDE_STATIC_FUNCTION_DECLARATIONS 54 55 #include <phymod/phymod.h> 56 #include <phymod/phymod_system.h> 57 #include <phymod/phymod_diagnostics.h> 58 #include <phymod/phymod_reg.h> 59 #include "bcmi_madura_defs.h" 60 #include "madura_cfg_seq.h" 61 #include "madura_diag_seq.h" 62 #include "madura_serdes/falcon2_madura_src/falcon2_madura_functions.h" 63 #include "madura_serdes/falcon2_madura_src/falcon2_madura_internal.h" 64 #include "madura_serdes/common2/srds_api_enum.h" 65 66 /* #define DEB */ 67 68 int disable_hw_state_machine(const phymod_access_t *pa ) 69 { 70 /*Disable HW state machine when there is no line side traffic for SA */ 71 uint32_t data = 0, rv = 0; 72 rv = PHYMOD_BUS_WRITE(pa,0x18000,0x501); 73 rv = PHYMOD_BUS_READ(pa,0x1be00,&data); 74 data &= ~(0xc); 75 data |= 0x8; 76 rv = PHYMOD_BUS_WRITE(pa,0x18000,0x50f); 77 rv = PHYMOD_BUS_WRITE(pa,0x1be00,data); 78 return rv; 79 } 80 81 int _madura_phymod_prbs_poly_to_serdes_prbs_poly(uint16_t phymod_poly, uint16_t *serdes_poly) 82 { 83 switch (phymod_poly) { 84 case phymodPrbsPoly7: 85 *serdes_poly = PRBS_7; 86 break; 87 case phymodPrbsPoly9: 88 *serdes_poly = PRBS_9; 89 break; 90 case phymodPrbsPoly11: 91 *serdes_poly = PRBS_11; 92 break; 93 case phymodPrbsPoly15: 94 *serdes_poly = PRBS_15; 95 break; 96 case phymodPrbsPoly23: 97 *serdes_poly = PRBS_23; 98 break; 99 case phymodPrbsPoly31: 100 *serdes_poly = PRBS_31; 101 break; 102 case phymodPrbsPoly58: 103 *serdes_poly = PRBS_58; 104 break; 105 default: 106 return PHYMOD_E_PARAM; 107 } 108 return PHYMOD_E_NONE; 109 } 110 int _madura_serdes_prbs_poly_to_phymod_prbs_poly(uint16_t serdes_poly, phymod_prbs_poly_t *phymod_poly) 111 { 112 switch (serdes_poly) { 113 case PRBS_7: 114 *phymod_poly = phymodPrbsPoly7; 115 break; 116 case PRBS_9: 117 *phymod_poly = phymodPrbsPoly9; 118 break; 119 case PRBS_11: 120 *phymod_poly = phymodPrbsPoly11; 121 break; 122 case PRBS_15: 123 *phymod_poly = phymodPrbsPoly15; 124 break; 125 case PRBS_23: 126 *phymod_poly = phymodPrbsPoly23; 127 break; 128 case PRBS_31: 129 *phymod_poly = phymodPrbsPoly31; 130 break; 131 case PRBS_58: 132 *phymod_poly = phymodPrbsPoly58; 133 break; 134 default: 135 return PHYMOD_E_PARAM; 136 } 137 return PHYMOD_E_NONE; 138 } 139 140 141 int _madura_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 142 { 143 /*function to select prbs polynomial mode and inversion*/ 144 phymod_phy_inf_config_t config; 145 uint16_t ip = 0; 146 uint16_t lane = 0, max_lane = 0; 147 uint16_t lane_mask = 0 ; 148 uint16_t prbs_poly = 0; 149 const phymod_access_t *pa = &phy->access; 150 151 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 152 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 153 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 154 _madura_phy_interface_config_get(pa, 0, &config))); 155 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 156 MADURA_GET_IP(pa, config, ip); 157 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 158 _madura_phymod_prbs_poly_to_serdes_prbs_poly (prbs->poly, &prbs_poly))); 159 160 max_lane = (ip == MADURA_FALCON_CORE) ? 161 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 162 163 MADURA_GET_CORE_SLICE_INFO(pa, ip, config); 164 165 PHYMOD_DEBUG_VERBOSE(("IP:%s Max_lane:%d lanemask:0x%x flags=%x\n", 166 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", max_lane, lane_mask, flags)); 167 168 for (lane = 0; lane < max_lane; lane ++) { 169 if (lane_mask & (1 << lane)) { 170 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 171 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 172 173 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 174 /*enable inversion on config tx is causing problem for lanes not to lock because of inverted lanes. Also same invert variable is used to invert lanes in two different registers. what it idealy should be ?*/ 175 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 176 falcon2_madura_config_tx_prbs(pa, prbs_poly, (uint8_t)prbs->invert))); 177 } 178 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags) || flags == 0) { 179 /* Enabling PRBS CHECKER */ 180 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 181 falcon2_madura_config_rx_prbs( 182 pa, prbs_poly, 0, (uint8_t)prbs->invert))); 183 #ifdef DEB 184 uint32_t data1; 185 PHYMOD_BUS_READ(pa,0x1d161,&data1); 186 printf("[--d161-%x--]\n",data1); 187 #endif 188 } 189 } else { 190 PHYMOD_DEBUG_VERBOSE(("Lane mask not Fine \n")); 191 } 192 } 193 194 PHYMOD_FREE(config.device_aux_modes); 195 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 196 197 return PHYMOD_E_NONE; 198 } 199 200 int _madura_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags, uint32_t enable) 201 { 202 /*Function to enable prbs_tx && enable prbs_cfg_rx ralated fields*/ 203 phymod_phy_inf_config_t config; 204 uint16_t ip = 0,side=-1; 205 uint16_t lane = 0, max_lane = 0, dig_lpbk_en = 0; 206 uint16_t lane_mask = 0; 207 const phymod_access_t *pa = &phy->access; 208 #ifdef DEB 209 uint32_t data1; 210 #endif 211 212 /*Disable HW state machine when there is no line side traffic for SA */ 213 disable_hw_state_machine(pa); 214 215 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 216 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 217 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 218 _madura_phy_interface_config_get(pa, 0, &config))); 219 220 MADURA_GET_IP(pa, config, ip); 221 max_lane = (ip == MADURA_FALCON_CORE) ? 222 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 223 224 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 225 MADURA_GET_CORE_SLICE_INFO(pa, ip, config ); 226 MADURA_GET_INTF_SIDE(pa,side); 227 228 PHYMOD_DEBUG_VERBOSE(("\n IP:%s side=%d Max_lane:%d lanemask:0x%x enable=%x\n", 229 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", side,max_lane, lane_mask, enable)); 230 231 for (lane = 0; lane < max_lane; lane ++) { 232 if (lane_mask & (1 << lane)) {/*if starts*/ 233 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 234 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 235 236 /*Remove system side fix to enable generation without line side traffic. To be handled in application by generating traffic on line side*/ 237 /*wr_falcon2_madura_pmd_tx_disable_frc(1);*/ 238 239 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 240 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 241 falcon2_madura_tx_prbs_en(pa, enable))); 242 #ifdef DEB 243 PHYMOD_BUS_READ(pa,0x1d171,&data1); 244 printf("[--d171-%x--]\n",data1); 245 #endif 246 } 247 248 if (PHYMOD_PRBS_DIRECTION_RX_GET(flags) || flags == 0) { 249 /* Enabling PRBS CHECKER SELF SYNC HYS*/ 250 if (enable) { 251 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 252 wr_falcon2_madura_prbs_chk_clk_en_frc_on(1))); 253 /* Check for digital loopback enable or not */ 254 ESTM(dig_lpbk_en = rd_falcon2_madura_dig_lpbk_en()); 255 /* Do not enable prbs_chk_en_auto_mode when digital lpbk is set */ 256 if (!dig_lpbk_en) { 257 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 258 wr_falcon2_madura_prbs_chk_en_auto_mode(1))); 259 } 260 } else { 261 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 262 wr_falcon2_madura_prbs_chk_clk_en_frc_on(0))); 263 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 264 wr_falcon2_madura_prbs_chk_en_auto_mode(0))); 265 } 266 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 267 falcon2_madura_rx_prbs_en(pa, enable))); 268 #ifdef DEB 269 PHYMOD_BUS_READ(pa,0x1d161,&data1); 270 printf("[--d161-%x--]\n",data1); 271 #endif 272 } 273 } else { 274 PHYMOD_DEBUG_VERBOSE(("Lane mask not Fine: lane_mask=%x lane=%x \n",lane_mask,lane)); 275 } 276 /*for loop ends*/ 277 } 278 279 PHYMOD_FREE(config.device_aux_modes); 280 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 281 return PHYMOD_E_NONE; 282 } 283 284 int _madura_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags, uint32_t *enable) 285 { 286 phymod_phy_inf_config_t config; 287 uint16_t ip = 0; 288 uint16_t lane = 0, max_lane = 0, lane_mask = 0; 289 uint8_t gen_en = 0, ckr_en = 0; 290 const phymod_access_t *pa = &phy->access; 291 292 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 293 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 294 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 295 _madura_phy_interface_config_get(pa, 0, &config))); 296 297 MADURA_GET_IP(pa, config, ip); 298 max_lane = (ip == MADURA_FALCON_CORE) ? 299 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 300 301 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 302 PHYMOD_DEBUG_VERBOSE(("%s :: IP:%s Max_lane:%d lanemask:0x%x \n", __FUNCTION__ , 303 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", max_lane, lane_mask)); 304 305 for (lane = 0; lane < max_lane; lane ++) { 306 if ((lane_mask & (1 << lane))) { 307 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 308 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 309 310 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 311 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 312 falcon2_madura_get_tx_prbs_en(pa, &gen_en))); 313 *enable = gen_en; 314 } 315 if (flags == 0 || PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 316 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 317 falcon2_madura_get_rx_prbs_en(pa, &ckr_en))); 318 *enable = ckr_en; 319 } 320 break;/*one lane at a time*/ 321 } 322 } 323 if (flags == 0) { 324 *enable = ckr_en & gen_en; 325 } 326 PHYMOD_FREE(config.device_aux_modes); 327 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 328 return PHYMOD_E_NONE; 329 } 330 331 int _madura_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 332 { 333 phymod_phy_inf_config_t config; 334 uint16_t ip = 0; 335 uint16_t lane = 0, max_lane = 0, lane_mask; 336 uint8_t data = 0; 337 enum srds_prbs_checker_mode_enum temp = 0; 338 enum srds_prbs_polynomial_enum serdes_poly = 0; 339 const phymod_access_t *pa = &phy->access; 340 341 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 342 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 343 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 344 _madura_phy_interface_config_get(pa, 0, &config))); 345 346 MADURA_GET_IP(pa, config, ip); 347 max_lane = (ip == MADURA_FALCON_CORE) ? 348 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 349 350 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 351 PHYMOD_DEBUG_VERBOSE(("%s :: IP:%s Max_lane:%d lanemask:0x%x flags=%x\n", __FUNCTION__ , 352 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", max_lane, lane_mask,flags)); 353 354 for (lane = 0; lane < max_lane; lane ++) { 355 if ((lane_mask & (1 << lane))) { 356 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 357 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 358 359 if (flags == 0 || PHYMOD_PRBS_DIRECTION_TX_GET(flags)) { 360 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 361 falcon2_madura_get_tx_prbs_config(pa, &serdes_poly, &data))); 362 prbs->invert = data; 363 } 364 if (flags == 0 || PHYMOD_PRBS_DIRECTION_RX_GET(flags)) { 365 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 366 falcon2_madura_get_rx_prbs_config(pa, &serdes_poly, &temp, &data))); 367 prbs->invert = data; 368 } 369 break;/*one lane enough to get config values*/ 370 } 371 } 372 373 PHYMOD_DEBUG_VERBOSE(("Checker POLY:%d\n", serdes_poly)); 374 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 375 _madura_serdes_prbs_poly_to_phymod_prbs_poly(serdes_poly, &prbs->poly))); 376 377 PHYMOD_FREE(config.device_aux_modes); 378 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 379 380 return PHYMOD_E_NONE; 381 } 382 383 int _madura_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 384 { 385 /*Read prbs check register field*/ 386 phymod_phy_inf_config_t config; 387 uint16_t ip = 0; 388 uint16_t lane = 0, max_lane = 0, lane_mask = 0; 389 uint8_t data = 0; 390 uint32_t err_cnt = 0; 391 const phymod_access_t *pa = &phy->access; 392 393 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 394 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 395 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 396 _madura_phy_interface_config_get(pa, 0, &config))); 397 398 MADURA_GET_IP(pa, config, ip); 399 max_lane = (ip == MADURA_FALCON_CORE) ? 400 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 401 PHYMOD_USLEEP(100000); 402 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 403 PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 404 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", max_lane, lane_mask)); 405 prbs_status->prbs_lock = 1; 406 prbs_status->prbs_lock_loss = 1; 407 for (lane = 0; lane < max_lane; lane ++) { 408 if ((lane_mask & (1 << lane))) { 409 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 410 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 411 412 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 413 falcon2_madura_prbs_chk_lock_state(pa, &data))); 414 prbs_status->prbs_lock &= data; 415 #ifdef DEB 416 uint32_t data1 = 0; 417 PHYMOD_BUS_READ(pa,0x1d169,&data1); 418 printf("[--d169-%x--]\n",data1); 419 #endif 420 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 421 falcon2_madura_prbs_err_count_state(pa, &err_cnt, &data))); 422 423 prbs_status->prbs_lock_loss &= data; 424 prbs_status->error_count |= err_cnt; 425 } 426 } 427 428 PHYMOD_FREE(config.device_aux_modes); 429 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 430 return PHYMOD_E_NONE; 431 } 432 433 int _madura_phy_display_eyescan(const phymod_access_t *pa) 434 { 435 phymod_phy_inf_config_t config; 436 uint16_t ip=0; 437 uint16_t intf_side=0; 438 uint16_t lane = 0, max_lane = 0; 439 uint16_t lane_mask = 0; 440 BCMI_MADURA_SLICEr_t slice_reg; 441 442 PHYMOD_MEMSET(&slice_reg, 0 , sizeof(BCMI_MADURA_SLICEr_t)); 443 444 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 445 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 446 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 447 _madura_phy_interface_config_get(pa, 0, &config))); 448 449 MADURA_GET_IP(pa, config, ip); 450 MADURA_GET_INTF_SIDE(pa, intf_side); 451 max_lane = (intf_side == MADURA_IF_SYS) ? MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE ; 452 453 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 454 PHYMOD_DEBUG_VERBOSE(("%s::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 455 (intf_side == MADURA_IF_LINE)?"FALCON2X":"FALCON", max_lane, lane_mask)); 456 457 for (lane = 0; lane < max_lane; lane++) { 458 if ((lane_mask & (1 << lane))) { 459 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 460 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 461 462 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 463 falcon2_madura_display_lane_state_hdr(pa))); 464 465 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 466 falcon2_madura_display_lane_state(pa))); 467 468 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 469 falcon2_madura_display_eye_scan(pa))); 470 } 471 } 472 PHYMOD_FREE(config.device_aux_modes); 473 474 PHYMOD_IF_ERR_RETURN( 475 BCMI_MADURA_WRITE_SLICEr(pa, slice_reg)); 476 477 return PHYMOD_E_NONE; 478 } 479 480 481 int _madura_phy_diagnostics_get(const phymod_access_t *pa, phymod_phy_diagnostics_t* diag) 482 { 483 phymod_phy_inf_config_t config; 484 uint16_t ip = 0; 485 uint16_t lane = 0, max_lane = 0; 486 uint16_t lane_mask = 0; 487 falcon2_madura_lane_state_st state; 488 489 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 490 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 491 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 492 _madura_phy_interface_config_get(pa, 0, &config))); 493 494 MADURA_GET_IP(pa, config, ip); 495 max_lane = (ip == MADURA_FALCON_CORE) ? 496 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 497 498 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 499 PHYMOD_DEBUG_VERBOSE(("%s::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 500 (ip == MADURA_2X_FALCON_CORE)?"FALCON2X":"FALCON", max_lane, lane_mask)); 501 502 for (lane = 0; lane < max_lane; lane++) { 503 if ((lane_mask & (1 << lane))) { 504 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 505 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 506 507 PHYMOD_DEBUG_VERBOSE(("Phy Diagnostics for Lane:%d \n",lane)); 508 /* set the core to get the master /slave */ 509 /* system side always master line side considered as slave*/ 510 PHYMOD_MEMSET(&state, 0, sizeof(falcon2_madura_lane_state_st)); 511 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 512 _falcon2_madura_read_lane_state(pa, &state))); 513 514 diag->signal_detect = state.sig_det; 515 diag->osr_mode = state.osr_mode.tx; 516 diag->rx_lock = state.rx_lock; 517 diag->tx_ppm = state.tx_ppm; 518 diag->clk90_offset = state.clk90; 519 diag->clkp1_offset = state.clkp1; 520 diag->p1_lvl = state.p1_lvl; 521 diag->dfe1_dcd = state.dfe1_dcd; 522 diag->dfe2_dcd = state.dfe2_dcd; 523 diag->slicer_offset.offset_pe = state.pe; 524 diag->slicer_offset.offset_ze = state.ze; 525 diag->slicer_offset.offset_me = state.me; 526 diag->slicer_offset.offset_po = state.po; 527 diag->slicer_offset.offset_zo = state.zo; 528 diag->slicer_offset.offset_mo = state.mo; 529 diag->eyescan.heye_left = state.heye_left; 530 diag->eyescan.heye_right = state.heye_right; 531 diag->eyescan.veye_upper = state.veye_upper; 532 diag->eyescan.veye_lower = state.veye_lower; 533 diag->link_time = state.link_time; 534 diag->pf_main = state.pf_main; 535 diag->pf_hiz = state.pf_hiz; 536 diag->pf_bst = state.pf_bst; 537 diag->pf_low = 0; /* not availble in serdes api*/ 538 diag->pf2_ctrl = state.pf2_ctrl; 539 diag->vga = state.vga; 540 diag->dc_offset = state.dc_offset; 541 diag->p1_lvl_ctrl = state.p1_lvl_ctrl; 542 diag->dfe1 = state.dfe1; 543 diag->dfe2 = state.dfe2; 544 diag->dfe3 = state.dfe3; 545 diag->dfe4 = state.dfe4; 546 diag->dfe5 = state.dfe5; 547 diag->dfe6 = state.dfe6; 548 diag->txfir_pre = state.txfir_pre; 549 diag->txfir_main = state.txfir_main; 550 diag->txfir_post1 = state.txfir_post1; 551 diag->txfir_post2 = state.txfir_post2; 552 diag->txfir_post3 = state.txfir_post3; 553 diag->tx_amp_ctrl = 0; /* not availble in serdes api*/ 554 diag->br_pd_en = state.br_pd_en; 555 break; 556 } 557 } 558 PHYMOD_FREE(config.device_aux_modes); 559 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 560 561 return PHYMOD_E_NONE; 562 } 563 564 565 int _madura_ber_proj_lane_speed_get(phymod_phy_inf_config_t *config, uint16_t ip, uint32_t *speed) 566 { 567 568 MADURA_DEVICE_AUX_MODE_T *aux; 569 aux = (MADURA_DEVICE_AUX_MODE_T*) config->device_aux_modes; 570 571 if (config->data_rate == MADURA_SPD_100G || config->data_rate == MADURA_SPD_106G) { 572 *speed = 25781250; 573 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 574 *speed = 27952500; 575 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 576 *speed = 27343750; 577 } 578 } else if ((config->data_rate == MADURA_SPD_40G ) && (!aux->pass_thru)) { 579 *speed = 20625000; 580 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 581 *speed = 21875000; 582 } 583 } else if ((config->data_rate == MADURA_SPD_20G ) && (!aux->pass_thru)) { 584 *speed = 20625000; 585 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 586 *speed = 21875000; 587 } 588 } else { 589 *speed = 10312500; 590 if (PHYMOD_INTF_MODES_OTN_GET(config)) { 591 *speed = 10937500; 592 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 593 *speed = 11180000; 594 } 595 } 596 597 return PHYMOD_E_NONE; 598 } 599 600 601 int _madura_ber_proj(const phymod_phy_access_t *phy, const phymod_phy_eyescan_options_t* eyescan_options) 602 { 603 phymod_phy_inf_config_t config; 604 uint16_t ip = 0; 605 uint16_t lane = 0, max_lane = 0; 606 uint16_t lane_mask = 0; 607 const phymod_access_t *pa = &phy->access; 608 #ifdef SERDES_API_FLOATING_POINT 609 uint32_t speed; 610 USR_DOUBLE speedD; 611 #endif 612 613 PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t)); 614 config.device_aux_modes = PHYMOD_MALLOC(sizeof(MADURA_DEVICE_AUX_MODE_T), "madura_device_aux_mode"); 615 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 616 _madura_phy_interface_config_get(pa, 0, &config))); 617 618 MADURA_GET_IP(pa, config, ip); 619 max_lane = (ip == MADURA_FALCON_CORE) ? 620 MADURA_MAX_FALCON_LANE : MADURA_MAX_2X_FALCON_LANE; 621 622 lane_mask = PHYMOD_ACC_LANE_MASK(pa); 623 PHYMOD_DEBUG_VERBOSE(("%s::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 624 (ip == MADURA_FALCON_CORE)?"FALCON":"FALCON_2X", max_lane, lane_mask)); 625 626 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 627 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 628 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 629 (falcon2_madura_display_core_state_hdr()))); 630 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 631 (falcon2_madura_display_core_state_line(pa)))); 632 633 for (lane = 0; lane < max_lane; lane++) { 634 if ((lane_mask & (1 << lane))) { 635 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 636 _madura_set_slice_reg (pa, ip, MADURA_DEV_PMA_PMD, lane, 0))); 637 638 PHYMOD_DEBUG_VERBOSE(("eye_margin_proj for Lane:%d \n",lane)); 639 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 640 (falcon2_madura_display_lane_state_hdr(pa)))); 641 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 642 (falcon2_madura_display_lane_state(pa)))); 643 #ifdef SERDES_API_FLOATING_POINT 644 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 645 (_madura_ber_proj_lane_speed_get(&config, ip, &speed)))); 646 speedD = speed * 1000.0; 647 MADURA_IF_ERR_RETURN_FREE(config.device_aux_modes, ( 648 (falcon2_madura_eye_margin_proj(pa, speedD, eyescan_options->ber_proj_scan_mode, 649 eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt)))); 650 #else 651 PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n")); 652 PHYMOD_FREE(config.device_aux_modes); 653 return PHYMOD_E_RESOURCE; 654 #endif 655 656 } 657 } 658 659 PHYMOD_FREE(config.device_aux_modes); 660 MADURA_RESET_SLICE(pa, MADURA_DEV_PMA_PMD); 661 662 return PHYMOD_E_NONE; 663 } 664